Repository: dotnet/runtime
File: src/coreclr/jit/regallocwasm.cpp (C++)

Code before:
    // If the node already has a regnum, trying to assign it a second one is no good.
    assert(node->GetRegNum() == REG_NA);
    node->SetRegNum(reg);
}

//------------------------------------------------------------------------
// ConsumeTemporaryRegForOperand: Consume the temporary register for a multiply-used operand.
//
// The contract with codegen is that such operands will have their register
// number set to a valid WASM local, to be "local.tee"d after the node is
// generated.
//
// Arguments:
//    operand - The node to consume the register for
//    reason  - What was the register allocated for
//
void WasmRegAlloc::ConsumeTemporaryRegForOperand(GenTree* operand DEBUGARG(const char* reason))
{
    if ((operand->gtLIRFlags & LIR::Flags::MultiplyUsed) == LIR::Flags::None)
    {
        return;
    }

    regNumber reg = ReleaseTemporaryRegister(genActualType(operand));
    // If this assert fails you likely called ConsumeTemporaryRegForOperand on your operands in the wrong order.
    assert(reg == operand->GetRegNum());
    CollectReference(operand);

    operand->gtLIRFlags &= ~LIR::Flags::MultiplyUsed;
    JITDUMP("Consumed a temporary reg for [%06u]: %s\n", Compiler::dspTreeID(operand), reason);
}

//------------------------------------------------------------------------
// RequestInternalRegister: request an internal register for a node with specific type.
//
// To be later assigned a physical register.
//
// Arguments:
//    node - node whose codegen will need an internal register
//    type - type of the internal register
//
// Returns:
//    reg number of internal register.
//
regNumber WasmRegAlloc::RequestInternalRegister(GenTree* node, var_types type)
{
    regNumber reg = AllocateTemporaryRegister(genActualType(type));
    m_codeGen->internalRegisters.Add(node, reg);
    return reg;
}


Review comment (suggestion):
```suggestion
assert((reg == operand->GetRegNum()) && "Temporary reg being consumed out of order");
```

Code after:
    assert((node->GetRegNum() == REG_NA) && "Trying to double-assign a temporary register");
    node->SetRegNum(reg);
}

//------------------------------------------------------------------------
// ConsumeTemporaryRegForOperand: Consume the temporary register for a multiply-used operand.
//
// The contract with codegen is that such operands will have their register
// number set to a valid WASM local, to be "local.tee"d after the node is
// generated.
//
// Arguments:
//    operand - The node to consume the register for
//    reason  - What was the register allocated for
//
void WasmRegAlloc::ConsumeTemporaryRegForOperand(GenTree* operand DEBUGARG(const char* reason))
{
    if ((operand->gtLIRFlags & LIR::Flags::MultiplyUsed) == LIR::Flags::None)
    {
        return;
    }

    regNumber reg = ReleaseTemporaryRegister(genActualType(operand));
    assert((reg == operand->GetRegNum()) && "Temporary reg being consumed out of order");
    CollectReference(operand);

    operand->gtLIRFlags &= ~LIR::Flags::MultiplyUsed;
    JITDUMP("Consumed a temporary reg for [%06u]: %s\n", Compiler::dspTreeID(operand), reason);
}

//------------------------------------------------------------------------
// RequestInternalRegister: request an internal register for a node with specific type.
//
// To be later assigned a physical register.
//
// Arguments:
//    node - node whose codegen will need an internal register
//    type - type of the internal register
//
// Returns:
//    reg number of internal register.
//
regNumber WasmRegAlloc::RequestInternalRegister(GenTree* node, var_types type)
{
    regNumber reg = AllocateTemporaryRegister(genActualType(type));
    m_codeGen->internalRegisters.Add(node, reg);
    return reg;
}

//------------------------------------------------------------------------
// ResolveReferences: Translate virtual registers to physical ones (WASM locals).