blob: e12bc9de0a77626817f960e86c2a3356ba879433 [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- 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
25namespace Ice {
26
27class Cfg {
28public:
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.
Jim Stichnothd97c7df2014-06-04 11:57:08 -070061 InstNumberT newInstNumber() { return NextInstNumber++; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070062
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; }
Matt Wala45a06232014-07-09 16:33:22 -070072 VarList &getArgs() { return Args; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070073
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070074 // Miscellaneous accessors.
75 TargetLowering *getTarget() const { return Target.get(); }
Jim Stichnothd97c7df2014-06-04 11:57:08 -070076 Liveness *getLiveness() const { return Live.get(); }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070077 bool hasComputedFrame() const;
78
79 // Passes over the CFG.
80 void translate();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070081 // After the CFG is fully constructed, iterate over the nodes and
82 // compute the predecessor edges, in the form of
83 // CfgNode::InEdges[].
84 void computePredecessors();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070085 void renumberInstructions();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070086 void placePhiLoads();
87 void placePhiStores();
88 void deletePhis();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070089 void doAddressOpt();
Matt Wala45a06232014-07-09 16:33:22 -070090 void doArgLowering();
Matt Walac3302742014-08-15 16:21:56 -070091 void doNopInsertion();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070092 void genCode();
93 void genFrame();
Jim Stichnothd97c7df2014-06-04 11:57:08 -070094 void livenessLightweight();
95 void liveness(LivenessMode Mode);
96 bool validateLiveness() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070097
98 // Manage the CurrentNode field, which is used for validating the
99 // Variable::DefNode field during dumping/emitting.
100 void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; }
101 const CfgNode *getCurrentNode() const { return CurrentNode; }
102
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700103 void emit();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700104 void dump(const IceString &Message = "");
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700105
106 // Allocate data of type T using the per-Cfg allocator.
107 template <typename T> T *allocate() { return Allocator.Allocate<T>(); }
108
109 // Allocate an instruction of type T using the per-Cfg instruction allocator.
110 template <typename T> T *allocateInst() { return Allocator.Allocate<T>(); }
111
112 // Allocate an array of data of type T using the per-Cfg allocator.
113 template <typename T> T *allocateArrayOf(size_t NumElems) {
114 return Allocator.Allocate<T>(NumElems);
115 }
116
117 // Deallocate data that was allocated via allocate<T>().
118 template <typename T> void deallocate(T *Object) {
119 Allocator.Deallocate(Object);
120 }
121
122 // Deallocate data that was allocated via allocateInst<T>().
123 template <typename T> void deallocateInst(T *Instr) {
124 Allocator.Deallocate(Instr);
125 }
126
127 // Deallocate data that was allocated via allocateArrayOf<T>().
128 template <typename T> void deallocateArrayOf(T *Array) {
129 Allocator.Deallocate(Array);
130 }
131
132private:
133 // TODO: for now, everything is allocated from the same allocator. In the
134 // future we may want to split this to several allocators, for example in
135 // order to use a "Recycler" to preserve memory. If we keep all allocation
136 // requests from the Cfg exposed via methods, we can always switch the
137 // implementation over at a later point.
138 llvm::BumpPtrAllocator Allocator;
139
140 GlobalContext *Ctx;
141 IceString FunctionName;
142 Type ReturnType;
143 bool IsInternalLinkage;
144 bool HasError;
145 IceString ErrorMessage;
146 CfgNode *Entry; // entry basic block
147 NodeList Nodes; // linearized node list; Entry should be first
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700148 InstNumberT NextInstNumber;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700149 VarList Variables;
150 VarList Args; // subset of Variables, in argument order
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700151 llvm::OwningPtr<Liveness> Live;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700152 llvm::OwningPtr<TargetLowering> Target;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700153
154 // CurrentNode is maintained during dumping/emitting just for
155 // validating Variable::DefNode. Normally, a traversal over
156 // CfgNodes maintains this, but before global operations like
157 // register allocation, setCurrentNode(NULL) should be called to
158 // avoid spurious validation failures.
159 const CfgNode *CurrentNode;
160
161 Cfg(const Cfg &) LLVM_DELETED_FUNCTION;
162 Cfg &operator=(const Cfg &) LLVM_DELETED_FUNCTION;
163};
164
165} // end of namespace Ice
166
167#endif // SUBZERO_SRC_ICECFG_H