diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-05-22 12:50:17 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-05-26 11:31:38 +0100 |
commit | a7062e05e6048c7f817d784a5b94e3122e25b1ec (patch) | |
tree | a5d6b64ae6d5352f761fc2547bda863281adbe40 /compiler/optimizing/ssa_builder.cc | |
parent | 8b5b1e5593ffa77c393e4172b71a3d5a821d2ed8 (diff) | |
download | art-a7062e05e6048c7f817d784a5b94e3122e25b1ec.zip art-a7062e05e6048c7f817d784a5b94e3122e25b1ec.tar.gz art-a7062e05e6048c7f817d784a5b94e3122e25b1ec.tar.bz2 |
Add a linear scan register allocator to the optimizing compiler.
This is a "by-the-book" implementation. It currently only deals
with allocating registers, with no hint optimizations.
The changes remaining to make it functional are:
- Allocate spill slots.
- Resolution and placements of Move instructions.
- Connect it to the code generator.
Change-Id: Ie0b2f6ba1b98da85425be721ce4afecd6b4012a4
Diffstat (limited to 'compiler/optimizing/ssa_builder.cc')
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 50e3254..33084df 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -19,6 +19,18 @@ namespace art { +static Primitive::Type MergeTypes(Primitive::Type existing, Primitive::Type new_type) { + // We trust the verifier has already done the necessary checking. + switch (existing) { + case Primitive::kPrimFloat: + case Primitive::kPrimDouble: + case Primitive::kPrimNot: + return existing; + default: + return new_type; + } +} + void SsaBuilder::BuildSsa() { // 1) Visit in reverse post order. We need to have all predecessors of a block visited // (with the exception of loops) in order to create the right environment for that @@ -32,11 +44,16 @@ void SsaBuilder::BuildSsa() { HBasicBlock* block = loop_headers_.Get(i); for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { HPhi* phi = it.Current()->AsPhi(); + Primitive::Type type = Primitive::kPrimVoid; for (size_t pred = 0; pred < block->GetPredecessors().Size(); pred++) { - phi->AddInput(ValueOfLocal(block->GetPredecessors().Get(pred), phi->GetRegNumber())); + HInstruction* input = ValueOfLocal(block->GetPredecessors().Get(pred), phi->GetRegNumber()); + phi->AddInput(input); + type = MergeTypes(type, input->GetType()); } + phi->SetType(type); } } + // TODO: Now that the type of loop phis is set, we need a type propagation phase. // 3) Clear locals. // TODO: Move this to a dead code eliminator phase. @@ -65,7 +82,6 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) { for (size_t local = 0; local < current_locals_->Size(); local++) { HInstruction* incoming = ValueOfLocal(block->GetLoopInformation()->GetPreHeader(), local); if (incoming != nullptr) { - // TODO: Compute union type. HPhi* phi = new (GetGraph()->GetArena()) HPhi( GetGraph()->GetArena(), local, 0, Primitive::kPrimVoid); block->AddPhi(phi); @@ -88,12 +104,18 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) { } } if (is_different) { - // TODO: Compute union type. HPhi* phi = new (GetGraph()->GetArena()) HPhi( GetGraph()->GetArena(), local, block->GetPredecessors().Size(), Primitive::kPrimVoid); + Primitive::Type type = Primitive::kPrimVoid; for (size_t i = 0; i < block->GetPredecessors().Size(); i++) { - phi->SetRawInputAt(i, ValueOfLocal(block->GetPredecessors().Get(i), local)); + HInstruction* value = ValueOfLocal(block->GetPredecessors().Get(i), local); + // We need to merge the incoming types, as the Dex format does not + // guarantee the inputs have the same type. In particular the 0 constant is + // used for all types, but the graph builder treats it as an int. + type = MergeTypes(type, value->GetType()); + phi->SetRawInputAt(i, value); } + phi->SetType(type); block->AddPhi(phi); value = phi; } |