summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-04-07 15:26:35 +0100
committerNicolas Geoffray <ngeoffray@google.com>2014-04-08 08:43:50 +0100
commitb55f835d66a61e5da6fc1895ba5a0482868c9552 (patch)
tree44659a826aeadcf2bf176c2e8d31108ba64c88eb /compiler/optimizing
parent427ca38b0a6c6fd7dc0dbb380619e2b91b56cf1c (diff)
downloadart-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.cc57
-rw-r--r--compiler/optimizing/builder.h1
-rw-r--r--compiler/optimizing/code_generator.cc23
-rw-r--r--compiler/optimizing/code_generator.h1
-rw-r--r--compiler/optimizing/code_generator_arm.cc13
-rw-r--r--compiler/optimizing/code_generator_x86.cc13
-rw-r--r--compiler/optimizing/nodes.h13
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) { }