blob: 3a3dcbfdf709392c088b0e6ca4e6a3ec08e2ffba [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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares the Cfg class, which represents the control flow graph and
12/// the overall per-function compilation context.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
Jim Stichnothf7c9a142014-04-29 10:52:43 -070014//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICECFG_H
17#define SUBZERO_SRC_ICECFG_H
18
John Portoaff4ccf2015-06-10 16:35:06 -070019#include "IceAssembler.h"
Jan Voung8acded02014-09-22 18:02:25 -070020#include "IceClFlags.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070021#include "IceDefs.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070022#include "IceGlobalContext.h"
Manasij Mukherjeeadf352b2016-07-19 13:31:36 -070023#include "IceLoopAnalyzer.h"
Jim Stichnoth467ffe52016-03-29 15:01:06 -070024#include "IceStringPool.h"
Jim Stichnotha18cc9c2014-09-30 19:10:22 -070025#include "IceTypes.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070026
27namespace Ice {
28
29class Cfg {
Jim Stichnothc6ead202015-02-24 09:30:30 -080030 Cfg() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070031 Cfg(const Cfg &) = delete;
32 Cfg &operator=(const Cfg &) = delete;
33
Nicolas Capensa9a92a52016-09-06 12:59:58 -040034 std::unique_ptr<ArenaAllocator> Allocator;
35
Jim Stichnothf7c9a142014-04-29 10:52:43 -070036public:
Jim Stichnothf7c9a142014-04-29 10:52:43 -070037 ~Cfg();
38
Jim Stichnothbbca7542015-02-11 16:08:31 -080039 static std::unique_ptr<Cfg> create(GlobalContext *Ctx,
40 uint32_t SequenceNumber) {
41 return std::unique_ptr<Cfg>(new Cfg(Ctx, SequenceNumber));
Jim Stichnoth31c95592014-12-19 12:51:35 -080042 }
Jim Stichnoth31c95592014-12-19 12:51:35 -080043
Jim Stichnothf7c9a142014-04-29 10:52:43 -070044 GlobalContext *getContext() const { return Ctx; }
Jim Stichnothbbca7542015-02-11 16:08:31 -080045 uint32_t getSequenceNumber() const { return SequenceNumber; }
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -070046 OptLevel getOptLevel() const { return OptimizationLevel; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070047
Jim Stichnotha5229652015-11-12 10:25:21 -080048 static constexpr VerboseMask defaultVerboseMask() {
Jim Stichnoth9f9aa2c2016-03-07 08:25:24 -080049 return (IceV_NO_PER_PASS_DUMP_BEYOND << 1) - 1;
Jim Stichnotha5229652015-11-12 10:25:21 -080050 }
Andrew Scull57e12682015-09-16 11:30:19 -070051 /// Returns true if any of the specified options in the verbose mask are set.
52 /// If the argument is omitted, it checks if any verbose options at all are
53 /// set.
Jim Stichnotha5229652015-11-12 10:25:21 -080054 bool isVerbose(VerboseMask Mask = defaultVerboseMask()) const {
55 return VMask & Mask;
56 }
Jim Stichnothfa4efea2015-01-27 05:06:03 -080057 void setVerbose(VerboseMask Mask) { VMask = Mask; }
58
Andrew Scull9612d322015-07-06 14:53:25 -070059 /// \name Manage the name and return type of the function being translated.
60 /// @{
Jim Stichnoth467ffe52016-03-29 15:01:06 -070061 void setFunctionName(GlobalString Name) { FunctionName = Name; }
62 GlobalString getFunctionName() const { return FunctionName; }
63 std::string getFunctionNameAndSize() const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070064 void setReturnType(Type Ty) { ReturnType = Ty; }
David Sehr0d9cf482015-11-16 17:00:38 -080065 Type getReturnType() const { return ReturnType; }
Andrew Scull9612d322015-07-06 14:53:25 -070066 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067
Andrew Scull9612d322015-07-06 14:53:25 -070068 /// \name Manage the "internal" attribute of the function.
69 /// @{
Jim Stichnothf7c9a142014-04-29 10:52:43 -070070 void setInternal(bool Internal) { IsInternalLinkage = Internal; }
71 bool getInternal() const { return IsInternalLinkage; }
Andrew Scull9612d322015-07-06 14:53:25 -070072 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070073
Andrew Scull9612d322015-07-06 14:53:25 -070074 /// \name Manage errors.
75 /// @{
76
Andrew Scull57e12682015-09-16 11:30:19 -070077 /// Translation error flagging. If support for some construct is known to be
78 /// missing, instead of an assertion failure, setError() should be called and
79 /// the error should be propagated back up. This way, we can gracefully fail
80 /// to translate and let a fallback translator handle the function.
Jim Stichnoth467ffe52016-03-29 15:01:06 -070081 void setError(const std::string &Message);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070082 bool hasError() const { return HasError; }
Jim Stichnoth467ffe52016-03-29 15:01:06 -070083 std::string getError() const { return ErrorMessage; }
Andrew Scull9612d322015-07-06 14:53:25 -070084 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070085
Andrew Scull9612d322015-07-06 14:53:25 -070086 /// \name Manage nodes (a.k.a. basic blocks, CfgNodes).
87 /// @{
Jim Stichnothf7c9a142014-04-29 10:52:43 -070088 void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; }
89 CfgNode *getEntryNode() const { return Entry; }
Andrew Scullaa6c1092015-09-03 17:50:30 -070090 /// Create a node and append it to the end of the linearized list. The loop
91 /// nest depth of the new node may not be valid if it is created after
92 /// computeLoopNestDepth.
Jim Stichnoth668a7a32014-12-10 15:32:25 -080093 CfgNode *makeNode();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070094 SizeT getNumNodes() const { return Nodes.size(); }
95 const NodeList &getNodes() const { return Nodes; }
Jim Stichnothe7dbc0b2015-09-15 10:09:24 -070096 /// Swap nodes of Cfg with given list of nodes. The number of nodes must
97 /// remain unchanged.
Karl Schimpfac7d7342015-08-06 12:55:23 -070098 void swapNodes(NodeList &NewNodes);
Andrew Scull9612d322015-07-06 14:53:25 -070099 /// @}
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800100
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700101 /// String pool for CfgNode::Name values.
102 StringPool *getNodeStrings() const { return NodeStrings.get(); }
103 /// String pool for Variable::Name values.
104 StringPool *getVarStrings() const { return VarStrings.get(); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700105
Andrew Scull9612d322015-07-06 14:53:25 -0700106 /// \name Manage instruction numbering.
107 /// @{
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700108 InstNumberT newInstNumber() { return NextInstNumber++; }
Jim Stichnoth47752552014-10-13 17:15:08 -0700109 InstNumberT getNextInstNumber() const { return NextInstNumber; }
Andrew Scull9612d322015-07-06 14:53:25 -0700110 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700111
Andrew Scull9612d322015-07-06 14:53:25 -0700112 /// \name Manage Variables.
113 /// @{
114
Andrew Scull57e12682015-09-16 11:30:19 -0700115 /// Create a new Variable with a particular type and an optional name. The
116 /// Node argument is the node where the variable is defined.
Jim Stichnothe343e062016-06-28 21:40:33 -0700117 // TODO(jpp): untemplate this with separate methods: makeVariable and
118 // makeStackVariable.
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800119 template <typename T = Variable> T *makeVariable(Type Ty) {
Jim Stichnoth800dab22014-09-20 12:25:02 -0700120 SizeT Index = Variables.size();
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800121 auto *Var = T::create(this, Ty, Index);
Jim Stichnoth800dab22014-09-20 12:25:02 -0700122 Variables.push_back(Var);
123 return Var;
124 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700125 SizeT getNumVariables() const { return Variables.size(); }
126 const VarList &getVariables() const { return Variables; }
Andrew Scull9612d322015-07-06 14:53:25 -0700127 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700128
Andrew Scull9612d322015-07-06 14:53:25 -0700129 /// \name Manage arguments to the function.
130 /// @{
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700131 void addArg(Variable *Arg);
132 const VarList &getArgs() const { return Args; }
Matt Wala45a06232014-07-09 16:33:22 -0700133 VarList &getArgs() { return Args; }
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700134 void addImplicitArg(Variable *Arg);
135 const VarList &getImplicitArgs() const { return ImplicitArgs; }
Andrew Scull9612d322015-07-06 14:53:25 -0700136 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700137
Andrew Scull86df4e92015-07-30 13:54:44 -0700138 /// \name Manage the jump tables.
139 /// @{
140 void addJumpTable(InstJumpTable *JumpTable) {
141 JumpTables.emplace_back(JumpTable);
142 }
143 /// @}
144
John Portodc619252016-02-10 15:57:16 -0800145 /// \name Manage the Globals used by this function.
146 /// @{
147 std::unique_ptr<VariableDeclarationList> getGlobalInits() {
148 return std::move(GlobalInits);
149 }
150 void addGlobal(VariableDeclaration *Global) {
151 if (GlobalInits == nullptr) {
152 GlobalInits.reset(new VariableDeclarationList);
153 }
154 GlobalInits->push_back(Global);
155 }
John Portoa78e4ba2016-03-15 09:28:04 -0700156 VariableDeclarationList *getGlobalPool() {
157 if (GlobalInits == nullptr) {
158 GlobalInits.reset(new VariableDeclarationList);
159 }
160 return GlobalInits.get();
161 }
John Portodc619252016-02-10 15:57:16 -0800162 /// @}
163
Andrew Scull9612d322015-07-06 14:53:25 -0700164 /// \name Miscellaneous accessors.
165 /// @{
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700166 TargetLowering *getTarget() const { return Target.get(); }
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700167 VariablesMetadata *getVMetadata() const { return VMetadata.get(); }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700168 Liveness *getLiveness() const { return Live.get(); }
Jim Stichnothbbca7542015-02-11 16:08:31 -0800169 template <typename T = Assembler> T *getAssembler() const {
John Porto2da710c2015-06-29 07:57:02 -0700170 return llvm::dyn_cast<T>(TargetAssembler.get());
Jan Voung8acded02014-09-22 18:02:25 -0700171 }
John Portobd2e2312016-03-15 11:06:25 -0700172 std::unique_ptr<Assembler> releaseAssembler() {
173 return std::move(TargetAssembler);
174 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700175 bool hasComputedFrame() const;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700176 bool getFocusedTiming() const { return FocusedTiming; }
177 void setFocusedTiming() { FocusedTiming = true; }
Qining Luaee5fa82015-08-20 14:59:03 -0700178 uint32_t getConstantBlindingCookie() const { return ConstantBlindingCookie; }
Andrew Scull9612d322015-07-06 14:53:25 -0700179 /// @}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700180
Andrew Scull9612d322015-07-06 14:53:25 -0700181 /// Returns true if Var is a global variable that is used by the profiling
182 /// code.
John Portof8b4cc82015-06-09 18:06:19 -0700183 static bool isProfileGlobal(const VariableDeclaration &Var);
184
Andrew Scull9612d322015-07-06 14:53:25 -0700185 /// Passes over the CFG.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700186 void translate();
Andrew Scull57e12682015-09-16 11:30:19 -0700187 /// After the CFG is fully constructed, iterate over the nodes and compute the
188 /// predecessor and successor edges, in the form of CfgNode::InEdges[] and
189 /// CfgNode::OutEdges[].
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700190 void computeInOutEdges();
Jim Stichnoth76719b42016-03-14 08:37:52 -0700191 /// Renumber the non-deleted instructions in the Cfg. This needs to be done
192 /// in preparation for live range analysis. The instruction numbers in a
193 /// block must be monotonically increasing. The range of instruction numbers
194 /// in a block, from lowest to highest, must not overlap with the range of any
195 /// other block.
196 ///
197 /// Also, if the configuration specifies to do so, remove/unlink all deleted
198 /// instructions from the Cfg, to speed up later passes over the instructions.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700199 void renumberInstructions();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700200 void placePhiLoads();
201 void placePhiStores();
202 void deletePhis();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700203 void advancedPhiLowering();
204 void reorderNodes();
Qining Lu969f6a32015-07-31 09:58:34 -0700205 void shuffleNodes();
Manasij Mukherjee53c8fbd2016-08-01 15:40:42 -0700206 void localCSE(bool AssumeSSA);
Manasij Mukherjee5bcc6ca2016-08-04 14:24:58 -0700207 void floatConstantCSE();
Manasij Mukherjee45f51a22016-06-27 16:12:37 -0700208 void shortCircuitJumps();
Manasij Mukherjeef47d5202016-07-12 16:59:17 -0700209 void loopInvariantCodeMotion();
David Sehr4318a412015-11-11 15:01:55 -0800210
David Sehr4318a412015-11-11 15:01:55 -0800211 /// Scan allocas to determine whether we need to use a frame pointer.
212 /// If SortAndCombine == true, merge all the fixed-size allocas in the
213 /// entry block and emit stack or frame pointer-relative addressing.
214 void processAllocas(bool SortAndCombine);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700215 void doAddressOpt();
John Portoa47c11c2016-04-21 05:53:42 -0700216 /// Find clusters of insertelement/extractelement instructions that can be
217 /// replaced by a shufflevector instruction.
218 void materializeVectorShuffles();
Matt Wala45a06232014-07-09 16:33:22 -0700219 void doArgLowering();
Matt Walac3302742014-08-15 16:21:56 -0700220 void doNopInsertion();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700221 void genCode();
222 void genFrame();
Manasij Mukherjeef47d5202016-07-12 16:59:17 -0700223 void generateLoopInfo();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700224 void livenessLightweight();
225 void liveness(LivenessMode Mode);
226 bool validateLiveness() const;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700227 void contractEmptyNodes();
Jim Stichnothff9c7062014-09-18 04:50:49 -0700228 void doBranchOpt();
Andrew Scull86df4e92015-07-30 13:54:44 -0700229 void markNodesForSandboxing();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700230
Andrew Scull9612d322015-07-06 14:53:25 -0700231 /// \name Manage the CurrentNode field.
232 /// CurrentNode is used for validating the Variable::DefNode field during
233 /// dumping/emitting.
234 /// @{
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700235 void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; }
Jim Stichnothae953202014-12-20 06:17:49 -0800236 void resetCurrentNode() { setCurrentNode(nullptr); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700237 const CfgNode *getCurrentNode() const { return CurrentNode; }
Andrew Scull9612d322015-07-06 14:53:25 -0700238 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700239
John Portoa3984a12016-04-01 11:14:30 -0700240 /// Get the total amount of memory held by the per-Cfg allocator.
241 size_t getTotalMemoryMB() const;
242
243 /// Get the current memory usage due to liveness data structures.
244 size_t getLivenessMemoryMB() const;
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800245
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700246 void emit();
Jan Voung0faec4c2014-11-05 17:29:56 -0800247 void emitIAS();
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700248 static void emitTextHeader(GlobalString Name, GlobalContext *Ctx,
Jim Stichnothbbca7542015-02-11 16:08:31 -0800249 const Assembler *Asm);
Jim Stichnothb88d8c82016-03-11 15:33:00 -0800250 void dump(const char *Message = "");
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700251
Andrew Scull9612d322015-07-06 14:53:25 -0700252 /// Allocate data of type T using the per-Cfg allocator.
Jim Stichnoth31c95592014-12-19 12:51:35 -0800253 template <typename T> T *allocate() { return Allocator->Allocate<T>(); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700254
Andrew Scull9612d322015-07-06 14:53:25 -0700255 /// Allocate an array of data of type T using the per-Cfg allocator.
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700256 template <typename T> T *allocateArrayOf(size_t NumElems) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800257 return Allocator->Allocate<T>(NumElems);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700258 }
259
Andrew Scull9612d322015-07-06 14:53:25 -0700260 /// Deallocate data that was allocated via allocate<T>().
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700261 template <typename T> void deallocate(T *Object) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800262 Allocator->Deallocate(Object);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700263 }
264
Andrew Scull9612d322015-07-06 14:53:25 -0700265 /// Deallocate data that was allocated via allocateArrayOf<T>().
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700266 template <typename T> void deallocateArrayOf(T *Array) {
Jim Stichnoth31c95592014-12-19 12:51:35 -0800267 Allocator->Deallocate(Array);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700268 }
269
Eric Holk16f80612016-04-04 17:07:42 -0700270 /// Update Phi labels with InEdges.
271 ///
272 /// The WASM translator cannot always determine the right incoming edge for a
273 /// value due to the CFG being built incrementally. The fixPhiNodes pass fills
274 /// in the correct information once everything is known.
275 void fixPhiNodes();
276
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700277private:
John Portoe82b5602016-02-24 15:58:55 -0800278 friend class CfgAllocatorTraits; // for Allocator access.
279
Jim Stichnothbbca7542015-02-11 16:08:31 -0800280 Cfg(GlobalContext *Ctx, uint32_t SequenceNumber);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700281
Andrew Scull9612d322015-07-06 14:53:25 -0700282 /// Adds a call to the ProfileSummary runtime function as the first
283 /// instruction in this CFG's entry block.
John Portof8b4cc82015-06-09 18:06:19 -0700284 void addCallToProfileSummary();
285
Andrew Scull9612d322015-07-06 14:53:25 -0700286 /// Iterates over the basic blocks in this CFG, adding profiling code to each
287 /// one of them. It returns a list with all the globals that the profiling
288 /// code needs to be defined.
John Portof8b4cc82015-06-09 18:06:19 -0700289 void profileBlocks();
290
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700291 void createNodeNameDeclaration(const std::string &NodeAsmName);
John Portoa78e4ba2016-03-15 09:28:04 -0700292 void
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700293 createBlockProfilingInfoDeclaration(const std::string &NodeAsmName,
John Portoa78e4ba2016-03-15 09:28:04 -0700294 VariableDeclaration *NodeNameDeclaration);
295
Andrew Scull86df4e92015-07-30 13:54:44 -0700296 /// Iterate through the registered jump tables and emit them.
297 void emitJumpTables();
298
Jim Stichnoth3607b6c2015-11-13 14:28:23 -0800299 enum AllocaBaseVariableType {
300 BVT_StackPointer,
301 BVT_FramePointer,
302 BVT_UserPointer
303 };
Thomas Lively1fd80c72016-06-27 14:47:21 -0700304 void sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas,
Jim Stichnoth3607b6c2015-11-13 14:28:23 -0800305 uint32_t CombinedAlignment, InstList &Insts,
306 AllocaBaseVariableType BaseVariableType);
307 void findRematerializable();
Manasij Mukherjeeadf352b2016-07-19 13:31:36 -0700308 CfgVector<Inst *>
309 findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body);
Jim Stichnoth3607b6c2015-11-13 14:28:23 -0800310
Nicolas Capensa9a92a52016-09-06 12:59:58 -0400311 static ArenaAllocator *createAllocator();
312
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700313 GlobalContext *Ctx;
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700314 uint32_t SequenceNumber; /// output order for emission
315 OptLevel OptimizationLevel = Opt_m1;
Qining Luaee5fa82015-08-20 14:59:03 -0700316 uint32_t ConstantBlindingCookie = 0; /// cookie for constant blinding
Jim Stichnothfa4efea2015-01-27 05:06:03 -0800317 VerboseMask VMask;
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700318 GlobalString FunctionName;
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700319 Type ReturnType = IceType_void;
320 bool IsInternalLinkage = false;
321 bool HasError = false;
322 bool FocusedTiming = false;
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700323 std::string ErrorMessage = "";
Andrew Scull9612d322015-07-06 14:53:25 -0700324 CfgNode *Entry = nullptr; /// entry basic block
325 NodeList Nodes; /// linearized node list; Entry should be first
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700326 InstNumberT NextInstNumber;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700327 VarList Variables;
Andrew Scull9612d322015-07-06 14:53:25 -0700328 VarList Args; /// subset of Variables, in argument order
329 VarList ImplicitArgs; /// subset of Variables
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700330 // Separate string pools for CfgNode and Variable names, due to a combination
331 // of the uniqueness requirement, and assumptions in lit tests.
332 std::unique_ptr<StringPool> NodeStrings;
333 std::unique_ptr<StringPool> VarStrings;
Jim Stichnotha18cc9c2014-09-30 19:10:22 -0700334 std::unique_ptr<Liveness> Live;
335 std::unique_ptr<TargetLowering> Target;
336 std::unique_ptr<VariablesMetadata> VMetadata;
337 std::unique_ptr<Assembler> TargetAssembler;
Andrew Scull9612d322015-07-06 14:53:25 -0700338 /// Globals required by this CFG. Mostly used for the profiler's globals.
John Portof8b4cc82015-06-09 18:06:19 -0700339 std::unique_ptr<VariableDeclarationList> GlobalInits;
Andrew Scull00741a02015-09-16 19:04:09 -0700340 CfgVector<InstJumpTable *> JumpTables;
Andrew Scull57e12682015-09-16 11:30:19 -0700341 /// CurrentNode is maintained during dumping/emitting just for validating
342 /// Variable::DefNode. Normally, a traversal over CfgNodes maintains this, but
343 /// before global operations like register allocation, resetCurrentNode()
344 /// should be called to avoid spurious validation failures.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700345 const CfgNode *CurrentNode = nullptr;
Manasij Mukherjeeadf352b2016-07-19 13:31:36 -0700346 CfgVector<Loop> LoopInfo;
Jim Stichnoth31c95592014-12-19 12:51:35 -0800347
Jim Stichnotha5fe17a2015-01-26 11:10:03 -0800348public:
John Portoe82b5602016-02-24 15:58:55 -0800349 static void TlsInit() { CfgAllocatorTraits::init(); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700350};
351
Andrew Scull6d47bcd2015-09-17 17:10:05 -0700352template <> Variable *Cfg::makeVariable<Variable>(Type Ty);
353
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700354struct NodeStringPoolTraits {
355 using OwnerType = Cfg;
356 static StringPool *getStrings(const OwnerType *PoolOwner) {
357 return PoolOwner->getNodeStrings();
358 }
359};
360using NodeString = StringID<NodeStringPoolTraits>;
361
362struct VariableStringPoolTraits {
363 using OwnerType = Cfg;
364 static StringPool *getStrings(const OwnerType *PoolOwner) {
365 return PoolOwner->getVarStrings();
366 }
367};
368using VariableString = StringID<VariableStringPoolTraits>;
369
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700370} // end of namespace Ice
371
372#endif // SUBZERO_SRC_ICECFG_H