ART: Introduce individual HInstruction cloning.
Introduce API for HInstruction cloning, support it for a few
instructions. add a gtest.
Test: cloner_test.cc, test-art-target, test-art-host.
Change-Id: I8b6299be5d04a26390d9ef13a20ce82ee5ae4afe
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index f4f6434..b90ff59 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -845,6 +845,13 @@
DCHECK(!instruction->HasEnvironment());
}
+void HBasicBlock::ReplaceAndRemovePhiWith(HPhi* initial, HPhi* replacement) {
+ DCHECK(initial->GetBlock() == this);
+ InsertPhiAfter(replacement, initial);
+ initial->ReplaceWith(replacement);
+ RemovePhi(initial);
+}
+
void HBasicBlock::ReplaceAndRemoveInstructionWith(HInstruction* initial,
HInstruction* replacement) {
DCHECK(initial->GetBlock() == this);
@@ -2902,6 +2909,28 @@
env_uses_.clear();
}
+HInstruction* ReplaceInstrOrPhiByClone(HInstruction* instr) {
+ HInstruction* clone = instr->Clone(instr->GetBlock()->GetGraph()->GetAllocator());
+ HBasicBlock* block = instr->GetBlock();
+
+ if (instr->IsPhi()) {
+ HPhi* phi = instr->AsPhi();
+ DCHECK(!phi->HasEnvironment());
+ HPhi* phi_clone = clone->AsPhi();
+ block->ReplaceAndRemovePhiWith(phi, phi_clone);
+ } else {
+ block->ReplaceAndRemoveInstructionWith(instr, clone);
+ if (instr->HasEnvironment()) {
+ clone->CopyEnvironmentFrom(instr->GetEnvironment());
+ HLoopInformation* loop_info = block->GetLoopInformation();
+ if (instr->IsSuspendCheck() && loop_info != nullptr) {
+ loop_info->SetSuspendCheck(clone->AsSuspendCheck());
+ }
+ }
+ }
+ return clone;
+}
+
// Returns an instruction with the opposite Boolean value from 'cond'.
HInstruction* HGraph::InsertOppositeCondition(HInstruction* cond, HInstruction* cursor) {
ArenaAllocator* allocator = GetAllocator();