diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/Android.mk | 1 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 109 | ||||
| -rw-r--r-- | compiler/optimizing/constant_area_fixups_x86.cc | 132 |
3 files changed, 133 insertions, 109 deletions
diff --git a/compiler/Android.mk b/compiler/Android.mk index 8e3b5550fb..20c80235ba 100644 --- a/compiler/Android.mk +++ b/compiler/Android.mk @@ -66,6 +66,7 @@ LIBART_COMPILER_SRC_FILES := \ optimizing/builder.cc \ optimizing/code_generator.cc \ optimizing/code_generator_utils.cc \ + optimizing/constant_area_fixups_x86.cc \ optimizing/constant_folding.cc \ optimizing/dead_code_elimination.cc \ optimizing/graph_checker.cc \ diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index b60eebf1ba..0ec3780290 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -5922,115 +5922,6 @@ Address CodeGeneratorX86::LiteralCaseTable(HX86PackedSwitch* switch_instr, return Address(reg, value, TIMES_4, kDummy32BitOffset, table_fixup); } -/** - * Finds instructions that need the constant area base as an input. - */ -class ConstantHandlerVisitor : public HGraphVisitor { - public: - explicit ConstantHandlerVisitor(HGraph* graph) : HGraphVisitor(graph), base_(nullptr) {} - - private: - void VisitAdd(HAdd* add) OVERRIDE { - BinaryFP(add); - } - - void VisitSub(HSub* sub) OVERRIDE { - BinaryFP(sub); - } - - void VisitMul(HMul* mul) OVERRIDE { - BinaryFP(mul); - } - - void VisitDiv(HDiv* div) OVERRIDE { - BinaryFP(div); - } - - void VisitReturn(HReturn* ret) OVERRIDE { - HConstant* value = ret->InputAt(0)->AsConstant(); - if ((value != nullptr && Primitive::IsFloatingPointType(value->GetType()))) { - ReplaceInput(ret, value, 0, true); - } - } - - void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE { - HandleInvoke(invoke); - } - - void VisitInvokeVirtual(HInvokeVirtual* invoke) OVERRIDE { - HandleInvoke(invoke); - } - - void VisitInvokeInterface(HInvokeInterface* invoke) OVERRIDE { - HandleInvoke(invoke); - } - - void BinaryFP(HBinaryOperation* bin) { - HConstant* rhs = bin->InputAt(1)->AsConstant(); - if (rhs != nullptr && Primitive::IsFloatingPointType(bin->GetResultType())) { - ReplaceInput(bin, rhs, 1, false); - } - } - - void VisitPackedSwitch(HPackedSwitch* switch_insn) OVERRIDE { - // We need to replace the HPackedSwitch with a HX86PackedSwitch in order to - // address the constant area. - InitializeConstantAreaPointer(switch_insn); - HGraph* graph = GetGraph(); - HBasicBlock* block = switch_insn->GetBlock(); - HX86PackedSwitch* x86_switch = new (graph->GetArena()) HX86PackedSwitch( - switch_insn->GetStartValue(), - switch_insn->GetNumEntries(), - switch_insn->InputAt(0), - base_, - switch_insn->GetDexPc()); - block->ReplaceAndRemoveInstructionWith(switch_insn, x86_switch); - } - - void InitializeConstantAreaPointer(HInstruction* user) { - // 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); - DCHECK(base_ != nullptr); - } - - void ReplaceInput(HInstruction* insn, HConstant* value, int input_index, bool materialize) { - InitializeConstantAreaPointer(insn); - HGraph* graph = GetGraph(); - HBasicBlock* block = insn->GetBlock(); - HX86LoadFromConstantTable* load_constant = - new (graph->GetArena()) HX86LoadFromConstantTable(base_, value, materialize); - block->InsertInstructionBefore(load_constant, insn); - insn->ReplaceInput(load_constant, input_index); - } - - void HandleInvoke(HInvoke* invoke) { - // Ensure that we can load FP arguments from the constant area. - for (size_t i = 0, e = invoke->InputCount(); i < e; i++) { - HConstant* input = invoke->InputAt(i)->AsConstant(); - if (input != nullptr && Primitive::IsFloatingPointType(input->GetType())) { - ReplaceInput(invoke, input, i, true); - } - } - } - - // The generated HX86ComputeBaseMethodAddress in the entry block needed as an - // input to the HX86LoadFromConstantTable instructions. - HX86ComputeBaseMethodAddress* base_; -}; - -void ConstantAreaFixups::Run() { - ConstantHandlerVisitor visitor(graph_); - visitor.VisitInsertionOrder(); -} - // TODO: target as memory. void CodeGeneratorX86::MoveFromReturnRegister(Location target, Primitive::Type type) { if (!target.IsValid()) { diff --git a/compiler/optimizing/constant_area_fixups_x86.cc b/compiler/optimizing/constant_area_fixups_x86.cc new file mode 100644 index 0000000000..c3470002c5 --- /dev/null +++ b/compiler/optimizing/constant_area_fixups_x86.cc @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "constant_area_fixups_x86.h" + +namespace art { +namespace x86 { + +/** + * Finds instructions that need the constant area base as an input. + */ +class ConstantHandlerVisitor : public HGraphVisitor { + public: + explicit ConstantHandlerVisitor(HGraph* graph) : HGraphVisitor(graph), base_(nullptr) {} + + private: + void VisitAdd(HAdd* add) OVERRIDE { + BinaryFP(add); + } + + void VisitSub(HSub* sub) OVERRIDE { + BinaryFP(sub); + } + + void VisitMul(HMul* mul) OVERRIDE { + BinaryFP(mul); + } + + void VisitDiv(HDiv* div) OVERRIDE { + BinaryFP(div); + } + + void VisitReturn(HReturn* ret) OVERRIDE { + HConstant* value = ret->InputAt(0)->AsConstant(); + if ((value != nullptr && Primitive::IsFloatingPointType(value->GetType()))) { + ReplaceInput(ret, value, 0, true); + } + } + + void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE { + HandleInvoke(invoke); + } + + void VisitInvokeVirtual(HInvokeVirtual* invoke) OVERRIDE { + HandleInvoke(invoke); + } + + void VisitInvokeInterface(HInvokeInterface* invoke) OVERRIDE { + HandleInvoke(invoke); + } + + void BinaryFP(HBinaryOperation* bin) { + HConstant* rhs = bin->InputAt(1)->AsConstant(); + if (rhs != nullptr && Primitive::IsFloatingPointType(bin->GetResultType())) { + ReplaceInput(bin, rhs, 1, false); + } + } + + void VisitPackedSwitch(HPackedSwitch* switch_insn) OVERRIDE { + // We need to replace the HPackedSwitch with a HX86PackedSwitch in order to + // address the constant area. + InitializeConstantAreaPointer(switch_insn); + HGraph* graph = GetGraph(); + HBasicBlock* block = switch_insn->GetBlock(); + HX86PackedSwitch* x86_switch = new (graph->GetArena()) HX86PackedSwitch( + switch_insn->GetStartValue(), + switch_insn->GetNumEntries(), + switch_insn->InputAt(0), + base_, + switch_insn->GetDexPc()); + block->ReplaceAndRemoveInstructionWith(switch_insn, x86_switch); + } + + void InitializeConstantAreaPointer(HInstruction* user) { + // 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); + DCHECK(base_ != nullptr); + } + + void ReplaceInput(HInstruction* insn, HConstant* value, int input_index, bool materialize) { + InitializeConstantAreaPointer(insn); + HGraph* graph = GetGraph(); + HBasicBlock* block = insn->GetBlock(); + HX86LoadFromConstantTable* load_constant = + new (graph->GetArena()) HX86LoadFromConstantTable(base_, value, materialize); + block->InsertInstructionBefore(load_constant, insn); + insn->ReplaceInput(load_constant, input_index); + } + + void HandleInvoke(HInvoke* invoke) { + // Ensure that we can load FP arguments from the constant area. + for (size_t i = 0, e = invoke->InputCount(); i < e; i++) { + HConstant* input = invoke->InputAt(i)->AsConstant(); + if (input != nullptr && Primitive::IsFloatingPointType(input->GetType())) { + ReplaceInput(invoke, input, i, true); + } + } + } + + // The generated HX86ComputeBaseMethodAddress in the entry block needed as an + // input to the HX86LoadFromConstantTable instructions. + HX86ComputeBaseMethodAddress* base_; +}; + +void ConstantAreaFixups::Run() { + ConstantHandlerVisitor visitor(graph_); + visitor.VisitInsertionOrder(); +} + +} // namespace x86 +} // namespace art |