Esempio n. 1
0
InlineContext* InlineContext::NewSuccess(Compiler*   compiler,
                                         InlineInfo* inlineInfo)
{
    InlineContext* calleeContext = new (compiler, CMK_Inlining) InlineContext;

    GenTree*       stmt          = inlineInfo->iciStmt;
    BYTE*          calleeIL      = inlineInfo->inlineCandidateInfo->methInfo.ILCode;
    InlineContext* parentContext = stmt->gtStmt.gtInlineContext;

    noway_assert(parentContext != nullptr);

    calleeContext->m_Code = calleeIL;
    calleeContext->m_Parent = parentContext;
    // Push on front here will put siblings in reverse lexical
    // order which we undo in the dumper
    calleeContext->m_Sibling = parentContext->m_Child;
    parentContext->m_Child = calleeContext;
    calleeContext->m_Child = nullptr;
    calleeContext->m_Offset = stmt->AsStmt()->gtStmtILoffsx;
    calleeContext->m_Observation = inlineInfo->inlineResult->GetObservation();
#ifdef DEBUG
    calleeContext->m_Callee = inlineInfo->fncHandle;
    calleeContext->m_TreeID = inlineInfo->inlineResult->GetCall()->gtTreeID;
#endif

    return calleeContext;
}
Esempio n. 2
0
GenTreeStmt* BasicBlock::lastStmt()
{
    if (bbTreeList == nullptr)
        return nullptr;

    GenTree* result = bbTreeList->gtPrev;
    assert(result && result->gtNext == nullptr);
    return result->AsStmt();
}
Esempio n. 3
0
//------------------------------------------------------------------------
// DecomposeBlock: Do LONG decomposition to all the statements in the given block.
// This must be done before lowering the block, as decomposition can insert
// additional statements.
//
// Decomposition is done as a post-order tree walk. Lower levels of the tree can
// create new nodes that need to be further decomposed at higher levels. That is,
// the decomposition "bubbles up" the tree.
//
// Arguments:
//    block - the block to process
//
// Return Value:
//    None.
//
void DecomposeLongs::DecomposeBlock(BasicBlock* block)
{
    assert(block == m_compiler->compCurBB); // compCurBB must already be set.

    for (GenTree* stmt = block->bbTreeList; stmt != nullptr; stmt = stmt->gtNext)
    {
#ifdef DEBUG
        if (m_compiler->verbose)
        {
            printf("Decomposing BB%02u, stmt id %u\n", block->bbNum, stmt->gtTreeID);
        }
#endif // DEBUG

        DecomposeStmt(stmt->AsStmt());
    }
}
Esempio n. 4
0
InlineContext* InlineStrategy::NewSuccess(InlineInfo* inlineInfo)
{
    InlineContext* calleeContext = new (m_Compiler, CMK_Inlining) InlineContext(this);
    GenTree*       stmt          = inlineInfo->iciStmt;
    BYTE*          calleeIL      = inlineInfo->inlineCandidateInfo->methInfo.ILCode;
    unsigned       calleeILSize  = inlineInfo->inlineCandidateInfo->methInfo.ILCodeSize;
    InlineContext* parentContext = stmt->gtStmt.gtInlineContext;

    noway_assert(parentContext != nullptr);

    calleeContext->m_Code   = calleeIL;
    calleeContext->m_ILSize = calleeILSize;
    calleeContext->m_Parent = parentContext;
    // Push on front here will put siblings in reverse lexical
    // order which we undo in the dumper
    calleeContext->m_Sibling     = parentContext->m_Child;
    parentContext->m_Child       = calleeContext;
    calleeContext->m_Child       = nullptr;
    calleeContext->m_Offset      = stmt->AsStmt()->gtStmtILoffsx;
    calleeContext->m_Observation = inlineInfo->inlineResult->GetObservation();
    calleeContext->m_Success     = true;

#if defined(DEBUG) || defined(INLINE_DATA)

    InlinePolicy* policy = inlineInfo->inlineResult->GetPolicy();

    calleeContext->m_Policy           = policy;
    calleeContext->m_CodeSizeEstimate = policy->CodeSizeEstimate();
    calleeContext->m_Callee           = inlineInfo->fncHandle;
    // +1 here since we set this before calling NoteOutcome.
    calleeContext->m_Ordinal = m_InlineCount + 1;
    // Update offset with more accurate info
    calleeContext->m_Offset = inlineInfo->inlineResult->GetCall()->gtRawILOffset;

#endif // defined(DEBUG) || defined(INLINE_DATA)

#if defined(DEBUG)

    calleeContext->m_TreeID = inlineInfo->inlineResult->GetCall()->gtTreeID;

#endif // defined(DEBUG)

    NoteOutcome(calleeContext);

    return calleeContext;
}
Esempio n. 5
0
//------------------------------------------------------------------------
// InsertNodeAsStmt: Insert a node as the root node of a new statement.
// If the current statement is embedded, the new statement will also be
// embedded. Otherwise, the new statement will be top level.
//
// Arguments:
//    node - node to insert
//
// Return Value:
//    None
//
// Notes:
// compCurStmt and compCurBB must be correctly set.
//
void DecomposeLongs::InsertNodeAsStmt(GenTree* node)
{
    assert(node != nullptr);
    assert(m_compiler->compCurBB != nullptr);
    assert(m_compiler->compCurStmt != nullptr);

    GenTreeStmt* curStmt = m_compiler->compCurStmt->AsStmt();
    GenTreeStmt* newStmt;

    if (curStmt->gtStmtIsTopLevel())
    {
        newStmt = m_compiler->fgNewStmtFromTree(node);

        // Find an insert point. Skip all embedded statements.
        GenTree* insertPt = curStmt;
        while ((insertPt->gtNext != nullptr) && (!insertPt->gtNext->AsStmt()->gtStmtIsTopLevel()))
        {
            insertPt = insertPt->gtNext;
        }

        m_compiler->fgInsertStmtAfter(m_compiler->compCurBB, insertPt, newStmt);
    }
    else
    {
        // The current statement is an embedded statement. Create a new embedded statement to
        // contain the node. First, find the parent non-embedded statement containing the
        // current statement.
        GenTree* parentStmt = curStmt;
        while ((parentStmt != nullptr) && (!parentStmt->AsStmt()->gtStmtIsTopLevel()))
        {
            parentStmt = parentStmt->gtPrev;
        }
        assert(parentStmt != nullptr);

        newStmt = m_compiler->fgMakeEmbeddedStmt(m_compiler->compCurBB, node, parentStmt);
    }

    newStmt->gtStmtILoffsx = curStmt->gtStmtILoffsx;
#ifdef DEBUG
    newStmt->gtStmtLastILoffs = curStmt->gtStmtLastILoffs;
#endif // DEBUG
}