ART: Force constants into the entry block
Optimizations such as GVN and BCE make the assumption that all
constants are located in the entry block of the CFG, but not all
passes adhere to this rule.
This patch makes constructors of constants private and only accessible
to friend classes - HGraph for int/long constants and SsaBuilder for
float/double - which ensure that they are placed correctly and not
duplicated.
Note that the ArenaAllocatorAdapter was modified to not increment
the ArenaAllocator's internal reference counter in order to allow
for use of ArenaSafeMap inside an arena-allocated objects. Because
their destructor is not called, the counter does not get decremented.
Change-Id: I36a4fa29ae34fb905cdefd482ccbf386cff14166
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index ec0cc3e..b7a92b5 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -55,20 +55,20 @@
if (inst->IsBinaryOperation()) {
// Constant folding: replace `op(a, b)' with a constant at
// compile time if `a' and `b' are both constants.
- HConstant* constant =
- inst->AsBinaryOperation()->TryStaticEvaluation();
+ HConstant* constant = inst->AsBinaryOperation()->TryStaticEvaluation();
if (constant != nullptr) {
- inst->GetBlock()->ReplaceAndRemoveInstructionWith(inst, constant);
+ inst->ReplaceWith(constant);
+ inst->GetBlock()->RemoveInstruction(inst);
} else {
inst->Accept(&simplifier);
}
} else if (inst->IsUnaryOperation()) {
// Constant folding: replace `op(a)' with a constant at compile
// time if `a' is a constant.
- HConstant* constant =
- inst->AsUnaryOperation()->TryStaticEvaluation();
+ HConstant* constant = inst->AsUnaryOperation()->TryStaticEvaluation();
if (constant != nullptr) {
- inst->GetBlock()->ReplaceAndRemoveInstructionWith(inst, constant);
+ inst->ReplaceWith(constant);
+ inst->GetBlock()->RemoveInstruction(inst);
}
} else if (inst->IsDivZeroCheck()) {
// We can safely remove the check if the input is a non-null constant.
@@ -173,9 +173,8 @@
// REM dst, src, src
// with
// CONSTANT 0
- ArenaAllocator* allocator = GetGraph()->GetArena();
- block->ReplaceAndRemoveInstructionWith(instruction,
- HConstant::NewConstant(allocator, type, 0));
+ instruction->ReplaceWith(GetGraph()->GetConstant(type, 0));
+ block->RemoveInstruction(instruction);
}
}
@@ -195,7 +194,6 @@
}
HBasicBlock* block = instruction->GetBlock();
- ArenaAllocator* allocator = GetGraph()->GetArena();
// We assume that GVN has run before, so we only perform a pointer
// comparison. If for some reason the values are equal but the pointers are
@@ -208,8 +206,8 @@
// CONSTANT 0
// Note that we cannot optimise `x - x` to `0` for floating-point. It does
// not work when `x` is an infinity.
- block->ReplaceAndRemoveInstructionWith(instruction,
- HConstant::NewConstant(allocator, type, 0));
+ instruction->ReplaceWith(GetGraph()->GetConstant(type, 0));
+ block->RemoveInstruction(instruction);
}
}
@@ -225,10 +223,8 @@
// CONSTANT 0
Primitive::Type type = instruction->GetType();
HBasicBlock* block = instruction->GetBlock();
- ArenaAllocator* allocator = GetGraph()->GetArena();
-
- block->ReplaceAndRemoveInstructionWith(instruction,
- HConstant::NewConstant(allocator, type, 0));
+ instruction->ReplaceWith(GetGraph()->GetConstant(type, 0));
+ block->RemoveInstruction(instruction);
}
}