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; }
GenTreeStmt* BasicBlock::lastStmt() { if (bbTreeList == nullptr) return nullptr; GenTree* result = bbTreeList->gtPrev; assert(result && result->gtNext == nullptr); return result->AsStmt(); }
//------------------------------------------------------------------------ // 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()); } }
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; }
//------------------------------------------------------------------------ // 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 }