Reduce PassDriver overhead, clean up Pass and PassDriver.
Remove name lookup map and use vector for the pass list.
Add traversal mode kNoNodes to skip BasicBlock traversal.
Replace the warn_override parameter with a DCHECK.
Move iterators from arena to the stack. Style cleanup.
Change-Id: I4bf10e28caa65efb98ce82a4d7486d803ceca535
diff --git a/compiler/dex/bb_optimizations.cc b/compiler/dex/bb_optimizations.cc
index f013067..b6716e6 100644
--- a/compiler/dex/bb_optimizations.cc
+++ b/compiler/dex/bb_optimizations.cc
@@ -23,7 +23,7 @@
/*
* Code Layout pass implementation start.
*/
-bool CodeLayout::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool CodeLayout::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
cUnit->mir_graph->LayoutBlocks(bb);
// No need of repeating, so just return false.
return false;
@@ -32,13 +32,13 @@
/*
* SSATransformation pass implementation start.
*/
-bool SSATransformation::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool SSATransformation::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
cUnit->mir_graph->InsertPhiNodeOperands(bb);
// No need of repeating, so just return false.
return false;
}
-void SSATransformation::End(CompilationUnit *cUnit) const {
+void SSATransformation::End(CompilationUnit* cUnit) const {
// Verify the dataflow information after the pass.
if (cUnit->enable_debug & (1 << kDebugVerifyDataflow)) {
cUnit->mir_graph->VerifyDataflow();
@@ -48,7 +48,7 @@
/*
* ConstantPropagation pass implementation start
*/
-bool ConstantPropagation::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool ConstantPropagation::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
cUnit->mir_graph->DoConstantPropagation(bb);
// No need of repeating, so just return false.
return false;
@@ -57,7 +57,7 @@
/*
* MethodUseCount pass implementation start.
*/
-bool MethodUseCount::Gate(const CompilationUnit *cUnit) const {
+bool MethodUseCount::Gate(const CompilationUnit* cUnit) const {
// First initialize the data.
cUnit->mir_graph->InitializeMethodUses();
@@ -67,7 +67,7 @@
return res;
}
-bool MethodUseCount::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool MethodUseCount::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
cUnit->mir_graph->CountUses(bb);
// No need of repeating, so just return false.
return false;
@@ -77,7 +77,7 @@
* Null Check Elimination and Type Inference Initialization pass implementation start.
*/
-bool NullCheckEliminationAndTypeInferenceInit::Gate(const CompilationUnit *cUnit) const {
+bool NullCheckEliminationAndTypeInferenceInit::Gate(const CompilationUnit* cUnit) const {
// First check the ssa register vector
cUnit->mir_graph->CheckSSARegisterVector();
@@ -87,7 +87,8 @@
return performInit;
}
-bool NullCheckEliminationAndTypeInferenceInit::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool NullCheckEliminationAndTypeInferenceInit::WalkBasicBlocks(CompilationUnit* cUnit,
+ BasicBlock* bb) const {
cUnit->mir_graph->NullCheckEliminationInit(bb);
// No need of repeating, so just return false.
return false;
@@ -96,7 +97,7 @@
/*
* BasicBlock Combine pass implementation start.
*/
-bool BBCombine::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool BBCombine::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
cUnit->mir_graph->CombineBlocks(bb);
// No need of repeating, so just return false.
@@ -106,7 +107,7 @@
/*
* BasicBlock Optimization pass implementation start.
*/
-void BBOptimizations::Start(CompilationUnit *cUnit) const {
+void BBOptimizations::Start(CompilationUnit* cUnit) const {
DCHECK_EQ(cUnit->num_compiler_temps, 0);
/*
diff --git a/compiler/dex/bb_optimizations.h b/compiler/dex/bb_optimizations.h
index 768b273..1286a8e 100644
--- a/compiler/dex/bb_optimizations.h
+++ b/compiler/dex/bb_optimizations.h
@@ -28,14 +28,14 @@
*/
class CodeLayout : public Pass {
public:
- CodeLayout():Pass("CodeLayout", "2_post_layout_cfg") {
+ CodeLayout() : Pass("CodeLayout", "2_post_layout_cfg") {
}
- void Start(CompilationUnit *cUnit) const {
+ void Start(CompilationUnit* cUnit) const {
cUnit->mir_graph->VerifyDataflow();
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
};
/**
@@ -44,16 +44,16 @@
*/
class SSATransformation : public Pass {
public:
- SSATransformation():Pass("SSATransformation", kPreOrderDFSTraversal, "3_post_ssa_cfg") {
+ SSATransformation() : Pass("SSATransformation", kPreOrderDFSTraversal, "3_post_ssa_cfg") {
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
- void Start(CompilationUnit *cUnit) const {
+ void Start(CompilationUnit* cUnit) const {
cUnit->mir_graph->InitializeSSATransformation();
}
- void End(CompilationUnit *cUnit) const;
+ void End(CompilationUnit* cUnit) const;
};
/**
@@ -62,12 +62,12 @@
*/
class ConstantPropagation : public Pass {
public:
- ConstantPropagation():Pass("ConstantPropagation") {
+ ConstantPropagation() : Pass("ConstantPropagation") {
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
- void Start(CompilationUnit *cUnit) const {
+ void Start(CompilationUnit* cUnit) const {
cUnit->mir_graph->InitializeConstantPropagation();
}
};
@@ -78,10 +78,10 @@
*/
class InitRegLocations : public Pass {
public:
- InitRegLocations():Pass("InitRegLocation") {
+ InitRegLocations() : Pass("InitRegLocation", kNoNodes) {
}
- void Start(CompilationUnit *cUnit) const {
+ void Start(CompilationUnit* cUnit) const {
cUnit->mir_graph->InitRegLocations();
}
};
@@ -92,12 +92,12 @@
*/
class MethodUseCount : public Pass {
public:
- MethodUseCount():Pass("UseCount") {
+ MethodUseCount() : Pass("UseCount") {
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
- bool Gate(const CompilationUnit *cUnit) const;
+ bool Gate(const CompilationUnit* cUnit) const;
};
/**
@@ -106,12 +106,12 @@
*/
class NullCheckEliminationAndTypeInferenceInit : public Pass {
public:
- NullCheckEliminationAndTypeInferenceInit():Pass("NCE_TypeInferenceInit") {
+ NullCheckEliminationAndTypeInferenceInit() : Pass("NCE_TypeInferenceInit") {
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
- bool Gate(const CompilationUnit *cUnit) const;
+ bool Gate(const CompilationUnit* cUnit) const;
};
/**
@@ -120,10 +120,11 @@
*/
class NullCheckEliminationAndTypeInference : public Pass {
public:
- NullCheckEliminationAndTypeInference():Pass("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "4_post_nce_cfg") {
+ NullCheckEliminationAndTypeInference()
+ : Pass("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "4_post_nce_cfg") {
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
}
};
@@ -134,14 +135,14 @@
*/
class BBCombine : public Pass {
public:
- BBCombine():Pass("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
+ BBCombine() : Pass("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
}
- bool Gate(const CompilationUnit *cUnit) const {
+ bool Gate(const CompilationUnit* cUnit) const {
return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
}
- bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+ bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
};
/**
@@ -150,14 +151,14 @@
*/
class BBOptimizations : public Pass {
public:
- BBOptimizations():Pass("BBOptimizations", "5_post_bbo_cfg") {
+ BBOptimizations() : Pass("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
}
- bool Gate(const CompilationUnit *cUnit) const {
+ bool Gate(const CompilationUnit* cUnit) const {
return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
}
- void Start(CompilationUnit *cUnit) const;
+ void Start(CompilationUnit* cUnit) const;
};
} // namespace art
diff --git a/compiler/dex/dataflow_iterator-inl.h b/compiler/dex/dataflow_iterator-inl.h
index 0ca1a47..f8b9c1a 100644
--- a/compiler/dex/dataflow_iterator-inl.h
+++ b/compiler/dex/dataflow_iterator-inl.h
@@ -107,7 +107,7 @@
// Find the next BasicBlock.
while (keep_looking == true) {
// Get next BasicBlock.
- res = all_nodes_iterator_->Next();
+ res = all_nodes_iterator_.Next();
// Are we done or is the BasicBlock not hidden?
if ((res == NULL) || (res->hidden == false)) {
diff --git a/compiler/dex/dataflow_iterator.h b/compiler/dex/dataflow_iterator.h
index 658a9b1..b45d6a4 100644
--- a/compiler/dex/dataflow_iterator.h
+++ b/compiler/dex/dataflow_iterator.h
@@ -138,21 +138,6 @@
return ForwardSingleNext();
}
-
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(PreOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
};
/**
@@ -184,21 +169,6 @@
return ForwardRepeatNext();
}
-
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(RepeatingPreOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
};
/**
@@ -230,21 +200,6 @@
return ForwardRepeatNext();
}
-
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(RepeatingPostOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
};
/**
@@ -275,21 +230,6 @@
return ReverseSingleNext();
}
-
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(ReversePostOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
};
/**
@@ -321,21 +261,6 @@
return ReverseRepeatNext();
}
-
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(RepeatingReversePostOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
};
/**
@@ -366,21 +291,6 @@
return ForwardSingleNext();
}
-
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(PostOrderDOMIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
};
/**
@@ -394,16 +304,15 @@
* @param mir_graph The MIRGraph considered.
*/
explicit AllNodesIterator(MIRGraph* mir_graph)
- : DataflowIterator(mir_graph, 0, 0) {
- all_nodes_iterator_ = new
- (mir_graph->GetArena()) GrowableArray<BasicBlock*>::Iterator(mir_graph->GetBlockList());
+ : DataflowIterator(mir_graph, 0, 0),
+ all_nodes_iterator_(mir_graph->GetBlockList()) {
}
/**
* @brief Resetting the iterator.
*/
void Reset() {
- all_nodes_iterator_->Reset();
+ all_nodes_iterator_.Reset();
}
/**
@@ -413,23 +322,8 @@
*/
virtual BasicBlock* Next(bool had_change = false) ALWAYS_INLINE;
- /**
- * @brief Redefine the new operator to use the arena
- * @param size actually unused, we use our own class size
- * @param arena the arena to perform the actual allocation
- * @return the pointer to the newly allocated object
- */
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(AllNodesIterator), ArenaAllocator::kAllocGrowableBitMap);
- }
-
- /**
- * @brief Redefine delete to not actually delete anything since we are using the arena
- */
- static void operator delete(void* p) {}
-
private:
- GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_; /**< @brief The list of all the nodes */
+ GrowableArray<BasicBlock*>::Iterator all_nodes_iterator_; /**< @brief The list of all the nodes */
};
} // namespace art
diff --git a/compiler/dex/growable_array.h b/compiler/dex/growable_array.h
index 639120a..b5842e1 100644
--- a/compiler/dex/growable_array.h
+++ b/compiler/dex/growable_array.h
@@ -66,11 +66,6 @@
idx_ = 0;
}
- static void* operator new(size_t size, ArenaAllocator* arena) {
- return arena->Alloc(sizeof(GrowableArray::Iterator), ArenaAllocator::kAllocGrowableArray);
- };
- static void operator delete(void* p) {} // Nop.
-
private:
size_t idx_;
GrowableArray* const g_list_;
diff --git a/compiler/dex/pass.h b/compiler/dex/pass.h
index c52ddf5..255892e 100644
--- a/compiler/dex/pass.h
+++ b/compiler/dex/pass.h
@@ -41,6 +41,7 @@
kRepeatingPostOrderDFSTraversal, /**< @brief Depth-First-Search / Repeating Post-Order. */
kRepeatingReversePostOrderDFSTraversal, /**< @brief Depth-First-Search / Repeating Reverse Post-Order. */
kPostOrderDOMTraversal, /**< @brief Dominator tree / Post-Order. */
+ kNoNodes, /**< @brief Skip BasicBlock traversal. */
};
/**
@@ -50,20 +51,22 @@
*/
class Pass {
public:
- Pass(const char *name, DataFlowAnalysisMode type, bool freed, const unsigned int f, const char *dump): pass_name_(name), traversal_type_(type), flags_(f), dump_cfg_folder_(dump) {
+ explicit Pass(const char* name, DataFlowAnalysisMode type = kAllNodes,
+ unsigned int flags = 0u, const char* dump = "")
+ : pass_name_(name), traversal_type_(type), flags_(flags), dump_cfg_folder_(dump) {
}
- Pass(const char *name, const char *dump): pass_name_(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_(dump) {
+ Pass(const char* name, DataFlowAnalysisMode type, const char* dump)
+ : pass_name_(name), traversal_type_(type), flags_(0), dump_cfg_folder_(dump) {
}
- explicit Pass(const char *name):pass_name_(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_("") {
+ Pass(const char* name, const char* dump)
+ : pass_name_(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_(dump) {
}
- Pass(const char *name, DataFlowAnalysisMode type, const char *dump):pass_name_(name), traversal_type_(type), flags_(false), dump_cfg_folder_(dump) {
+ virtual ~Pass() {
}
- virtual ~Pass() {}
-
virtual const char* GetName() const {
return pass_name_;
}
@@ -76,14 +79,16 @@
return (flags_ & flag);
}
- const char* GetDumpCFGFolder() const {return dump_cfg_folder_;}
+ const char* GetDumpCFGFolder() const {
+ return dump_cfg_folder_;
+ }
/**
* @brief Gate for the pass: determines whether to execute the pass or not considering a CompilationUnit
* @param c_unit the CompilationUnit.
* @return whether or not to execute the pass
*/
- virtual bool Gate(const CompilationUnit *c_unit) const {
+ virtual bool Gate(const CompilationUnit* c_unit) const {
// Unused parameter.
UNUSED(c_unit);
@@ -95,7 +100,7 @@
* @brief Start of the pass: called before the WalkBasicBlocks function
* @param c_unit the considered CompilationUnit.
*/
- virtual void Start(CompilationUnit *c_unit) const {
+ virtual void Start(CompilationUnit* c_unit) const {
// Unused parameter.
UNUSED(c_unit);
}
@@ -104,7 +109,7 @@
* @brief End of the pass: called after the WalkBasicBlocks function
* @param c_unit the considered CompilationUnit.
*/
- virtual void End(CompilationUnit *c_unit) const {
+ virtual void End(CompilationUnit* c_unit) const {
// Unused parameter.
UNUSED(c_unit);
}
@@ -115,7 +120,7 @@
* @param bb the BasicBlock.
* @return whether or not there is a change when walking the BasicBlock
*/
- virtual bool WalkBasicBlocks(CompilationUnit *c_unit, BasicBlock *bb) const {
+ virtual bool WalkBasicBlocks(CompilationUnit* c_unit, BasicBlock* bb) const {
// Unused parameters.
UNUSED(c_unit);
UNUSED(bb);
diff --git a/compiler/dex/pass_driver.cc b/compiler/dex/pass_driver.cc
index 820dc5a..4f8739a 100644
--- a/compiler/dex/pass_driver.cc
+++ b/compiler/dex/pass_driver.cc
@@ -16,6 +16,8 @@
#include <dlfcn.h>
+#include "base/logging.h"
+#include "base/macros.h"
#include "bb_optimizations.h"
#include "compiler_internals.h"
#include "dataflow_iterator.h"
@@ -28,7 +30,8 @@
namespace { // anonymous namespace
/**
- * @brief Helper function to create a single instance of a given Pass and can be shared across the threads
+ * @brief Helper function to create a single instance of a given Pass and can be shared across
+ * the threads.
*/
template <typename PassType>
const Pass* GetPassInstance() {
@@ -36,55 +39,58 @@
return &pass;
}
+void DoWalkBasicBlocks(CompilationUnit* c_unit, const Pass* pass, DataflowIterator* iterator) {
+ // Paranoid: Check the iterator before walking the BasicBlocks.
+ DCHECK(iterator != nullptr);
+
+ bool change = false;
+ for (BasicBlock *bb = iterator->Next(change); bb != 0; bb = iterator->Next(change)) {
+ change = pass->WalkBasicBlocks(c_unit, bb);
+ }
+}
+
+template <typename Iterator>
+inline void DoWalkBasicBlocks(CompilationUnit* c_unit, const Pass* pass) {
+ Iterator iterator(c_unit->mir_graph.get());
+ DoWalkBasicBlocks(c_unit, pass, &iterator);
+}
+
} // anonymous namespace
-PassDriver::PassDriver(CompilationUnit* cu, bool create_default_passes) : cu_(cu) {
- dump_cfg_folder_ = "/sdcard/";
+PassDriver::PassDriver(CompilationUnit* cu, bool create_default_passes)
+ : cu_(cu), dump_cfg_folder_("/sdcard/") {
+ DCHECK(cu != nullptr);
// If need be, create the default passes.
- if (create_default_passes == true) {
+ if (create_default_passes) {
CreatePasses();
}
}
PassDriver::~PassDriver() {
- // Clear the map: done to remove any chance of having a pointer after freeing below
- pass_map_.clear();
}
-void PassDriver::InsertPass(const Pass* new_pass, bool warn_override) {
- assert(new_pass != 0);
+void PassDriver::InsertPass(const Pass* new_pass) {
+ DCHECK(new_pass != nullptr);
+ DCHECK(new_pass->GetName() != nullptr && new_pass->GetName()[0] != 0);
- // Get name here to not do it all over the method.
- const std::string& name = new_pass->GetName();
+ // It is an error to override an existing pass.
+ DCHECK(GetPass(new_pass->GetName()) == nullptr)
+ << "Pass name " << new_pass->GetName() << " already used.";
- // Do we want to warn the user about squashing a pass?
- if (warn_override == false) {
- auto it = pass_map_.find(name);
-
- if (it != pass_map_.end()) {
- LOG(INFO) << "Pass name " << name << " already used, overwriting pass";
- }
- }
-
- // Now add to map and list.
- pass_map_.Put(name, new_pass);
+ // Now add to the list.
pass_list_.push_back(new_pass);
}
void PassDriver::CreatePasses() {
/*
- * Create the pass list:
- * - These passes are immutable and are shared across the threads:
- * - This is achieved via:
- * - The UniquePtr used here.
- * - DISALLOW_COPY_AND_ASSIGN in the base Pass class.
+ * Create the pass list. These passes are immutable and are shared across the threads.
*
* Advantage is that there will be no race conditions here.
* Disadvantage is the passes can't change their internal states depending on CompilationUnit:
* - This is not yet an issue: no current pass would require it.
*/
- static const Pass* passes[] = {
+ static const Pass* const passes[] = {
GetPassInstance<CodeLayout>(),
GetPassInstance<SSATransformation>(),
GetPassInstance<ConstantPropagation>(),
@@ -96,14 +102,10 @@
GetPassInstance<BBOptimizations>(),
};
- // Get number of elements in the array.
- unsigned int nbr = (sizeof(passes) / sizeof(passes[0]));
-
- // Insert each pass into the map and into the list via the InsertPass method:
- // - Map is used for the lookup
- // - List is used for the pass walk
- for (unsigned int i = 0; i < nbr; i++) {
- InsertPass(passes[i]);
+ // Insert each pass into the list via the InsertPass method.
+ pass_list_.reserve(arraysize(passes));
+ for (const Pass* pass : passes) {
+ InsertPass(pass);
}
}
@@ -114,49 +116,37 @@
}
void PassDriver::DispatchPass(CompilationUnit* c_unit, const Pass* curPass) {
- DataflowIterator* iterator = 0;
-
LOG(DEBUG) << "Dispatching " << curPass->GetName();
- MIRGraph* mir_graph = c_unit->mir_graph.get();
- ArenaAllocator *arena = &(c_unit->arena);
-
- // Let us start by getting the right iterator.
DataFlowAnalysisMode mode = curPass->GetTraversal();
switch (mode) {
case kPreOrderDFSTraversal:
- iterator = new (arena) PreOrderDfsIterator(mir_graph);
+ DoWalkBasicBlocks<PreOrderDfsIterator>(c_unit, curPass);
break;
case kRepeatingPreOrderDFSTraversal:
- iterator = new (arena) RepeatingPreOrderDfsIterator(mir_graph);
+ DoWalkBasicBlocks<RepeatingPreOrderDfsIterator>(c_unit, curPass);
break;
case kRepeatingPostOrderDFSTraversal:
- iterator = new (arena) RepeatingPostOrderDfsIterator(mir_graph);
+ DoWalkBasicBlocks<RepeatingPostOrderDfsIterator>(c_unit, curPass);
break;
case kReversePostOrderDFSTraversal:
- iterator = new (arena) ReversePostOrderDfsIterator(mir_graph);
+ DoWalkBasicBlocks<ReversePostOrderDfsIterator>(c_unit, curPass);
break;
case kRepeatingReversePostOrderDFSTraversal:
- iterator = new (arena) RepeatingReversePostOrderDfsIterator(mir_graph);
+ DoWalkBasicBlocks<RepeatingReversePostOrderDfsIterator>(c_unit, curPass);
break;
case kPostOrderDOMTraversal:
- iterator = new (arena) PostOrderDOMIterator(mir_graph);
+ DoWalkBasicBlocks<PostOrderDOMIterator>(c_unit, curPass);
break;
case kAllNodes:
- iterator = new (arena) AllNodesIterator(mir_graph);
+ DoWalkBasicBlocks<AllNodesIterator>(c_unit, curPass);
+ break;
+ case kNoNodes:
break;
default:
LOG(DEBUG) << "Iterator mode not handled in dispatcher: " << mode;
- return;
- }
-
- // Paranoid: Check the iterator before walking the BasicBlocks.
- assert(iterator != 0);
-
- bool change = false;
- for (BasicBlock *bb = iterator->Next(change); bb != 0; bb = iterator->Next(change)) {
- change = curPass->WalkBasicBlocks(c_unit, bb);
+ break;
}
}
@@ -166,33 +156,34 @@
curPass->End(c_unit);
}
-bool PassDriver::RunPass(CompilationUnit* c_unit, const Pass* curPass, bool time_split) {
- // Paranoid: c_unit or curPass cannot be 0, and the pass should have a name.
- if (c_unit == 0 || curPass == 0 || (strcmp(curPass->GetName(), "") == 0)) {
- return false;
- }
+bool PassDriver::RunPass(CompilationUnit* c_unit, const Pass* pass, bool time_split) {
+ // Paranoid: c_unit and pass cannot be nullptr, and the pass should have a name.
+ DCHECK(c_unit != nullptr);
+ DCHECK(pass != nullptr);
+ DCHECK(pass->GetName() != nullptr && pass->GetName()[0] != 0);
// Do we perform a time split
- if (time_split == true) {
- c_unit->NewTimingSplit(curPass->GetName());
+ if (time_split) {
+ c_unit->NewTimingSplit(pass->GetName());
}
// Check the pass gate first.
- bool shouldApplyPass = curPass->Gate(c_unit);
+ bool should_apply_pass = pass->Gate(c_unit);
- if (shouldApplyPass == true) {
+ if (should_apply_pass) {
// Applying the pass: first start, doWork, and end calls.
- ApplyPass(c_unit, curPass);
+ ApplyPass(c_unit, pass);
// Clean up if need be.
- HandlePassFlag(c_unit, curPass);
+ HandlePassFlag(c_unit, pass);
// Do we want to log it?
if ((c_unit->enable_debug& (1 << kDebugDumpCFG)) != 0) {
// Do we have a pass folder?
- const std::string& passFolder = curPass->GetDumpCFGFolder();
+ const char* passFolder = pass->GetDumpCFGFolder();
+ DCHECK(passFolder != nullptr);
- if (passFolder != "") {
+ if (passFolder[0] != 0) {
// Create directory prefix.
std::string prefix = GetDumpCFGFolder();
prefix += passFolder;
@@ -204,19 +195,18 @@
}
// If the pass gate passed, we can declare success.
- return shouldApplyPass;
+ return should_apply_pass;
}
-bool PassDriver::RunPass(CompilationUnit* c_unit, const std::string& pass_name) {
- // Paranoid: c_unit cannot be 0 and we need a pass name.
- if (c_unit == 0 || pass_name == "") {
- return false;
- }
+bool PassDriver::RunPass(CompilationUnit* c_unit, const char* pass_name) {
+ // Paranoid: c_unit cannot be nullptr and we need a pass name.
+ DCHECK(c_unit != nullptr);
+ DCHECK(pass_name != nullptr && pass_name[0] != 0);
- const Pass* curPass = GetPass(pass_name);
+ const Pass* cur_pass = GetPass(pass_name);
- if (curPass != 0) {
- return RunPass(c_unit, curPass);
+ if (cur_pass != nullptr) {
+ return RunPass(c_unit, cur_pass);
}
// Return false, we did not find the pass.
@@ -224,27 +214,26 @@
}
void PassDriver::Launch() {
- for (const Pass *curPass : pass_list_) {
- RunPass(cu_, curPass, true);
+ for (const Pass* cur_pass : pass_list_) {
+ RunPass(cu_, cur_pass, true);
}
}
void PassDriver::PrintPassNames() const {
LOG(INFO) << "Loop Passes are:";
- for (const Pass *curPass : pass_list_) {
- LOG(INFO) << "\t-" << curPass->GetName();
+ for (const Pass* cur_pass : pass_list_) {
+ LOG(INFO) << "\t-" << cur_pass->GetName();
}
}
-const Pass* PassDriver::GetPass(const std::string& name) const {
- auto it = pass_map_.find(name);
-
- if (it != pass_map_.end()) {
- return it->second;
+const Pass* PassDriver::GetPass(const char* name) const {
+ for (const Pass* cur_pass : pass_list_) {
+ if (strcmp(name, cur_pass->GetName()) == 0) {
+ return cur_pass;
+ }
}
-
- return 0;
+ return nullptr;
}
} // namespace art
diff --git a/compiler/dex/pass_driver.h b/compiler/dex/pass_driver.h
index d580460..c734d3e 100644
--- a/compiler/dex/pass_driver.h
+++ b/compiler/dex/pass_driver.h
@@ -17,7 +17,7 @@
#ifndef ART_COMPILER_DEX_PASS_DRIVER_H_
#define ART_COMPILER_DEX_PASS_DRIVER_H_
-#include <list>
+#include <vector>
#include "pass.h"
#include "safe_map.h"
@@ -42,7 +42,7 @@
* @param new_pass the new Pass to insert in the map and list.
* @param warn_override warn if the name of the Pass is already used.
*/
- void InsertPass(const Pass* new_pass, bool warn_override = true);
+ void InsertPass(const Pass* new_pass);
/**
* @brief Run a pass using the name as key.
@@ -50,7 +50,7 @@
* @param pass_name the Pass name.
* @return whether the pass was applied.
*/
- bool RunPass(CompilationUnit* c_unit, const std::string& pass_name);
+ bool RunPass(CompilationUnit* c_unit, const char* pass_name);
/**
* @brief Run a pass using the Pass itself.
@@ -75,20 +75,17 @@
void PrintPassNames() const;
- const Pass* GetPass(const std::string& name) const;
+ const Pass* GetPass(const char* name) const;
- const char *GetDumpCFGFolder() const {
+ const char* GetDumpCFGFolder() const {
return dump_cfg_folder_;
}
protected:
void CreatePasses();
- /** @brief The Pass Map: contains name -> pass for quick lookup. */
- SafeMap<std::string, const Pass*> pass_map_;
-
/** @brief List of passes: provides the order to execute the passes. */
- std::list<const Pass*> pass_list_;
+ std::vector<const Pass*> pass_list_;
/** @brief The CompilationUnit on which to execute the passes on. */
CompilationUnit* const cu_;