diff options
Diffstat (limited to 'src/jit/block.cpp')
-rw-r--r-- | src/jit/block.cpp | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/jit/block.cpp b/src/jit/block.cpp index 2d37754ec5..47f1052cc8 100644 --- a/src/jit/block.cpp +++ b/src/jit/block.cpp @@ -554,7 +554,9 @@ void BasicBlock::dspBlockHeader(Compiler* compiler, } if (showFlags) { - printf(" flags=0x%08x: ", bbFlags); + const unsigned lowFlags = (unsigned)bbFlags; + const unsigned highFlags = (unsigned)(bbFlags >> 32); + printf(" flags=0x%08x.%08x: ", highFlags, lowFlags); dspFlags(); } printf("\n"); @@ -568,7 +570,25 @@ void* BasicBlock::HeapPhiArg::operator new(size_t sz, Compiler* comp) return comp->compGetMem(sz, CMK_HeapPhiArg); } -void BasicBlock::CloneBlockState(Compiler* compiler, BasicBlock* to, const BasicBlock* from) +//------------------------------------------------------------------------ +// CloneBlockState: Try to populate `to` block with a copy of `from` block's statements, replacing +// uses of local `varNum` with IntCns `varVal`. +// +// Arguments: +// compiler - Jit compiler instance +// to - New/empty block to copy statements into +// from - Block to copy statements from +// varNum - lclVar uses with lclNum `varNum` will be replaced; can be ~0 to indicate no replacement. +// varVal - If replacing uses of `varNum`, replace them with int constants with value `varVal`. +// +// Return Value: +// Cloning may fail because this routine uses `gtCloneExpr` for cloning and it can't handle all +// IR nodes. If cloning of any statement fails, `false` will be returned and block `to` may be +// partially populated. If cloning of all statements succeeds, `true` will be returned and +// block `to` will be fully populated. + +bool BasicBlock::CloneBlockState( + Compiler* compiler, BasicBlock* to, const BasicBlock* from, unsigned varNum, int varVal) { assert(to->bbTreeList == nullptr); @@ -595,9 +615,17 @@ void BasicBlock::CloneBlockState(Compiler* compiler, BasicBlock* to, const Basic for (GenTreePtr fromStmt = from->bbTreeList; fromStmt != nullptr; fromStmt = fromStmt->gtNext) { - compiler->fgInsertStmtAtEnd(to, - compiler->fgNewStmtFromTree(compiler->gtCloneExpr(fromStmt->gtStmt.gtStmtExpr))); + auto newExpr = compiler->gtCloneExpr(fromStmt->gtStmt.gtStmtExpr, 0, varNum, varVal); + if (!newExpr) + { + // gtCloneExpr doesn't handle all opcodes, so may fail to clone a statement. + // When that happens, it returns nullptr; abandon the rest of this block and + // return `false` to the caller to indicate that cloning was unsuccessful. + return false; + } + compiler->fgInsertStmtAtEnd(to, compiler->fgNewStmtFromTree(newExpr)); } + return true; } // LIR helpers @@ -667,7 +695,6 @@ GenTreeStmt* BasicBlock::lastStmt() return result->AsStmt(); } - //------------------------------------------------------------------------ // BasicBlock::firstNode: Returns the first node in the block. // |