summaryrefslogtreecommitdiff
path: root/src/jit/block.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/block.cpp')
-rw-r--r--src/jit/block.cpp37
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.
//