From f8c762b8cbd4a223c697d7e7bdb976fb39224cb8 Mon Sep 17 00:00:00 2001 From: Jean Christophe Beyler Date: Fri, 2 May 2014 12:54:37 -0700 Subject: ART: ChildBlockIterator Implementation - Added the API to be able to walk through a BasicBlock's children directly. - When calling Reset(GrowableArray*), there is an assignment to the g_list_ member. This is not possible with the g_list_ being const. Change-Id: I25d06484fd93848d80ccf96a1324058370b2ee46 Signed-Off-By: Jean Christophe Beyler Signed-off-by: Razvan A Lupusoru Signed-off-by: Yixin Shou Signed-off-by: Chao-ying Fu Signed-off-by: Udayan Banerji --- compiler/dex/mir_graph.cc | 51 +++++++++++++++++++++++++++++++++++++++++++++++ compiler/dex/mir_graph.h | 23 +++++++++++++++++++++ 2 files changed, 74 insertions(+) (limited to 'compiler/dex') diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index 30d0bc3d0a..ca90a833cc 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -1257,4 +1257,55 @@ void MIRGraph::InitializeSSATransformation() { DoDFSPreOrderSSARename(GetEntryBlock()); } +ChildBlockIterator::ChildBlockIterator(BasicBlock* bb, MIRGraph* mir_graph) + : basic_block_(bb), mir_graph_(mir_graph), visited_fallthrough_(false), + visited_taken_(false), have_successors_(false) { + // Check if we actually do have successors. + if (basic_block_ != 0 && basic_block_->successor_block_list_type != kNotUsed) { + have_successors_ = true; + successor_iter_.Reset(basic_block_->successor_blocks); + } +} + +BasicBlock* ChildBlockIterator::Next() { + // We check if we have a basic block. If we don't we cannot get next child. + if (basic_block_ == nullptr) { + return nullptr; + } + + // If we haven't visited fallthrough, return that. + if (visited_fallthrough_ == false) { + visited_fallthrough_ = true; + + BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->fall_through); + if (result != nullptr) { + return result; + } + } + + // If we haven't visited taken, return that. + if (visited_taken_ == false) { + visited_taken_ = true; + + BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->taken); + if (result != nullptr) { + return result; + } + } + + // We visited both taken and fallthrough. Now check if we have successors we need to visit. + if (have_successors_ == true) { + // Get information about next successor block. + SuccessorBlockInfo* successor_block_info = successor_iter_.Next(); + + // If we don't have anymore successors, return nullptr. + if (successor_block_info != nullptr) { + return mir_graph_->GetBasicBlock(successor_block_info->block); + } + } + + // We do not have anything. + return nullptr; +} + } // namespace art diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index c728d84942..85a2d04306 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -341,6 +341,29 @@ struct SuccessorBlockInfo { int key; }; +/** + * @class ChildBlockIterator + * @brief Enable an easy iteration of the children. + */ +class ChildBlockIterator { + public: + /** + * @brief Constructs a child iterator. + * @param bb The basic whose children we need to iterate through. + * @param mir_graph The MIRGraph used to get the basic block during iteration. + */ + ChildBlockIterator(BasicBlock* bb, MIRGraph* mir_graph); + BasicBlock* Next(); + + private: + BasicBlock* basic_block_; + MIRGraph* mir_graph_; + bool visited_fallthrough_; + bool visited_taken_; + bool have_successors_; + GrowableArray::Iterator successor_iter_; +}; + /* * Whereas a SSA name describes a definition of a Dalvik vreg, the RegLocation describes * the type of an SSA name (and, can also be used by code generators to record where the -- cgit v1.2.3