| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 //===- subzero/src/IceCfg.h - Control flow graph ----------------*- C++ -*-===// | 
|  | 2 // | 
|  | 3 //                        The Subzero Code Generator | 
|  | 4 // | 
|  | 5 // This file is distributed under the University of Illinois Open Source | 
|  | 6 // License. See LICENSE.TXT for details. | 
|  | 7 // | 
|  | 8 //===----------------------------------------------------------------------===// | 
|  | 9 // | 
|  | 10 // This file declares the Cfg class, which represents the control flow | 
|  | 11 // graph and the overall per-function compilation context. | 
|  | 12 // | 
|  | 13 //===----------------------------------------------------------------------===// | 
|  | 14 | 
|  | 15 #ifndef SUBZERO_SRC_ICECFG_H | 
|  | 16 #define SUBZERO_SRC_ICECFG_H | 
|  | 17 | 
|  | 18 #include "IceDefs.h" | 
|  | 19 #include "IceTypes.h" | 
|  | 20 #include "IceGlobalContext.h" | 
|  | 21 | 
|  | 22 #include "llvm/ADT/OwningPtr.h" | 
|  | 23 #include "llvm/Support/Allocator.h" | 
|  | 24 | 
|  | 25 namespace Ice { | 
|  | 26 | 
|  | 27 class Cfg { | 
|  | 28 public: | 
|  | 29   Cfg(GlobalContext *Ctx); | 
|  | 30   ~Cfg(); | 
|  | 31 | 
|  | 32   GlobalContext *getContext() const { return Ctx; } | 
|  | 33 | 
|  | 34   // Manage the name and return type of the function being translated. | 
|  | 35   void setFunctionName(const IceString &Name) { FunctionName = Name; } | 
|  | 36   IceString getFunctionName() const { return FunctionName; } | 
|  | 37   void setReturnType(Type Ty) { ReturnType = Ty; } | 
|  | 38 | 
|  | 39   // Manage the "internal" attribute of the function. | 
|  | 40   void setInternal(bool Internal) { IsInternalLinkage = Internal; } | 
|  | 41   bool getInternal() const { return IsInternalLinkage; } | 
|  | 42 | 
|  | 43   // Translation error flagging.  If support for some construct is | 
|  | 44   // known to be missing, instead of an assertion failure, setError() | 
|  | 45   // should be called and the error should be propagated back up. | 
|  | 46   // This way, we can gracefully fail to translate and let a fallback | 
|  | 47   // translator handle the function. | 
|  | 48   void setError(const IceString &Message); | 
|  | 49   bool hasError() const { return HasError; } | 
|  | 50   IceString getError() const { return ErrorMessage; } | 
|  | 51 | 
|  | 52   // Manage nodes (a.k.a. basic blocks, CfgNodes). | 
|  | 53   void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; } | 
|  | 54   CfgNode *getEntryNode() const { return Entry; } | 
|  | 55   // Create a node and append it to the end of the linearized list. | 
|  | 56   CfgNode *makeNode(const IceString &Name = ""); | 
|  | 57   SizeT getNumNodes() const { return Nodes.size(); } | 
|  | 58   const NodeList &getNodes() const { return Nodes; } | 
|  | 59 | 
|  | 60   // Manage instruction numbering. | 
|  | 61   int newInstNumber() { return NextInstNumber++; } | 
|  | 62 | 
|  | 63   // Manage Variables. | 
|  | 64   Variable *makeVariable(Type Ty, const CfgNode *Node, | 
|  | 65                          const IceString &Name = ""); | 
|  | 66   SizeT getNumVariables() const { return Variables.size(); } | 
|  | 67   const VarList &getVariables() const { return Variables; } | 
|  | 68 | 
|  | 69   // Manage arguments to the function. | 
|  | 70   void addArg(Variable *Arg); | 
|  | 71   const VarList &getArgs() const { return Args; } | 
|  | 72 | 
|  | 73   // After the CFG is fully constructed, iterate over the nodes and | 
|  | 74   // compute the predecessor edges, in the form of | 
|  | 75   // CfgNode::InEdges[]. | 
|  | 76   void computePredecessors(); | 
|  | 77 | 
|  | 78   // Manage the CurrentNode field, which is used for validating the | 
|  | 79   // Variable::DefNode field during dumping/emitting. | 
|  | 80   void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; } | 
|  | 81   const CfgNode *getCurrentNode() const { return CurrentNode; } | 
|  | 82 | 
|  | 83   void dump(); | 
|  | 84 | 
|  | 85   // Allocate data of type T using the per-Cfg allocator. | 
|  | 86   template <typename T> T *allocate() { return Allocator.Allocate<T>(); } | 
|  | 87 | 
|  | 88   // Allocate an instruction of type T using the per-Cfg instruction allocator. | 
|  | 89   template <typename T> T *allocateInst() { return Allocator.Allocate<T>(); } | 
|  | 90 | 
|  | 91   // Allocate an array of data of type T using the per-Cfg allocator. | 
|  | 92   template <typename T> T *allocateArrayOf(size_t NumElems) { | 
|  | 93     return Allocator.Allocate<T>(NumElems); | 
|  | 94   } | 
|  | 95 | 
|  | 96   // Deallocate data that was allocated via allocate<T>(). | 
|  | 97   template <typename T> void deallocate(T *Object) { | 
|  | 98     Allocator.Deallocate(Object); | 
|  | 99   } | 
|  | 100 | 
|  | 101   // Deallocate data that was allocated via allocateInst<T>(). | 
|  | 102   template <typename T> void deallocateInst(T *Instr) { | 
|  | 103     Allocator.Deallocate(Instr); | 
|  | 104   } | 
|  | 105 | 
|  | 106   // Deallocate data that was allocated via allocateArrayOf<T>(). | 
|  | 107   template <typename T> void deallocateArrayOf(T *Array) { | 
|  | 108     Allocator.Deallocate(Array); | 
|  | 109   } | 
|  | 110 | 
|  | 111 private: | 
|  | 112   // TODO: for now, everything is allocated from the same allocator. In the | 
|  | 113   // future we may want to split this to several allocators, for example in | 
|  | 114   // order to use a "Recycler" to preserve memory. If we keep all allocation | 
|  | 115   // requests from the Cfg exposed via methods, we can always switch the | 
|  | 116   // implementation over at a later point. | 
|  | 117   llvm::BumpPtrAllocator Allocator; | 
|  | 118 | 
|  | 119   GlobalContext *Ctx; | 
|  | 120   IceString FunctionName; | 
|  | 121   Type ReturnType; | 
|  | 122   bool IsInternalLinkage; | 
|  | 123   bool HasError; | 
|  | 124   IceString ErrorMessage; | 
|  | 125   CfgNode *Entry; // entry basic block | 
|  | 126   NodeList Nodes; // linearized node list; Entry should be first | 
|  | 127   int NextInstNumber; | 
|  | 128   VarList Variables; | 
|  | 129   VarList Args; // subset of Variables, in argument order | 
|  | 130 | 
|  | 131   // CurrentNode is maintained during dumping/emitting just for | 
|  | 132   // validating Variable::DefNode.  Normally, a traversal over | 
|  | 133   // CfgNodes maintains this, but before global operations like | 
|  | 134   // register allocation, setCurrentNode(NULL) should be called to | 
|  | 135   // avoid spurious validation failures. | 
|  | 136   const CfgNode *CurrentNode; | 
|  | 137 | 
|  | 138   Cfg(const Cfg &) LLVM_DELETED_FUNCTION; | 
|  | 139   Cfg &operator=(const Cfg &) LLVM_DELETED_FUNCTION; | 
|  | 140 }; | 
|  | 141 | 
|  | 142 } // end of namespace Ice | 
|  | 143 | 
|  | 144 #endif // SUBZERO_SRC_ICECFG_H | 
| OLD | NEW | 
|---|