Move PC-relative addressing bases to a better position.
Move the platform-specific HX86ComputeBaseMethodAddress and
HArmDexCacheArraysBase to the latest dominator of their uses
outside any loop. This brings the base closer to the first
use (previously, it was in the entry block) and relieves
some pressure on the register allocator while avoiding
recalculation of the base in a loop.
Change-Id: I231aa81eb5b4de9af2d0167054d06b65eb18a636
diff --git a/compiler/optimizing/pc_relative_fixups_x86.cc b/compiler/optimizing/pc_relative_fixups_x86.cc
index 808a1dc..b383f1e 100644
--- a/compiler/optimizing/pc_relative_fixups_x86.cc
+++ b/compiler/optimizing/pc_relative_fixups_x86.cc
@@ -26,6 +26,15 @@
public:
explicit PCRelativeHandlerVisitor(HGraph* graph) : HGraphVisitor(graph), base_(nullptr) {}
+ void MoveBaseIfNeeded() {
+ if (base_ != nullptr) {
+ // Bring the base closer to the first use (previously, it was in the
+ // entry block) and relieve some pressure on the register allocator
+ // while avoiding recalculation of the base in a loop.
+ base_->MoveBeforeFirstUserAndOutOfLoops();
+ }
+ }
+
private:
void VisitAdd(HAdd* add) OVERRIDE {
BinaryFP(add);
@@ -72,7 +81,7 @@
void VisitPackedSwitch(HPackedSwitch* switch_insn) OVERRIDE {
// We need to replace the HPackedSwitch with a HX86PackedSwitch in order to
// address the constant area.
- InitializePCRelativeBasePointer(switch_insn);
+ InitializePCRelativeBasePointer();
HGraph* graph = GetGraph();
HBasicBlock* block = switch_insn->GetBlock();
HX86PackedSwitch* x86_switch = new (graph->GetArena()) HX86PackedSwitch(
@@ -84,22 +93,22 @@
block->ReplaceAndRemoveInstructionWith(switch_insn, x86_switch);
}
- void InitializePCRelativeBasePointer(HInstruction* user) {
+ void InitializePCRelativeBasePointer() {
// Ensure we only initialize the pointer once.
if (base_ != nullptr) {
return;
}
- HGraph* graph = GetGraph();
- HBasicBlock* entry = graph->GetEntryBlock();
- base_ = new (graph->GetArena()) HX86ComputeBaseMethodAddress();
- HInstruction* insert_pos = (user->GetBlock() == entry) ? user : entry->GetLastInstruction();
- entry->InsertInstructionBefore(base_, insert_pos);
+ // Insert the base at the start of the entry block, move it to a better
+ // position later in MoveBaseIfNeeded().
+ base_ = new (GetGraph()->GetArena()) HX86ComputeBaseMethodAddress();
+ HBasicBlock* entry_block = GetGraph()->GetEntryBlock();
+ entry_block->InsertInstructionBefore(base_, entry_block->GetFirstInstruction());
DCHECK(base_ != nullptr);
}
void ReplaceInput(HInstruction* insn, HConstant* value, int input_index, bool materialize) {
- InitializePCRelativeBasePointer(insn);
+ InitializePCRelativeBasePointer();
HX86LoadFromConstantTable* load_constant =
new (GetGraph()->GetArena()) HX86LoadFromConstantTable(base_, value, materialize);
insn->GetBlock()->InsertInstructionBefore(load_constant, insn);
@@ -111,7 +120,7 @@
// addressing, we need the PC-relative address base.
HInvokeStaticOrDirect* invoke_static_or_direct = invoke->AsInvokeStaticOrDirect();
if (invoke_static_or_direct != nullptr && invoke_static_or_direct->HasPcRelativeDexCache()) {
- InitializePCRelativeBasePointer(invoke);
+ InitializePCRelativeBasePointer();
// Add the extra parameter base_.
DCHECK(!invoke_static_or_direct->HasCurrentMethodInput());
invoke_static_or_direct->AddSpecialInput(base_);
@@ -133,6 +142,7 @@
void PcRelativeFixups::Run() {
PCRelativeHandlerVisitor visitor(graph_);
visitor.VisitInsertionOrder();
+ visitor.MoveBaseIfNeeded();
}
} // namespace x86