summaryrefslogtreecommitdiffstats
path: root/compiler/sea_ir/ir/sea.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/sea_ir/ir/sea.h')
-rw-r--r--compiler/sea_ir/ir/sea.h353
1 files changed, 0 insertions, 353 deletions
diff --git a/compiler/sea_ir/ir/sea.h b/compiler/sea_ir/ir/sea.h
deleted file mode 100644
index 26b16be019..0000000000
--- a/compiler/sea_ir/ir/sea.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ART_COMPILER_SEA_IR_IR_SEA_H_
-#define ART_COMPILER_SEA_IR_IR_SEA_H_
-
-#include <set>
-#include <map>
-
-#include "utils/scoped_hashtable.h"
-#include "gtest/gtest_prod.h"
-#include "dex_file.h"
-#include "dex_instruction.h"
-#include "sea_ir/ir/instruction_tools.h"
-#include "sea_ir/ir/instruction_nodes.h"
-
-namespace sea_ir {
-
-// Reverse post-order numbering constants
-enum RegionNumbering {
- NOT_VISITED = -1,
- VISITING = -2
-};
-
-class TypeInference;
-class CodeGenData;
-
-class Region;
-class InstructionNode;
-class PhiInstructionNode;
-class SignatureNode;
-
-// A SignatureNode is a declaration of one parameter in the function signature.
-// This class is used to provide place-holder definitions to which instructions
-// can return from the GetSSAUses() calls, instead of having missing SSA edges.
-class SignatureNode: public InstructionNode {
- public:
- // Creates a new signature node representing the initial definition of the
- // register @register_no which is the @signature_position-th argument to the method.
- explicit SignatureNode(unsigned int register_no, unsigned int signature_position):
- InstructionNode(NULL), register_no_(register_no), position_(signature_position) { }
-
- int GetResultRegister() const {
- return register_no_;
- }
-
- unsigned int GetPositionInSignature() const {
- return position_;
- }
-
- std::vector<int> GetUses() const {
- return std::vector<int>();
- }
-
- void Accept(IRVisitor* v) {
- v->Visit(this);
- v->Traverse(this);
- }
-
- private:
- const unsigned int register_no_;
- const unsigned int position_; // The position of this parameter node is
- // in the function parameter list.
-};
-
-class PhiInstructionNode: public InstructionNode {
- public:
- explicit PhiInstructionNode(int register_no):
- InstructionNode(NULL), register_no_(register_no), definition_edges_() {}
- // Returns the register on which this phi-function is used.
- int GetRegisterNumber() const {
- return register_no_;
- }
-
- // Renames the use of @reg_no to refer to the instruction @definition.
- // Phi-functions are different than normal instructions in that they
- // have multiple predecessor regions; this is why RenameToSSA has
- // the additional parameter specifying that @parameter_id is the incoming
- // edge for @definition, essentially creating SSA form.
- void RenameToSSA(int reg_no, InstructionNode* definition, unsigned int predecessor_id) {
- DCHECK(NULL != definition) << "Tried to rename to SSA using a NULL definition for "
- << StringId() << " register " << reg_no;
- if (definition_edges_.size() < predecessor_id+1) {
- definition_edges_.resize(predecessor_id+1, NULL);
- }
- if (NULL == definition_edges_.at(predecessor_id)) {
- definition_edges_[predecessor_id] = new std::vector<InstructionNode*>();
- }
- definition_edges_[predecessor_id]->push_back(definition);
- definition->AddSSAUse(this);
- }
-
- // Returns the ordered set of Instructions that define the input operands of this instruction.
- // Precondition: SeaGraph.ConvertToSSA().
- std::vector<InstructionNode*> GetSSAProducers() {
- std::vector<InstructionNode*> producers;
- for (std::vector<std::vector<InstructionNode*>*>::const_iterator
- cit = definition_edges_.begin(); cit != definition_edges_.end(); cit++) {
- producers.insert(producers.end(), (*cit)->begin(), (*cit)->end());
- }
- return producers;
- }
-
- // Returns the instruction that defines the phi register from predecessor
- // on position @predecessor_pos. Note that the return value is vector<> just
- // for consistency with the return value of GetSSAUses() on regular instructions,
- // The returned vector should always have a single element because the IR is SSA.
- std::vector<InstructionNode*>* GetSSAUses(int predecessor_pos) {
- return definition_edges_.at(predecessor_pos);
- }
-
- void Accept(IRVisitor* v) {
- v->Visit(this);
- v->Traverse(this);
- }
-
- private:
- int register_no_;
- // This vector has one entry for each predecessors, each with a single
- // element, storing the id of the instruction that defines the register
- // corresponding to this phi function.
- std::vector<std::vector<InstructionNode*>*> definition_edges_;
-};
-
-// This class corresponds to a basic block in traditional compiler IRs.
-// The dataflow analysis relies on this class both during execution and
-// for storing its results.
-class Region : public SeaNode {
- public:
- explicit Region():
- SeaNode(), successors_(), predecessors_(), reaching_defs_size_(0),
- rpo_number_(NOT_VISITED), idom_(NULL), idominated_set_(), df_(), phi_set_() {
- string_id_ = "cluster_" + string_id_;
- }
- // Adds @instruction as an instruction node child in the current region.
- void AddChild(sea_ir::InstructionNode* instruction);
- // Returns the last instruction node child of the current region.
- // This child has the CFG successors pointing to the new regions.
- SeaNode* GetLastChild() const;
- // Returns all the child instructions of this region, in program order.
- std::vector<InstructionNode*>* GetInstructions() {
- return &instructions_;
- }
-
- // Computes Downward Exposed Definitions for the current node.
- void ComputeDownExposedDefs();
- const std::map<int, sea_ir::InstructionNode*>* GetDownExposedDefs() const;
- // Performs one iteration of the reaching definitions algorithm
- // and returns true if the reaching definitions set changed.
- bool UpdateReachingDefs();
- // Returns the set of reaching definitions for the current region.
- std::map<int, std::set<sea_ir::InstructionNode*>* >* GetReachingDefs();
-
- void SetRPO(int rpo) {
- rpo_number_ = rpo;
- }
-
- int GetRPO() {
- return rpo_number_;
- }
-
- void SetIDominator(Region* dom) {
- idom_ = dom;
- }
-
- Region* GetIDominator() const {
- return idom_;
- }
-
- void AddToIDominatedSet(Region* dominated) {
- idominated_set_.insert(dominated);
- }
-
- const std::set<Region*>* GetIDominatedSet() {
- return &idominated_set_;
- }
- // Adds @df_reg to the dominance frontier of the current region.
- void AddToDominanceFrontier(Region* df_reg) {
- df_.insert(df_reg);
- }
- // Returns the dominance frontier of the current region.
- // Preconditions: SeaGraph.ComputeDominanceFrontier()
- std::set<Region*>* GetDominanceFrontier() {
- return &df_;
- }
- // Returns true if the region contains a phi function for @reg_no.
- bool ContainsPhiFor(int reg_no) {
- return (phi_set_.end() != phi_set_.find(reg_no));
- }
- // Returns the phi-functions from the region.
- std::vector<PhiInstructionNode*>* GetPhiNodes() {
- return &phi_instructions_;
- }
- // Adds a phi-function for @reg_no to this region.
- // Note: The insertion order does not matter, as phi-functions
- // are conceptually executed at the same time.
- bool InsertPhiFor(int reg_no);
- // Sets the phi-function uses to be as defined in @scoped_table for predecessor @@predecessor.
- void SetPhiDefinitionsForUses(const utils::ScopedHashtable<int, InstructionNode*>* scoped_table,
- Region* predecessor);
-
- void Accept(IRVisitor* v) {
- v->Visit(this);
- v->Traverse(this);
- }
-
- void AddSuccessor(Region* successor) {
- DCHECK(successor) << "Tried to add NULL successor to SEA node.";
- successors_.push_back(successor);
- return;
- }
- void AddPredecessor(Region* predecessor) {
- DCHECK(predecessor) << "Tried to add NULL predecessor to SEA node.";
- predecessors_.push_back(predecessor);
- }
-
- std::vector<sea_ir::Region*>* GetSuccessors() {
- return &successors_;
- }
- std::vector<sea_ir::Region*>* GetPredecessors() {
- return &predecessors_;
- }
-
- private:
- std::vector<sea_ir::Region*> successors_; // CFG successor nodes (regions)
- std::vector<sea_ir::Region*> predecessors_; // CFG predecessor nodes (instructions/regions)
- std::vector<sea_ir::InstructionNode*> instructions_;
- std::map<int, sea_ir::InstructionNode*> de_defs_;
- std::map<int, std::set<sea_ir::InstructionNode*>* > reaching_defs_;
- int reaching_defs_size_;
- int rpo_number_; // reverse postorder number of the region
- // Immediate dominator node.
- Region* idom_;
- // The set of nodes immediately dominated by the region.
- std::set<Region*> idominated_set_;
- // Records the dominance frontier.
- std::set<Region*> df_;
- // Records the set of register numbers that have phi nodes in this region.
- std::set<int> phi_set_;
- std::vector<PhiInstructionNode*> phi_instructions_;
-};
-
-// A SeaGraph instance corresponds to a source code function.
-// Its main point is to encapsulate the SEA IR representation of it
-// and acts as starting point for visitors (ex: during code generation).
-class SeaGraph: IVisitable {
- public:
- static SeaGraph* GetGraph(const art::DexFile&);
-
- CodeGenData* CompileMethod(const std::string& function_name,
- const art::DexFile::CodeItem* code_item, uint16_t class_def_idx,
- uint32_t method_idx, uint32_t method_access_flags, const art::DexFile& dex_file);
- // Returns all regions corresponding to this SeaGraph.
- std::vector<Region*>* GetRegions() {
- return &regions_;
- }
- // Recursively computes the reverse postorder value for @crt_bb and successors.
- static void ComputeRPO(Region* crt_bb, int& crt_rpo);
- // Returns the "lowest common ancestor" of @i and @j in the dominator tree.
- static Region* Intersect(Region* i, Region* j);
- // Returns the vector of parameters of the function.
- std::vector<SignatureNode*>* GetParameterNodes() {
- return &parameters_;
- }
-
- const art::DexFile* GetDexFile() const {
- return &dex_file_;
- }
-
- virtual void Accept(IRVisitor* visitor) {
- visitor->Initialize(this);
- visitor->Visit(this);
- visitor->Traverse(this);
- }
-
- TypeInference* ti_;
- uint16_t class_def_idx_;
- uint32_t method_idx_;
- uint32_t method_access_flags_;
-
- protected:
- explicit SeaGraph(const art::DexFile& df);
- virtual ~SeaGraph() { }
-
- private:
- FRIEND_TEST(RegionsTest, Basics);
- // Registers @childReg as a region belonging to the SeaGraph instance.
- void AddRegion(Region* childReg);
- // Returns new region and registers it with the SeaGraph instance.
- Region* GetNewRegion();
- // Adds a (formal) parameter node to the vector of parameters of the function.
- void AddParameterNode(SignatureNode* parameterNode) {
- parameters_.push_back(parameterNode);
- }
- // Adds a CFG edge from @src node to @dst node.
- void AddEdge(Region* src, Region* dst) const;
- // Builds the non-SSA sea-ir representation of the function @code_item from @dex_file
- // with class id @class_def_idx and method id @method_idx.
- void BuildMethodSeaGraph(const art::DexFile::CodeItem* code_item,
- const art::DexFile& dex_file, uint16_t class_def_idx,
- uint32_t method_idx, uint32_t method_access_flags);
- // Computes immediate dominators for each region.
- // Precondition: ComputeMethodSeaGraph()
- void ComputeIDominators();
- // Computes Downward Exposed Definitions for all regions in the graph.
- void ComputeDownExposedDefs();
- // Computes the reaching definitions set following the equations from
- // Cooper & Torczon, "Engineering a Compiler", second edition, page 491.
- // Precondition: ComputeDEDefs()
- void ComputeReachingDefs();
- // Computes the reverse-postorder numbering for the region nodes.
- // Precondition: ComputeDEDefs()
- void ComputeRPO();
- // Computes the dominance frontier for all regions in the graph,
- // following the algorithm from
- // Cooper & Torczon, "Engineering a Compiler", second edition, page 499.
- // Precondition: ComputeIDominators()
- void ComputeDominanceFrontier();
- // Converts the IR to semi-pruned SSA form.
- void ConvertToSSA();
- // Performs the renaming phase of the SSA transformation during ConvertToSSA() execution.
- void RenameAsSSA();
- // Identifies the definitions corresponding to uses for region @node
- // by using the scoped hashtable of names @ scoped_table.
- void RenameAsSSA(Region* node, utils::ScopedHashtable<int, InstructionNode*>* scoped_table);
- // Generate LLVM IR for the method.
- // Precondition: ConvertToSSA().
- CodeGenData* GenerateLLVM(const std::string& function_name, const art::DexFile& dex_file);
- // Inserts one SignatureNode for each argument of the function in
- void InsertSignatureNodes(const art::DexFile::CodeItem* code_item, Region* r);
-
- static SeaGraph graph_;
- std::vector<Region*> regions_;
- std::vector<SignatureNode*> parameters_;
- const art::DexFile& dex_file_;
- const art::DexFile::CodeItem* code_item_;
-};
-} // namespace sea_ir
-#endif // ART_COMPILER_SEA_IR_IR_SEA_H_