| Index: src/IceCfg.h | 
| diff --git a/src/IceCfg.h b/src/IceCfg.h | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..05e1e3b30ace68b9ccc56b2b85fa8f6ca8cbe7b2 | 
| --- /dev/null | 
| +++ b/src/IceCfg.h | 
| @@ -0,0 +1,144 @@ | 
| +//===- subzero/src/IceCfg.h - Control flow graph ----------------*- C++ -*-===// | 
| +// | 
| +//                        The Subzero Code Generator | 
| +// | 
| +// This file is distributed under the University of Illinois Open Source | 
| +// License. See LICENSE.TXT for details. | 
| +// | 
| +//===----------------------------------------------------------------------===// | 
| +// | 
| +// This file declares the Cfg class, which represents the control flow | 
| +// graph and the overall per-function compilation context. | 
| +// | 
| +//===----------------------------------------------------------------------===// | 
| + | 
| +#ifndef SUBZERO_SRC_ICECFG_H | 
| +#define SUBZERO_SRC_ICECFG_H | 
| + | 
| +#include "IceDefs.h" | 
| +#include "IceTypes.h" | 
| +#include "IceGlobalContext.h" | 
| + | 
| +#include "llvm/ADT/OwningPtr.h" | 
| +#include "llvm/Support/Allocator.h" | 
| + | 
| +namespace Ice { | 
| + | 
| +class Cfg { | 
| +public: | 
| +  Cfg(GlobalContext *Ctx); | 
| +  ~Cfg(); | 
| + | 
| +  GlobalContext *getContext() const { return Ctx; } | 
| + | 
| +  // Manage the name and return type of the function being translated. | 
| +  void setFunctionName(const IceString &Name) { FunctionName = Name; } | 
| +  IceString getFunctionName() const { return FunctionName; } | 
| +  void setReturnType(Type Ty) { ReturnType = Ty; } | 
| + | 
| +  // Manage the "internal" attribute of the function. | 
| +  void setInternal(bool Internal) { IsInternalLinkage = Internal; } | 
| +  bool getInternal() const { return IsInternalLinkage; } | 
| + | 
| +  // Translation error flagging.  If support for some construct is | 
| +  // known to be missing, instead of an assertion failure, setError() | 
| +  // should be called and the error should be propagated back up. | 
| +  // This way, we can gracefully fail to translate and let a fallback | 
| +  // translator handle the function. | 
| +  void setError(const IceString &Message); | 
| +  bool hasError() const { return HasError; } | 
| +  IceString getError() const { return ErrorMessage; } | 
| + | 
| +  // Manage nodes (a.k.a. basic blocks, CfgNodes). | 
| +  void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; } | 
| +  CfgNode *getEntryNode() const { return Entry; } | 
| +  // Create a node and append it to the end of the linearized list. | 
| +  CfgNode *makeNode(const IceString &Name = ""); | 
| +  SizeT getNumNodes() const { return Nodes.size(); } | 
| +  const NodeList &getNodes() const { return Nodes; } | 
| + | 
| +  // Manage instruction numbering. | 
| +  int newInstNumber() { return NextInstNumber++; } | 
| + | 
| +  // Manage Variables. | 
| +  Variable *makeVariable(Type Ty, const CfgNode *Node, | 
| +                         const IceString &Name = ""); | 
| +  SizeT getNumVariables() const { return Variables.size(); } | 
| +  const VarList &getVariables() const { return Variables; } | 
| + | 
| +  // Manage arguments to the function. | 
| +  void addArg(Variable *Arg); | 
| +  const VarList &getArgs() const { return Args; } | 
| + | 
| +  // After the CFG is fully constructed, iterate over the nodes and | 
| +  // compute the predecessor edges, in the form of | 
| +  // CfgNode::InEdges[]. | 
| +  void computePredecessors(); | 
| + | 
| +  // Manage the CurrentNode field, which is used for validating the | 
| +  // Variable::DefNode field during dumping/emitting. | 
| +  void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; } | 
| +  const CfgNode *getCurrentNode() const { return CurrentNode; } | 
| + | 
| +  void dump(); | 
| + | 
| +  // Allocate data of type T using the per-Cfg allocator. | 
| +  template <typename T> T *allocate() { return Allocator.Allocate<T>(); } | 
| + | 
| +  // Allocate an instruction of type T using the per-Cfg instruction allocator. | 
| +  template <typename T> T *allocateInst() { return Allocator.Allocate<T>(); } | 
| + | 
| +  // Allocate an array of data of type T using the per-Cfg allocator. | 
| +  template <typename T> T *allocateArrayOf(size_t NumElems) { | 
| +    return Allocator.Allocate<T>(NumElems); | 
| +  } | 
| + | 
| +  // Deallocate data that was allocated via allocate<T>(). | 
| +  template <typename T> void deallocate(T *Object) { | 
| +    Allocator.Deallocate(Object); | 
| +  } | 
| + | 
| +  // Deallocate data that was allocated via allocateInst<T>(). | 
| +  template <typename T> void deallocateInst(T *Instr) { | 
| +    Allocator.Deallocate(Instr); | 
| +  } | 
| + | 
| +  // Deallocate data that was allocated via allocateArrayOf<T>(). | 
| +  template <typename T> void deallocateArrayOf(T *Array) { | 
| +    Allocator.Deallocate(Array); | 
| +  } | 
| + | 
| +private: | 
| +  // TODO: for now, everything is allocated from the same allocator. In the | 
| +  // future we may want to split this to several allocators, for example in | 
| +  // order to use a "Recycler" to preserve memory. If we keep all allocation | 
| +  // requests from the Cfg exposed via methods, we can always switch the | 
| +  // implementation over at a later point. | 
| +  llvm::BumpPtrAllocator Allocator; | 
| + | 
| +  GlobalContext *Ctx; | 
| +  IceString FunctionName; | 
| +  Type ReturnType; | 
| +  bool IsInternalLinkage; | 
| +  bool HasError; | 
| +  IceString ErrorMessage; | 
| +  CfgNode *Entry; // entry basic block | 
| +  NodeList Nodes; // linearized node list; Entry should be first | 
| +  int NextInstNumber; | 
| +  VarList Variables; | 
| +  VarList Args; // subset of Variables, in argument order | 
| + | 
| +  // CurrentNode is maintained during dumping/emitting just for | 
| +  // validating Variable::DefNode.  Normally, a traversal over | 
| +  // CfgNodes maintains this, but before global operations like | 
| +  // register allocation, setCurrentNode(NULL) should be called to | 
| +  // avoid spurious validation failures. | 
| +  const CfgNode *CurrentNode; | 
| + | 
| +  Cfg(const Cfg &) LLVM_DELETED_FUNCTION; | 
| +  Cfg &operator=(const Cfg &) LLVM_DELETED_FUNCTION; | 
| +}; | 
| + | 
| +} // end of namespace Ice | 
| + | 
| +#endif // SUBZERO_SRC_ICECFG_H | 
|  |