def METHOD_NAME(circuit: QuantumCircuit) -> QuantumCircuit:
    """Canonicalize all control-flow operations in a circuit.
    This is not an efficient operation, and does not affect any properties of the circuit.  Its
    intent is to normalise parts of circuits that have a non-deterministic construction.  These are
    the ordering of bit arguments in control-flow blocks output by the builder interface, and
    automatically generated ``for``-loop variables.
    The canonical form sorts the bits in the arguments of these operations so that they always
    appear in the order they were originally added to the outer-most circuit.  For-loop variables
    are re-bound into new, cached auto-generated ones."""
    params = iter(_CanonicalParametersIterator())
    base_bit_order = {bit: i for i, bit in enumerate(circuit.qubits)}
    base_bit_order.update((bit, i) for i, bit in enumerate(circuit.clbits))
    def worker(circuit, bit_map=None):
        if bit_map is None:
            bit_map = {bit: bit for bits in (circuit.qubits, circuit.clbits) for bit in bits}
        def bit_key(bit):
            return base_bit_order[bit_map[bit]]
        # This isn't quite QuantumCircuit.copy_empty_like because of the bit reordering.
        out = QuantumCircuit(
            sorted(circuit.qubits, key=bit_key),
            sorted(circuit.clbits, key=bit_key),
            *circuit.qregs,
            *circuit.cregs,
            name=circuit.name,
            global_phase=circuit.global_phase,
            metadata=circuit.metadata,
        )
        for instruction in circuit.data:
            new_instruction = instruction
            # Control-flow operations associated bits in the instruction arguments with bits in the
            # circuit blocks just by sequencing.  All blocks must have the same width.
            if isinstance(new_instruction.operation, ControlFlowOp):
                op = new_instruction.operation
                first_block = op.blocks[0]
                inner_bit_map = dict(
                    zip(first_block.qubits, (bit_map[bit] for bit in new_instruction.qubits))
                )
                inner_bit_map.update(
                    zip(first_block.clbits, (bit_map[bit] for bit in new_instruction.clbits))
                )
                new_instruction = CircuitInstruction(
                    operation=op.replace_blocks(
                        [worker(block, inner_bit_map) for block in op.blocks]
                    ),
                    qubits=sorted(new_instruction.qubits, key=bit_key),
                    clbits=sorted(new_instruction.clbits, key=bit_key),
                )
            elif isinstance(new_instruction.operation, (BreakLoopOp, ContinueLoopOp)):
                new_instruction = new_instruction.replace(
                    qubits=sorted(new_instruction.qubits, key=bit_key),
                    clbits=sorted(new_instruction.clbits, key=bit_key),
                )
            # For for loops specifically, the control-flow builders generate a loop parameter if one
            # is needed but not explicitly supplied.  We want the parameters to compare equal, so we
            # replace them with those from a shared list.
            if isinstance(new_instruction.operation, ForLoopOp):
                old_op = new_instruction.operation
                indexset, loop_param, body = old_op.params
                if loop_param is not None:
                    new_loop_param = next(params)
                    new_op = ForLoopOp(
                        indexset,
                        new_loop_param,
                        body.assign_parameters({loop_param: new_loop_param}),
                    )
                    new_instruction = new_instruction.replace(operation=new_op)
            out._append(new_instruction)
        return out
    return worker(circuit)