OSDN Git Service

Optimizing: Tag arena allocations in SsaBuilder.
authorVladimir Marko <vmarko@google.com>
Tue, 15 Sep 2015 14:33:14 +0000 (15:33 +0100)
committerVladimir Marko <vmarko@google.com>
Wed, 16 Sep 2015 15:41:01 +0000 (16:41 +0100)
Replace GrowableArray with ArenaVector in SsaBuilder and
tag allocations with a new arena allocation type.

Change-Id: I27312c51d7be9d2ad02a974cce93b365c65c5fc4

compiler/optimizing/nodes.cc
compiler/optimizing/nodes.h
compiler/optimizing/nodes_test.cc
compiler/optimizing/ssa_builder.cc
compiler/optimizing/ssa_builder.h
runtime/base/arena_allocator.cc
runtime/base/arena_allocator.h

index 570ce2e..54f4071 100644 (file)
@@ -668,9 +668,9 @@ void HBasicBlock::RemoveInstructionOrPhi(HInstruction* instruction, bool ensure_
   }
 }
 
-void HEnvironment::CopyFrom(const GrowableArray<HInstruction*>& locals) {
-  for (size_t i = 0; i < locals.Size(); i++) {
-    HInstruction* instruction = locals.Get(i);
+void HEnvironment::CopyFrom(const ArenaVector<HInstruction*>& locals) {
+  for (size_t i = 0; i < locals.size(); i++) {
+    HInstruction* instruction = locals[i];
     SetRawEnvAt(i, instruction);
     if (instruction != nullptr) {
       instruction->AddEnvUseAt(this, i);
index 993cc37..70002ad 100644 (file)
@@ -1544,7 +1544,7 @@ class HEnvironment : public ArenaObject<kArenaAllocEnvironment> {
     }
   }
 
-  void CopyFrom(const GrowableArray<HInstruction*>& locals);
+  void CopyFrom(const ArenaVector<HInstruction*>& locals);
   void CopyFrom(HEnvironment* environment);
 
   // Copy from `env`. If it's a loop phi for `loop_header`, copy the first
index fef77aa..8eeac56 100644 (file)
@@ -133,8 +133,8 @@ TEST(Node, ParentEnvironment) {
 
   HEnvironment* environment = new (&allocator) HEnvironment(
       &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic, with_environment);
-  GrowableArray<HInstruction*> array(&allocator, 1);
-  array.Add(parameter1);
+  ArenaVector<HInstruction*> array(allocator.Adapter());
+  array.push_back(parameter1);
 
   environment->CopyFrom(array);
   with_environment->SetRawEnvironment(environment);
index e6209b9..9dcbea0 100644 (file)
@@ -35,7 +35,9 @@ namespace art {
 class DeadPhiHandling : public ValueObject {
  public:
   explicit DeadPhiHandling(HGraph* graph)
-      : graph_(graph), worklist_(graph->GetArena(), kDefaultWorklistSize) {}
+      : graph_(graph), worklist_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
+    worklist_.reserve(kDefaultWorklistSize);
+  }
 
   void Run();
 
@@ -47,7 +49,7 @@ class DeadPhiHandling : public ValueObject {
   bool UpdateType(HPhi* phi);
 
   HGraph* const graph_;
-  GrowableArray<HPhi*> worklist_;
+  ArenaVector<HPhi*> worklist_;
 
   static constexpr size_t kDefaultWorklistSize = 8;
 
@@ -136,8 +138,9 @@ void DeadPhiHandling::VisitBasicBlock(HBasicBlock* block) {
 }
 
 void DeadPhiHandling::ProcessWorklist() {
-  while (!worklist_.IsEmpty()) {
-    HPhi* instruction = worklist_.Pop();
+  while (!worklist_.empty()) {
+    HPhi* instruction = worklist_.back();
+    worklist_.pop_back();
     // Note that the same equivalent phi can be added multiple times in the work list, if
     // used by multiple phis. The first call to `UpdateType` will know whether the phi is
     // dead or live.
@@ -149,7 +152,7 @@ void DeadPhiHandling::ProcessWorklist() {
 
 void DeadPhiHandling::AddToWorklist(HPhi* instruction) {
   DCHECK(instruction->IsLive());
-  worklist_.Add(instruction);
+  worklist_.push_back(instruction);
 }
 
 void DeadPhiHandling::AddDependentInstructionsToWorklist(HPhi* instruction) {
@@ -237,8 +240,7 @@ void SsaBuilder::BuildSsa() {
   }
 
   // 2) Set inputs of loop phis.
-  for (size_t i = 0; i < loop_headers_.Size(); i++) {
-    HBasicBlock* block = loop_headers_.Get(i);
+  for (HBasicBlock* block : loop_headers_) {
     for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
       HPhi* phi = it.Current()->AsPhi();
       for (HBasicBlock* predecessor : block->GetPredecessors()) {
@@ -344,7 +346,9 @@ void SsaBuilder::BuildSsa() {
 }
 
 HInstruction* SsaBuilder::ValueOfLocal(HBasicBlock* block, size_t local) {
-  return GetLocalsFor(block)->Get(local);
+  ArenaVector<HInstruction*>* locals = GetLocalsFor(block);
+  DCHECK_LT(local, locals->size());
+  return (*locals)[local];
 }
 
 void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
@@ -357,22 +361,22 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
     // because we are visiting in reverse post order. We create phis for all initialized
     // locals from the pre header. Their inputs will be populated at the end of
     // the analysis.
-    for (size_t local = 0; local < current_locals_->Size(); local++) {
+    for (size_t local = 0; local < current_locals_->size(); ++local) {
       HInstruction* incoming = ValueOfLocal(block->GetLoopInformation()->GetPreHeader(), local);
       if (incoming != nullptr) {
         HPhi* phi = new (GetGraph()->GetArena()) HPhi(
             GetGraph()->GetArena(), local, 0, Primitive::kPrimVoid);
         block->AddPhi(phi);
-        current_locals_->Put(local, phi);
+        (*current_locals_)[local] = phi;
       }
     }
     // Save the loop header so that the last phase of the analysis knows which
     // blocks need to be updated.
-    loop_headers_.Add(block);
+    loop_headers_.push_back(block);
   } else if (block->GetPredecessors().size() > 0) {
     // All predecessors have already been visited because we are visiting in reverse post order.
     // We merge the values of all locals, creating phis if those values differ.
-    for (size_t local = 0; local < current_locals_->Size(); local++) {
+    for (size_t local = 0; local < current_locals_->size(); ++local) {
       bool one_predecessor_has_no_value = false;
       bool is_different = false;
       HInstruction* value = ValueOfLocal(block->GetPredecessor(0), local);
@@ -403,7 +407,7 @@ void SsaBuilder::VisitBasicBlock(HBasicBlock* block) {
         block->AddPhi(phi);
         value = phi;
       }
-      current_locals_->Put(local, value);
+      (*current_locals_)[local] = value;
     }
   }
 
@@ -534,7 +538,8 @@ HInstruction* SsaBuilder::GetReferenceTypeEquivalent(HInstruction* value) {
 }
 
 void SsaBuilder::VisitLoadLocal(HLoadLocal* load) {
-  HInstruction* value = current_locals_->Get(load->GetLocal()->GetRegNumber());
+  DCHECK_LT(load->GetLocal()->GetRegNumber(), current_locals_->size());
+  HInstruction* value = (*current_locals_)[load->GetLocal()->GetRegNumber()];
   // If the operation requests a specific type, we make sure its input is of that type.
   if (load->GetType() != value->GetType()) {
     if (load->GetType() == Primitive::kPrimFloat || load->GetType() == Primitive::kPrimDouble) {
@@ -548,7 +553,8 @@ void SsaBuilder::VisitLoadLocal(HLoadLocal* load) {
 }
 
 void SsaBuilder::VisitStoreLocal(HStoreLocal* store) {
-  current_locals_->Put(store->GetLocal()->GetRegNumber(), store->InputAt(1));
+  DCHECK_LT(store->GetLocal()->GetRegNumber(), current_locals_->size());
+  (*current_locals_)[store->GetLocal()->GetRegNumber()] = store->InputAt(1);
   store->GetBlock()->RemoveInstruction(store);
 }
 
@@ -556,7 +562,7 @@ void SsaBuilder::VisitInstruction(HInstruction* instruction) {
   if (instruction->NeedsEnvironment()) {
     HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment(
         GetGraph()->GetArena(),
-        current_locals_->Size(),
+        current_locals_->size(),
         GetGraph()->GetDexFile(),
         GetGraph()->GetMethodIdx(),
         instruction->GetDexPc(),
@@ -571,11 +577,12 @@ void SsaBuilder::VisitInstruction(HInstruction* instruction) {
     const HTryBoundary& try_entry =
         instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry();
     for (HExceptionHandlerIterator it(try_entry); !it.Done(); it.Advance()) {
-      GrowableArray<HInstruction*>* handler_locals = GetLocalsFor(it.Current());
-      for (size_t i = 0, e = current_locals_->Size(); i < e; ++i) {
-        HInstruction* local_value = current_locals_->Get(i);
+      ArenaVector<HInstruction*>* handler_locals = GetLocalsFor(it.Current());
+      DCHECK_EQ(handler_locals->size(), current_locals_->size());
+      for (size_t i = 0, e = current_locals_->size(); i < e; ++i) {
+        HInstruction* local_value = (*current_locals_)[i];
         if (local_value != nullptr) {
-          handler_locals->Get(i)->AsPhi()->AddInput(local_value);
+          (*handler_locals)[i]->AsPhi()->AddInput(local_value);
         }
       }
     }
index dc76177..804296f 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
 #define ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
 
+#include "base/arena_containers.h"
 #include "nodes.h"
 #include "optimization.h"
 
@@ -51,33 +52,33 @@ class SsaBuilder : public HGraphVisitor {
   explicit SsaBuilder(HGraph* graph)
       : HGraphVisitor(graph),
         current_locals_(nullptr),
-        loop_headers_(graph->GetArena(), kDefaultNumberOfLoops),
-        locals_for_(graph->GetArena(), graph->GetBlocks().size()) {
-    locals_for_.SetSize(graph->GetBlocks().size());
+        loop_headers_(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
+        locals_for_(graph->GetBlocks().size(),
+                    ArenaVector<HInstruction*>(graph->GetArena()->Adapter(kArenaAllocSsaBuilder)),
+                    graph->GetArena()->Adapter(kArenaAllocSsaBuilder)) {
+    loop_headers_.reserve(kDefaultNumberOfLoops);
   }
 
   void BuildSsa();
 
-  GrowableArray<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
-    GrowableArray<HInstruction*>* locals = locals_for_.Get(block->GetBlockId());
-    if (locals == nullptr) {
+  ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
+    DCHECK_LT(block->GetBlockId(), locals_for_.size());
+    ArenaVector<HInstruction*>* locals = &locals_for_[block->GetBlockId()];
+    if (locals->empty() && GetGraph()->GetNumberOfVRegs() != 0u) {
       const size_t vregs = GetGraph()->GetNumberOfVRegs();
-      ArenaAllocator* arena = GetGraph()->GetArena();
-      locals = new (arena) GrowableArray<HInstruction*>(arena, vregs);
-      locals->SetSize(vregs);
+      locals->resize(vregs, nullptr);
 
       if (block->IsCatchBlock()) {
         // We record incoming inputs of catch phis at throwing instructions and
         // must therefore eagerly create the phis. Unused phis will be removed
         // in the dead phi analysis.
+        ArenaAllocator* arena = GetGraph()->GetArena();
         for (size_t i = 0; i < vregs; ++i) {
           HPhi* phi = new (arena) HPhi(arena, i, 0, Primitive::kPrimVoid);
           block->AddPhi(phi);
-          locals->Put(i, phi);
+          (*locals)[i] = phi;
         }
       }
-
-      locals_for_.Put(block->GetBlockId(), locals);
     }
     return locals;
   }
@@ -107,14 +108,14 @@ class SsaBuilder : public HGraphVisitor {
   static HPhi* GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive::Type type);
 
   // Locals for the current block being visited.
-  GrowableArray<HInstruction*>* current_locals_;
+  ArenaVector<HInstruction*>* current_locals_;
 
   // Keep track of loop headers found. The last phase of the analysis iterates
   // over these blocks to set the inputs of their phis.
-  GrowableArray<HBasicBlock*> loop_headers_;
+  ArenaVector<HBasicBlock*> loop_headers_;
 
   // HEnvironment for each block.
-  GrowableArray<GrowableArray<HInstruction*>*> locals_for_;
+  ArenaVector<ArenaVector<HInstruction*>> locals_for_;
 
   DISALLOW_COPY_AND_ASSIGN(SsaBuilder);
 };
index 337df38..4e51f55 100644 (file)
@@ -74,6 +74,7 @@ const char* const ArenaAllocatorStatsImpl<kCount>::kAllocNames[] = {
   "Environment  ",
   "EnvVRegs     ",
   "EnvLocations ",
+  "SsaBuilder   ",
   "MoveOperands ",
   "CodeBuffer   ",
   "StackMaps    ",
index 8104978..c5eb741 100644 (file)
@@ -84,6 +84,7 @@ enum ArenaAllocKind {
   kArenaAllocEnvironment,
   kArenaAllocEnvironmentVRegs,
   kArenaAllocEnvironmentLocations,
+  kArenaAllocSsaBuilder,
   kArenaAllocMoveOperands,
   kArenaAllocCodeBuffer,
   kArenaAllocStackMaps,