diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-07 15:26:35 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-08 08:43:50 +0100 |
commit | b55f835d66a61e5da6fc1895ba5a0482868c9552 (patch) | |
tree | 44659a826aeadcf2bf176c2e8d31108ba64c88eb /compiler/optimizing | |
parent | 427ca38b0a6c6fd7dc0dbb380619e2b91b56cf1c (diff) | |
download | art-b55f835d66a61e5da6fc1895ba5a0482868c9552.zip art-b55f835d66a61e5da6fc1895ba5a0482868c9552.tar.gz art-b55f835d66a61e5da6fc1895ba5a0482868c9552.tar.bz2 |
Test control flow instruction with optimizing compiler.
Add support for basic instructions to implement these tests.
Change-Id: I3870bf9301599043b3511522bb49dc6364c9b4c0
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/builder.cc | 57 | ||||
-rw-r--r-- | compiler/optimizing/builder.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 23 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 13 |
7 files changed, 82 insertions, 39 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index f89583d..beccf01 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -44,15 +44,14 @@ bool HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) { graph_->SetNumberOfInVRegs(number_of_parameters); const char* shorty = dex_compilation_unit_->GetShorty(); int locals_index = locals_.Size() - number_of_parameters; - HBasicBlock* first_block = entry_block_->GetSuccessors()->Get(0); int parameter_index = 0; if (!dex_compilation_unit_->IsStatic()) { // Add the implicit 'this' argument, not expressed in the signature. HParameterValue* parameter = new (arena_) HParameterValue(parameter_index++); - first_block->AddInstruction(parameter); + entry_block_->AddInstruction(parameter); HLocal* local = GetLocalAt(locals_index++); - first_block->AddInstruction(new (arena_) HStoreLocal(local, parameter)); + entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter)); number_of_parameters--; } @@ -68,11 +67,11 @@ bool HGraphBuilder::InitializeParameters(uint16_t number_of_parameters) { default: { // integer and reference parameters. HParameterValue* parameter = new (arena_) HParameterValue(parameter_index++); - first_block->AddInstruction(parameter); + entry_block_->AddInstruction(parameter); HLocal* local = GetLocalAt(locals_index++); // Store the parameter value in the local that the dex code will use // to reference that parameter. - first_block->AddInstruction(new (arena_) HStoreLocal(local, parameter)); + entry_block_->AddInstruction(new (arena_) HStoreLocal(local, parameter)); break; } } @@ -87,6 +86,24 @@ static bool CanHandleCodeItem(const DexFile::CodeItem& code_item) { return true; } +template<typename T> +void HGraphBuilder::If_22t(const Instruction& instruction, int32_t dex_offset, bool is_not) { + HInstruction* first = LoadLocal(instruction.VRegA()); + HInstruction* second = LoadLocal(instruction.VRegB()); + current_block_->AddInstruction(new (arena_) T(first, second)); + if (is_not) { + current_block_->AddInstruction(new (arena_) HNot(current_block_->GetLastInstruction())); + } + current_block_->AddInstruction(new (arena_) HIf(current_block_->GetLastInstruction())); + HBasicBlock* target = FindBlockStartingAt(instruction.GetTargetOffset() + dex_offset); + DCHECK(target != nullptr); + current_block_->AddSuccessor(target); + target = FindBlockStartingAt(dex_offset + instruction.SizeInCodeUnits()); + DCHECK(target != nullptr); + current_block_->AddSuccessor(target); + current_block_ = nullptr; +} + HGraph* HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item) { if (!CanHandleCodeItem(code_item)) { return nullptr; @@ -238,6 +255,19 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ break; } + case Instruction::CONST_16: { + int32_t register_index = instruction.VRegA(); + HIntConstant* constant = GetConstant(instruction.VRegB_21s()); + UpdateLocal(register_index, constant); + break; + } + + case Instruction::MOVE: { + HInstruction* value = LoadLocal(instruction.VRegB()); + UpdateLocal(instruction.VRegA(), value); + break; + } + case Instruction::RETURN_VOID: { current_block_->AddInstruction(new (arena_) HReturnVoid()); current_block_->AddSuccessor(exit_block_); @@ -246,17 +276,12 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ } case Instruction::IF_EQ: { - HInstruction* first = LoadLocal(instruction.VRegA()); - HInstruction* second = LoadLocal(instruction.VRegB()); - current_block_->AddInstruction(new (arena_) HEqual(first, second)); - current_block_->AddInstruction(new (arena_) HIf(current_block_->GetLastInstruction())); - HBasicBlock* target = FindBlockStartingAt(instruction.GetTargetOffset() + dex_offset); - DCHECK(target != nullptr); - current_block_->AddSuccessor(target); - target = FindBlockStartingAt(dex_offset + instruction.SizeInCodeUnits()); - DCHECK(target != nullptr); - current_block_->AddSuccessor(target); - current_block_ = nullptr; + If_22t<HEqual>(instruction, dex_offset, false); + break; + } + + case Instruction::IF_NE: { + If_22t<HEqual>(instruction, dex_offset, true); break; } diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index df64d71..60d9982 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -79,6 +79,7 @@ class HGraphBuilder : public ValueObject { template<typename T> void Binop_12x(const Instruction& instruction); template<typename T> void Binop_22b(const Instruction& instruction, bool reverse); template<typename T> void Binop_22s(const Instruction& instruction, bool reverse); + template<typename T> void If_22t(const Instruction& instruction, int32_t dex_offset, bool is_not); ArenaAllocator* const arena_; diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 40a7b6f..7e63c69 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -33,8 +33,8 @@ void CodeGenerator::Compile(CodeAllocator* allocator) { const GrowableArray<HBasicBlock*>* blocks = GetGraph()->GetBlocks(); DCHECK(blocks->Get(0) == GetGraph()->GetEntryBlock()); DCHECK(GoesToNextBlock(GetGraph()->GetEntryBlock(), blocks->Get(1))); - CompileEntryBlock(); - for (size_t i = 1; i < blocks->Size(); i++) { + GenerateFrameEntry(); + for (size_t i = 0; i < blocks->Size(); i++) { CompileBlock(blocks->Get(i)); } size_t code_size = GetAssembler()->CodeSize(); @@ -43,30 +43,11 @@ void CodeGenerator::Compile(CodeAllocator* allocator) { GetAssembler()->FinalizeInstructions(code); } -void CodeGenerator::CompileEntryBlock() { - HGraphVisitor* location_builder = GetLocationBuilder(); - HGraphVisitor* instruction_visitor = GetInstructionVisitor(); - if (kIsDebugBuild) { - for (HInstructionIterator it(GetGraph()->GetEntryBlock()); !it.Done(); it.Advance()) { - HInstruction* current = it.Current(); - // Instructions in the entry block should not generate code. - current->Accept(location_builder); - DCHECK(current->GetLocations() == nullptr); - current->Accept(instruction_visitor); - } - } - GenerateFrameEntry(); -} - void CodeGenerator::CompileBlock(HBasicBlock* block) { Bind(GetLabelOf(block)); HGraphVisitor* location_builder = GetLocationBuilder(); HGraphVisitor* instruction_visitor = GetInstructionVisitor(); for (HInstructionIterator it(block); !it.Done(); it.Advance()) { - // For each instruction, we emulate a stack-based machine, where the inputs are popped from - // the runtime stack, and the result is pushed on the stack. We currently can do this because - // we do not perform any code motion, and the Dex format does not reference individual - // instructions but uses registers instead (our equivalent of HLocal). HInstruction* current = it.Current(); current->Accept(location_builder); InitLocations(current); diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index e144733..6648598 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -180,7 +180,6 @@ class CodeGenerator : public ArenaObject { private: void InitLocations(HInstruction* instruction); void CompileBlock(HBasicBlock* block); - void CompileEntryBlock(); HGraph* const graph_; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 2364bc8..4e88765 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -149,7 +149,6 @@ void LocationsBuilderARM::VisitLocal(HLocal* local) { void InstructionCodeGeneratorARM::VisitLocal(HLocal* local) { DCHECK_EQ(local->GetBlock(), GetGraph()->GetEntryBlock()); - codegen_->SetFrameSize(codegen_->GetFrameSize() + kArmWordSize); } void LocationsBuilderARM::VisitLoadLocal(HLoadLocal* load) { @@ -384,5 +383,17 @@ void InstructionCodeGeneratorARM::VisitParameterValue(HParameterValue* instructi } } +void LocationsBuilderARM::VisitNot(HNot* instruction) { + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); + locations->SetInAt(0, Location(R0)); + locations->SetOut(Location(R0)); + instruction->SetLocations(locations); +} + +void InstructionCodeGeneratorARM::VisitNot(HNot* instruction) { + LocationSummary* locations = instruction->GetLocations(); + __ eor(locations->Out().reg<Register>(), locations->InAt(0).reg<Register>(), ShifterOperand(1)); +} + } // namespace arm } // namespace art diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 540a72a..88198dc 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -379,5 +379,18 @@ void InstructionCodeGeneratorX86::VisitParameterValue(HParameterValue* instructi } } +void LocationsBuilderX86::VisitNot(HNot* instruction) { + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); + locations->SetInAt(0, Location(EAX)); + locations->SetOut(Location(EAX)); + instruction->SetLocations(locations); +} + +void InstructionCodeGeneratorX86::VisitNot(HNot* instruction) { + LocationSummary* locations = instruction->GetLocations(); + DCHECK_EQ(locations->InAt(0).reg<Register>(), locations->Out().reg<Register>()); + __ xorl(locations->Out().reg<Register>(), Immediate(1)); +} + } // namespace x86 } // namespace art diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index d1f672f..adea0ba 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -227,6 +227,7 @@ class HBasicBlock : public ArenaObject { M(LoadLocal) \ M(Local) \ M(NewInstance) \ + M(Not) \ M(ParameterValue) \ M(PushArgument) \ M(Return) \ @@ -740,6 +741,18 @@ class HParameterValue : public HTemplateInstruction<0> { DISALLOW_COPY_AND_ASSIGN(HParameterValue); }; +class HNot : public HTemplateInstruction<1> { + public: + explicit HNot(HInstruction* input) { + SetRawInputAt(0, input); + } + + DECLARE_INSTRUCTION(Not); + + private: + DISALLOW_COPY_AND_ASSIGN(HNot); +}; + class HGraphVisitor : public ValueObject { public: explicit HGraphVisitor(HGraph* graph) : graph_(graph) { } |