Example #1
0
//------------------------------------------------------------------------
// DecomposeCall: Decompose GT_CALL.
//
// Arguments:
//    ppTree - the tree to decompose
//    data - tree walk context
//
// Return Value:
//    None.
//
void DecomposeLongs::DecomposeCall(GenTree** ppTree, Compiler::fgWalkData* data)
{
    assert(ppTree != nullptr);
    assert(*ppTree != nullptr);
    assert(data != nullptr);
    assert((*ppTree)->OperGet() == GT_CALL);

    GenTree* parent = data->parent;

    // We only need to force var = call() if the call is not a top-level node.
    if (parent == nullptr)
        return;

    if (parent->gtOper == GT_STORE_LCL_VAR)
    {
        // If parent is already a STORE_LCL_VAR, we can skip it if
        // it is already marked as lvIsMultiRegRet.
        unsigned varNum = parent->AsLclVarCommon()->gtLclNum;
        if (m_compiler->lvaTable[varNum].lvIsMultiRegRet)
        {
            return;
        }
        else if (!m_compiler->lvaTable[varNum].lvPromoted)
        {
            // If var wasn't promoted, we can just set lvIsMultiRegRet.
            m_compiler->lvaTable[varNum].lvIsMultiRegRet = true;
            return;
        }
    }

    // Otherwise, we need to force var = call()
    GenTree* tree = *ppTree;
    GenTree** treePtr = nullptr;
    parent = tree->gtGetParent(&treePtr);

    assert(treePtr != nullptr);

    GenTreeStmt* asgStmt = m_compiler->fgInsertEmbeddedFormTemp(treePtr);
    GenTree* stLclVar = asgStmt->gtStmtExpr;
    assert(stLclVar->OperIsLocalStore());

    unsigned varNum = stLclVar->AsLclVarCommon()->gtLclNum;
    m_compiler->lvaTable[varNum].lvIsMultiRegRet = true;
    m_compiler->fgFixupIfCallArg(data->parentStack, tree, *treePtr);

    // Decompose new node
    DecomposeNode(treePtr, data);
}