1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceCfg.h - Control flow graph ----------------*- C++ -*-===// 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // The Subzero Code Generator 4*03ce13f7SAndroid Build Coastguard Worker // 5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*03ce13f7SAndroid Build Coastguard Worker // 8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*03ce13f7SAndroid Build Coastguard Worker /// 10*03ce13f7SAndroid Build Coastguard Worker /// \file 11*03ce13f7SAndroid Build Coastguard Worker /// \brief Declares the Cfg class, which represents the control flow graph and 12*03ce13f7SAndroid Build Coastguard Worker /// the overall per-function compilation context. 13*03ce13f7SAndroid Build Coastguard Worker /// 14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*03ce13f7SAndroid Build Coastguard Worker 16*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICECFG_H 17*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICECFG_H 18*03ce13f7SAndroid Build Coastguard Worker 19*03ce13f7SAndroid Build Coastguard Worker #include "IceAssembler.h" 20*03ce13f7SAndroid Build Coastguard Worker #include "IceClFlags.h" 21*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h" 22*03ce13f7SAndroid Build Coastguard Worker #include "IceGlobalContext.h" 23*03ce13f7SAndroid Build Coastguard Worker #include "IceLoopAnalyzer.h" 24*03ce13f7SAndroid Build Coastguard Worker #include "IceStringPool.h" 25*03ce13f7SAndroid Build Coastguard Worker #include "IceTypes.h" 26*03ce13f7SAndroid Build Coastguard Worker 27*03ce13f7SAndroid Build Coastguard Worker namespace Ice { 28*03ce13f7SAndroid Build Coastguard Worker 29*03ce13f7SAndroid Build Coastguard Worker class Cfg { 30*03ce13f7SAndroid Build Coastguard Worker Cfg() = delete; 31*03ce13f7SAndroid Build Coastguard Worker Cfg(const Cfg &) = delete; 32*03ce13f7SAndroid Build Coastguard Worker Cfg &operator=(const Cfg &) = delete; 33*03ce13f7SAndroid Build Coastguard Worker 34*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<ArenaAllocator> Allocator; 35*03ce13f7SAndroid Build Coastguard Worker 36*03ce13f7SAndroid Build Coastguard Worker public: 37*03ce13f7SAndroid Build Coastguard Worker ~Cfg(); 38*03ce13f7SAndroid Build Coastguard Worker create(GlobalContext * Ctx,uint32_t SequenceNumber)39*03ce13f7SAndroid Build Coastguard Worker static std::unique_ptr<Cfg> create(GlobalContext *Ctx, 40*03ce13f7SAndroid Build Coastguard Worker uint32_t SequenceNumber) { 41*03ce13f7SAndroid Build Coastguard Worker return std::unique_ptr<Cfg>(new Cfg(Ctx, SequenceNumber)); 42*03ce13f7SAndroid Build Coastguard Worker } 43*03ce13f7SAndroid Build Coastguard Worker getContext()44*03ce13f7SAndroid Build Coastguard Worker GlobalContext *getContext() const { return Ctx; } getSequenceNumber()45*03ce13f7SAndroid Build Coastguard Worker uint32_t getSequenceNumber() const { return SequenceNumber; } getOptLevel()46*03ce13f7SAndroid Build Coastguard Worker OptLevel getOptLevel() const { return OptimizationLevel; } 47*03ce13f7SAndroid Build Coastguard Worker defaultVerboseMask()48*03ce13f7SAndroid Build Coastguard Worker static constexpr VerboseMask defaultVerboseMask() { 49*03ce13f7SAndroid Build Coastguard Worker return (IceV_NO_PER_PASS_DUMP_BEYOND << 1) - 1; 50*03ce13f7SAndroid Build Coastguard Worker } 51*03ce13f7SAndroid Build Coastguard Worker /// Returns true if any of the specified options in the verbose mask are set. 52*03ce13f7SAndroid Build Coastguard Worker /// If the argument is omitted, it checks if any verbose options at all are 53*03ce13f7SAndroid Build Coastguard Worker /// set. 54*03ce13f7SAndroid Build Coastguard Worker bool isVerbose(VerboseMask Mask = defaultVerboseMask()) const { 55*03ce13f7SAndroid Build Coastguard Worker return VMask & Mask; 56*03ce13f7SAndroid Build Coastguard Worker } setVerbose(VerboseMask Mask)57*03ce13f7SAndroid Build Coastguard Worker void setVerbose(VerboseMask Mask) { VMask = Mask; } 58*03ce13f7SAndroid Build Coastguard Worker 59*03ce13f7SAndroid Build Coastguard Worker /// \name Manage the name and return type of the function being translated. 60*03ce13f7SAndroid Build Coastguard Worker /// @{ setFunctionName(GlobalString Name)61*03ce13f7SAndroid Build Coastguard Worker void setFunctionName(GlobalString Name) { FunctionName = Name; } getFunctionName()62*03ce13f7SAndroid Build Coastguard Worker GlobalString getFunctionName() const { return FunctionName; } 63*03ce13f7SAndroid Build Coastguard Worker std::string getFunctionNameAndSize() const; setReturnType(Type Ty)64*03ce13f7SAndroid Build Coastguard Worker void setReturnType(Type Ty) { ReturnType = Ty; } getReturnType()65*03ce13f7SAndroid Build Coastguard Worker Type getReturnType() const { return ReturnType; } 66*03ce13f7SAndroid Build Coastguard Worker /// @} 67*03ce13f7SAndroid Build Coastguard Worker 68*03ce13f7SAndroid Build Coastguard Worker /// \name Manage the "internal" attribute of the function. 69*03ce13f7SAndroid Build Coastguard Worker /// @{ setInternal(bool Internal)70*03ce13f7SAndroid Build Coastguard Worker void setInternal(bool Internal) { IsInternalLinkage = Internal; } getInternal()71*03ce13f7SAndroid Build Coastguard Worker bool getInternal() const { return IsInternalLinkage; } 72*03ce13f7SAndroid Build Coastguard Worker /// @} 73*03ce13f7SAndroid Build Coastguard Worker 74*03ce13f7SAndroid Build Coastguard Worker /// \name Manage errors. 75*03ce13f7SAndroid Build Coastguard Worker /// @{ 76*03ce13f7SAndroid Build Coastguard Worker 77*03ce13f7SAndroid Build Coastguard Worker /// Translation error flagging. If support for some construct is known to be 78*03ce13f7SAndroid Build Coastguard Worker /// missing, instead of an assertion failure, setError() should be called and 79*03ce13f7SAndroid Build Coastguard Worker /// the error should be propagated back up. This way, we can gracefully fail 80*03ce13f7SAndroid Build Coastguard Worker /// to translate and let a fallback translator handle the function. 81*03ce13f7SAndroid Build Coastguard Worker void setError(const std::string &Message); hasError()82*03ce13f7SAndroid Build Coastguard Worker bool hasError() const { return HasError; } getError()83*03ce13f7SAndroid Build Coastguard Worker std::string getError() const { return ErrorMessage; } 84*03ce13f7SAndroid Build Coastguard Worker /// @} 85*03ce13f7SAndroid Build Coastguard Worker 86*03ce13f7SAndroid Build Coastguard Worker /// \name Manage nodes (a.k.a. basic blocks, CfgNodes). 87*03ce13f7SAndroid Build Coastguard Worker /// @{ setEntryNode(CfgNode * EntryNode)88*03ce13f7SAndroid Build Coastguard Worker void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; } getEntryNode()89*03ce13f7SAndroid Build Coastguard Worker CfgNode *getEntryNode() const { return Entry; } 90*03ce13f7SAndroid Build Coastguard Worker /// Create a node and append it to the end of the linearized list. The loop 91*03ce13f7SAndroid Build Coastguard Worker /// nest depth of the new node may not be valid if it is created after 92*03ce13f7SAndroid Build Coastguard Worker /// computeLoopNestDepth. 93*03ce13f7SAndroid Build Coastguard Worker CfgNode *makeNode(); getNumNodes()94*03ce13f7SAndroid Build Coastguard Worker SizeT getNumNodes() const { return Nodes.size(); } getNodes()95*03ce13f7SAndroid Build Coastguard Worker const NodeList &getNodes() const { return Nodes; } 96*03ce13f7SAndroid Build Coastguard Worker /// Swap nodes of Cfg with given list of nodes. The number of nodes must 97*03ce13f7SAndroid Build Coastguard Worker /// remain unchanged. 98*03ce13f7SAndroid Build Coastguard Worker void swapNodes(NodeList &NewNodes); 99*03ce13f7SAndroid Build Coastguard Worker /// @} 100*03ce13f7SAndroid Build Coastguard Worker 101*03ce13f7SAndroid Build Coastguard Worker /// String pool for CfgNode::Name values. getNodeStrings()102*03ce13f7SAndroid Build Coastguard Worker StringPool *getNodeStrings() const { return NodeStrings.get(); } 103*03ce13f7SAndroid Build Coastguard Worker /// String pool for Variable::Name values. getVarStrings()104*03ce13f7SAndroid Build Coastguard Worker StringPool *getVarStrings() const { return VarStrings.get(); } 105*03ce13f7SAndroid Build Coastguard Worker 106*03ce13f7SAndroid Build Coastguard Worker /// \name Manage instruction numbering. 107*03ce13f7SAndroid Build Coastguard Worker /// @{ newInstNumber()108*03ce13f7SAndroid Build Coastguard Worker InstNumberT newInstNumber() { return NextInstNumber++; } getNextInstNumber()109*03ce13f7SAndroid Build Coastguard Worker InstNumberT getNextInstNumber() const { return NextInstNumber; } 110*03ce13f7SAndroid Build Coastguard Worker /// @} 111*03ce13f7SAndroid Build Coastguard Worker 112*03ce13f7SAndroid Build Coastguard Worker /// \name Manage Variables. 113*03ce13f7SAndroid Build Coastguard Worker /// @{ 114*03ce13f7SAndroid Build Coastguard Worker 115*03ce13f7SAndroid Build Coastguard Worker /// Create a new Variable with a particular type and an optional name. The 116*03ce13f7SAndroid Build Coastguard Worker /// Node argument is the node where the variable is defined. 117*03ce13f7SAndroid Build Coastguard Worker // TODO(jpp): untemplate this with separate methods: makeVariable and 118*03ce13f7SAndroid Build Coastguard Worker // makeStackVariable. makeVariable(Type Ty)119*03ce13f7SAndroid Build Coastguard Worker template <typename T = Variable> T *makeVariable(Type Ty) { 120*03ce13f7SAndroid Build Coastguard Worker SizeT Index = Variables.size(); 121*03ce13f7SAndroid Build Coastguard Worker auto *Var = T::create(this, Ty, Index); 122*03ce13f7SAndroid Build Coastguard Worker Variables.push_back(Var); 123*03ce13f7SAndroid Build Coastguard Worker return Var; 124*03ce13f7SAndroid Build Coastguard Worker } getNumVariables()125*03ce13f7SAndroid Build Coastguard Worker SizeT getNumVariables() const { return Variables.size(); } getVariables()126*03ce13f7SAndroid Build Coastguard Worker const VarList &getVariables() const { return Variables; } 127*03ce13f7SAndroid Build Coastguard Worker /// @} 128*03ce13f7SAndroid Build Coastguard Worker 129*03ce13f7SAndroid Build Coastguard Worker /// \name Manage arguments to the function. 130*03ce13f7SAndroid Build Coastguard Worker /// @{ 131*03ce13f7SAndroid Build Coastguard Worker void addArg(Variable *Arg); getArgs()132*03ce13f7SAndroid Build Coastguard Worker const VarList &getArgs() const { return Args; } getArgs()133*03ce13f7SAndroid Build Coastguard Worker VarList &getArgs() { return Args; } 134*03ce13f7SAndroid Build Coastguard Worker void addImplicitArg(Variable *Arg); getImplicitArgs()135*03ce13f7SAndroid Build Coastguard Worker const VarList &getImplicitArgs() const { return ImplicitArgs; } 136*03ce13f7SAndroid Build Coastguard Worker /// @} 137*03ce13f7SAndroid Build Coastguard Worker 138*03ce13f7SAndroid Build Coastguard Worker /// \name Manage the jump tables. 139*03ce13f7SAndroid Build Coastguard Worker /// @{ addJumpTable(InstJumpTable * JumpTable)140*03ce13f7SAndroid Build Coastguard Worker void addJumpTable(InstJumpTable *JumpTable) { 141*03ce13f7SAndroid Build Coastguard Worker JumpTables.emplace_back(JumpTable); 142*03ce13f7SAndroid Build Coastguard Worker } 143*03ce13f7SAndroid Build Coastguard Worker /// @} 144*03ce13f7SAndroid Build Coastguard Worker 145*03ce13f7SAndroid Build Coastguard Worker /// \name Manage the Globals used by this function. 146*03ce13f7SAndroid Build Coastguard Worker /// @{ getGlobalInits()147*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<VariableDeclarationList> getGlobalInits() { 148*03ce13f7SAndroid Build Coastguard Worker return std::move(GlobalInits); 149*03ce13f7SAndroid Build Coastguard Worker } addGlobal(VariableDeclaration * Global)150*03ce13f7SAndroid Build Coastguard Worker void addGlobal(VariableDeclaration *Global) { 151*03ce13f7SAndroid Build Coastguard Worker if (GlobalInits == nullptr) { 152*03ce13f7SAndroid Build Coastguard Worker GlobalInits.reset(new VariableDeclarationList); 153*03ce13f7SAndroid Build Coastguard Worker } 154*03ce13f7SAndroid Build Coastguard Worker GlobalInits->push_back(Global); 155*03ce13f7SAndroid Build Coastguard Worker } getGlobalPool()156*03ce13f7SAndroid Build Coastguard Worker VariableDeclarationList *getGlobalPool() { 157*03ce13f7SAndroid Build Coastguard Worker if (GlobalInits == nullptr) { 158*03ce13f7SAndroid Build Coastguard Worker GlobalInits.reset(new VariableDeclarationList); 159*03ce13f7SAndroid Build Coastguard Worker } 160*03ce13f7SAndroid Build Coastguard Worker return GlobalInits.get(); 161*03ce13f7SAndroid Build Coastguard Worker } 162*03ce13f7SAndroid Build Coastguard Worker /// @} 163*03ce13f7SAndroid Build Coastguard Worker 164*03ce13f7SAndroid Build Coastguard Worker /// \name Miscellaneous accessors. 165*03ce13f7SAndroid Build Coastguard Worker /// @{ getTarget()166*03ce13f7SAndroid Build Coastguard Worker TargetLowering *getTarget() const { return Target.get(); } getVMetadata()167*03ce13f7SAndroid Build Coastguard Worker VariablesMetadata *getVMetadata() const { return VMetadata.get(); } getLiveness()168*03ce13f7SAndroid Build Coastguard Worker Liveness *getLiveness() const { return Live.get(); } getAssembler()169*03ce13f7SAndroid Build Coastguard Worker template <typename T = Assembler> T *getAssembler() const { 170*03ce13f7SAndroid Build Coastguard Worker return llvm::dyn_cast<T>(TargetAssembler.get()); 171*03ce13f7SAndroid Build Coastguard Worker } releaseAssembler()172*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<Assembler> releaseAssembler() { 173*03ce13f7SAndroid Build Coastguard Worker return std::move(TargetAssembler); 174*03ce13f7SAndroid Build Coastguard Worker } 175*03ce13f7SAndroid Build Coastguard Worker bool hasComputedFrame() const; getFocusedTiming()176*03ce13f7SAndroid Build Coastguard Worker bool getFocusedTiming() const { return FocusedTiming; } setFocusedTiming()177*03ce13f7SAndroid Build Coastguard Worker void setFocusedTiming() { FocusedTiming = true; } 178*03ce13f7SAndroid Build Coastguard Worker /// @} 179*03ce13f7SAndroid Build Coastguard Worker 180*03ce13f7SAndroid Build Coastguard Worker /// Passes over the CFG. 181*03ce13f7SAndroid Build Coastguard Worker void translate(); 182*03ce13f7SAndroid Build Coastguard Worker /// After the CFG is fully constructed, iterate over the nodes and compute the 183*03ce13f7SAndroid Build Coastguard Worker /// predecessor and successor edges, in the form of CfgNode::InEdges[] and 184*03ce13f7SAndroid Build Coastguard Worker /// CfgNode::OutEdges[]. 185*03ce13f7SAndroid Build Coastguard Worker void computeInOutEdges(); 186*03ce13f7SAndroid Build Coastguard Worker /// Renumber the non-deleted instructions in the Cfg. This needs to be done 187*03ce13f7SAndroid Build Coastguard Worker /// in preparation for live range analysis. The instruction numbers in a 188*03ce13f7SAndroid Build Coastguard Worker /// block must be monotonically increasing. The range of instruction numbers 189*03ce13f7SAndroid Build Coastguard Worker /// in a block, from lowest to highest, must not overlap with the range of any 190*03ce13f7SAndroid Build Coastguard Worker /// other block. 191*03ce13f7SAndroid Build Coastguard Worker /// 192*03ce13f7SAndroid Build Coastguard Worker /// Also, if the configuration specifies to do so, remove/unlink all deleted 193*03ce13f7SAndroid Build Coastguard Worker /// instructions from the Cfg, to speed up later passes over the instructions. 194*03ce13f7SAndroid Build Coastguard Worker void renumberInstructions(); 195*03ce13f7SAndroid Build Coastguard Worker void placePhiLoads(); 196*03ce13f7SAndroid Build Coastguard Worker void placePhiStores(); 197*03ce13f7SAndroid Build Coastguard Worker void deletePhis(); 198*03ce13f7SAndroid Build Coastguard Worker void advancedPhiLowering(); 199*03ce13f7SAndroid Build Coastguard Worker void reorderNodes(); 200*03ce13f7SAndroid Build Coastguard Worker void localCSE(bool AssumeSSA); 201*03ce13f7SAndroid Build Coastguard Worker void floatConstantCSE(); 202*03ce13f7SAndroid Build Coastguard Worker void shortCircuitJumps(); 203*03ce13f7SAndroid Build Coastguard Worker void loopInvariantCodeMotion(); 204*03ce13f7SAndroid Build Coastguard Worker 205*03ce13f7SAndroid Build Coastguard Worker /// Scan allocas to determine whether we need to use a frame pointer. 206*03ce13f7SAndroid Build Coastguard Worker /// If SortAndCombine == true, merge all the fixed-size allocas in the 207*03ce13f7SAndroid Build Coastguard Worker /// entry block and emit stack or frame pointer-relative addressing. 208*03ce13f7SAndroid Build Coastguard Worker void processAllocas(bool SortAndCombine); 209*03ce13f7SAndroid Build Coastguard Worker void doAddressOpt(); 210*03ce13f7SAndroid Build Coastguard Worker /// Find clusters of insertelement/extractelement instructions that can be 211*03ce13f7SAndroid Build Coastguard Worker /// replaced by a shufflevector instruction. 212*03ce13f7SAndroid Build Coastguard Worker void materializeVectorShuffles(); 213*03ce13f7SAndroid Build Coastguard Worker void doArgLowering(); 214*03ce13f7SAndroid Build Coastguard Worker void genCode(); 215*03ce13f7SAndroid Build Coastguard Worker void genFrame(); 216*03ce13f7SAndroid Build Coastguard Worker void generateLoopInfo(); 217*03ce13f7SAndroid Build Coastguard Worker void livenessLightweight(); 218*03ce13f7SAndroid Build Coastguard Worker void liveness(LivenessMode Mode); 219*03ce13f7SAndroid Build Coastguard Worker bool validateLiveness() const; 220*03ce13f7SAndroid Build Coastguard Worker void contractEmptyNodes(); 221*03ce13f7SAndroid Build Coastguard Worker void doBranchOpt(); 222*03ce13f7SAndroid Build Coastguard Worker 223*03ce13f7SAndroid Build Coastguard Worker /// \name Manage the CurrentNode field. 224*03ce13f7SAndroid Build Coastguard Worker /// CurrentNode is used for validating the Variable::DefNode field during 225*03ce13f7SAndroid Build Coastguard Worker /// dumping/emitting. 226*03ce13f7SAndroid Build Coastguard Worker /// @{ setCurrentNode(const CfgNode * Node)227*03ce13f7SAndroid Build Coastguard Worker void setCurrentNode(const CfgNode *Node) { CurrentNode = Node; } resetCurrentNode()228*03ce13f7SAndroid Build Coastguard Worker void resetCurrentNode() { setCurrentNode(nullptr); } getCurrentNode()229*03ce13f7SAndroid Build Coastguard Worker const CfgNode *getCurrentNode() const { return CurrentNode; } 230*03ce13f7SAndroid Build Coastguard Worker /// @} 231*03ce13f7SAndroid Build Coastguard Worker 232*03ce13f7SAndroid Build Coastguard Worker /// Get the total amount of memory held by the per-Cfg allocator. 233*03ce13f7SAndroid Build Coastguard Worker size_t getTotalMemoryMB() const; 234*03ce13f7SAndroid Build Coastguard Worker 235*03ce13f7SAndroid Build Coastguard Worker /// Get the current memory usage due to liveness data structures. 236*03ce13f7SAndroid Build Coastguard Worker size_t getLivenessMemoryMB() const; 237*03ce13f7SAndroid Build Coastguard Worker 238*03ce13f7SAndroid Build Coastguard Worker void emit(); 239*03ce13f7SAndroid Build Coastguard Worker void emitIAS(); 240*03ce13f7SAndroid Build Coastguard Worker static void emitTextHeader(GlobalString Name, GlobalContext *Ctx, 241*03ce13f7SAndroid Build Coastguard Worker const Assembler *Asm); 242*03ce13f7SAndroid Build Coastguard Worker void dump(const char *Message = ""); 243*03ce13f7SAndroid Build Coastguard Worker 244*03ce13f7SAndroid Build Coastguard Worker /// Allocate data of type T using the per-Cfg allocator. allocate()245*03ce13f7SAndroid Build Coastguard Worker template <typename T> T *allocate() { return Allocator->Allocate<T>(); } 246*03ce13f7SAndroid Build Coastguard Worker 247*03ce13f7SAndroid Build Coastguard Worker /// Allocate an array of data of type T using the per-Cfg allocator. allocateArrayOf(size_t NumElems)248*03ce13f7SAndroid Build Coastguard Worker template <typename T> T *allocateArrayOf(size_t NumElems) { 249*03ce13f7SAndroid Build Coastguard Worker return Allocator->Allocate<T>(NumElems); 250*03ce13f7SAndroid Build Coastguard Worker } 251*03ce13f7SAndroid Build Coastguard Worker 252*03ce13f7SAndroid Build Coastguard Worker /// Deallocate data that was allocated via allocate<T>(). deallocate(T * Object)253*03ce13f7SAndroid Build Coastguard Worker template <typename T> void deallocate(T *Object) { 254*03ce13f7SAndroid Build Coastguard Worker Allocator->Deallocate(Object); 255*03ce13f7SAndroid Build Coastguard Worker } 256*03ce13f7SAndroid Build Coastguard Worker 257*03ce13f7SAndroid Build Coastguard Worker /// Deallocate data that was allocated via allocateArrayOf<T>(). deallocateArrayOf(T * Array)258*03ce13f7SAndroid Build Coastguard Worker template <typename T> void deallocateArrayOf(T *Array) { 259*03ce13f7SAndroid Build Coastguard Worker Allocator->Deallocate(Array); 260*03ce13f7SAndroid Build Coastguard Worker } 261*03ce13f7SAndroid Build Coastguard Worker 262*03ce13f7SAndroid Build Coastguard Worker /// Update Phi labels with InEdges. 263*03ce13f7SAndroid Build Coastguard Worker /// 264*03ce13f7SAndroid Build Coastguard Worker /// The WASM translator cannot always determine the right incoming edge for a 265*03ce13f7SAndroid Build Coastguard Worker /// value due to the CFG being built incrementally. The fixPhiNodes pass fills 266*03ce13f7SAndroid Build Coastguard Worker /// in the correct information once everything is known. 267*03ce13f7SAndroid Build Coastguard Worker void fixPhiNodes(); 268*03ce13f7SAndroid Build Coastguard Worker setStackSizeLimit(uint32_t Limit)269*03ce13f7SAndroid Build Coastguard Worker void setStackSizeLimit(uint32_t Limit) { StackSizeLimit = Limit; } getStackSizeLimit()270*03ce13f7SAndroid Build Coastguard Worker uint32_t getStackSizeLimit() const { return StackSizeLimit; } 271*03ce13f7SAndroid Build Coastguard Worker 272*03ce13f7SAndroid Build Coastguard Worker private: 273*03ce13f7SAndroid Build Coastguard Worker friend class CfgAllocatorTraits; // for Allocator access. 274*03ce13f7SAndroid Build Coastguard Worker 275*03ce13f7SAndroid Build Coastguard Worker Cfg(GlobalContext *Ctx, uint32_t SequenceNumber); 276*03ce13f7SAndroid Build Coastguard Worker 277*03ce13f7SAndroid Build Coastguard Worker void createNodeNameDeclaration(const std::string &NodeAsmName); 278*03ce13f7SAndroid Build Coastguard Worker void 279*03ce13f7SAndroid Build Coastguard Worker createBlockProfilingInfoDeclaration(const std::string &NodeAsmName, 280*03ce13f7SAndroid Build Coastguard Worker VariableDeclaration *NodeNameDeclaration); 281*03ce13f7SAndroid Build Coastguard Worker 282*03ce13f7SAndroid Build Coastguard Worker /// Iterate through the registered jump tables and emit them. 283*03ce13f7SAndroid Build Coastguard Worker void emitJumpTables(); 284*03ce13f7SAndroid Build Coastguard Worker 285*03ce13f7SAndroid Build Coastguard Worker enum AllocaBaseVariableType { 286*03ce13f7SAndroid Build Coastguard Worker BVT_StackPointer, 287*03ce13f7SAndroid Build Coastguard Worker BVT_FramePointer, 288*03ce13f7SAndroid Build Coastguard Worker BVT_UserPointer 289*03ce13f7SAndroid Build Coastguard Worker }; 290*03ce13f7SAndroid Build Coastguard Worker void sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas, 291*03ce13f7SAndroid Build Coastguard Worker uint32_t CombinedAlignment, InstList &Insts, 292*03ce13f7SAndroid Build Coastguard Worker AllocaBaseVariableType BaseVariableType); 293*03ce13f7SAndroid Build Coastguard Worker void findRematerializable(); 294*03ce13f7SAndroid Build Coastguard Worker CfgVector<Inst *> 295*03ce13f7SAndroid Build Coastguard Worker findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body); 296*03ce13f7SAndroid Build Coastguard Worker 297*03ce13f7SAndroid Build Coastguard Worker static ArenaAllocator *createAllocator(); 298*03ce13f7SAndroid Build Coastguard Worker 299*03ce13f7SAndroid Build Coastguard Worker GlobalContext *Ctx; 300*03ce13f7SAndroid Build Coastguard Worker uint32_t SequenceNumber; /// output order for emission 301*03ce13f7SAndroid Build Coastguard Worker OptLevel OptimizationLevel = Opt_m1; 302*03ce13f7SAndroid Build Coastguard Worker VerboseMask VMask; 303*03ce13f7SAndroid Build Coastguard Worker GlobalString FunctionName; 304*03ce13f7SAndroid Build Coastguard Worker Type ReturnType = IceType_void; 305*03ce13f7SAndroid Build Coastguard Worker bool IsInternalLinkage = false; 306*03ce13f7SAndroid Build Coastguard Worker bool HasError = false; 307*03ce13f7SAndroid Build Coastguard Worker bool FocusedTiming = false; 308*03ce13f7SAndroid Build Coastguard Worker std::string ErrorMessage = ""; 309*03ce13f7SAndroid Build Coastguard Worker CfgNode *Entry = nullptr; /// entry basic block 310*03ce13f7SAndroid Build Coastguard Worker NodeList Nodes; /// linearized node list; Entry should be first 311*03ce13f7SAndroid Build Coastguard Worker InstNumberT NextInstNumber; 312*03ce13f7SAndroid Build Coastguard Worker VarList Variables; 313*03ce13f7SAndroid Build Coastguard Worker VarList Args; /// subset of Variables, in argument order 314*03ce13f7SAndroid Build Coastguard Worker VarList ImplicitArgs; /// subset of Variables 315*03ce13f7SAndroid Build Coastguard Worker // Separate string pools for CfgNode and Variable names, due to a combination 316*03ce13f7SAndroid Build Coastguard Worker // of the uniqueness requirement, and assumptions in lit tests. 317*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<StringPool> NodeStrings; 318*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<StringPool> VarStrings; 319*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<Liveness> Live; 320*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<TargetLowering> Target; 321*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<VariablesMetadata> VMetadata; 322*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<Assembler> TargetAssembler; 323*03ce13f7SAndroid Build Coastguard Worker /// Globals required by this CFG. 324*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<VariableDeclarationList> GlobalInits; 325*03ce13f7SAndroid Build Coastguard Worker CfgVector<InstJumpTable *> JumpTables; 326*03ce13f7SAndroid Build Coastguard Worker /// CurrentNode is maintained during dumping/emitting just for validating 327*03ce13f7SAndroid Build Coastguard Worker /// Variable::DefNode. Normally, a traversal over CfgNodes maintains this, but 328*03ce13f7SAndroid Build Coastguard Worker /// before global operations like register allocation, resetCurrentNode() 329*03ce13f7SAndroid Build Coastguard Worker /// should be called to avoid spurious validation failures. 330*03ce13f7SAndroid Build Coastguard Worker const CfgNode *CurrentNode = nullptr; 331*03ce13f7SAndroid Build Coastguard Worker CfgVector<Loop> LoopInfo; 332*03ce13f7SAndroid Build Coastguard Worker uint32_t StackSizeLimit = 1 * 1024 * 1024; // 1 MiB 333*03ce13f7SAndroid Build Coastguard Worker 334*03ce13f7SAndroid Build Coastguard Worker public: TlsInit()335*03ce13f7SAndroid Build Coastguard Worker static void TlsInit() { CfgAllocatorTraits::init(); } 336*03ce13f7SAndroid Build Coastguard Worker }; 337*03ce13f7SAndroid Build Coastguard Worker 338*03ce13f7SAndroid Build Coastguard Worker template <> Variable *Cfg::makeVariable<Variable>(Type Ty); 339*03ce13f7SAndroid Build Coastguard Worker 340*03ce13f7SAndroid Build Coastguard Worker struct NodeStringPoolTraits { 341*03ce13f7SAndroid Build Coastguard Worker using OwnerType = Cfg; getStringsNodeStringPoolTraits342*03ce13f7SAndroid Build Coastguard Worker static StringPool *getStrings(const OwnerType *PoolOwner) { 343*03ce13f7SAndroid Build Coastguard Worker return PoolOwner->getNodeStrings(); 344*03ce13f7SAndroid Build Coastguard Worker } 345*03ce13f7SAndroid Build Coastguard Worker }; 346*03ce13f7SAndroid Build Coastguard Worker using NodeString = StringID<NodeStringPoolTraits>; 347*03ce13f7SAndroid Build Coastguard Worker 348*03ce13f7SAndroid Build Coastguard Worker struct VariableStringPoolTraits { 349*03ce13f7SAndroid Build Coastguard Worker using OwnerType = Cfg; getStringsVariableStringPoolTraits350*03ce13f7SAndroid Build Coastguard Worker static StringPool *getStrings(const OwnerType *PoolOwner) { 351*03ce13f7SAndroid Build Coastguard Worker return PoolOwner->getVarStrings(); 352*03ce13f7SAndroid Build Coastguard Worker } 353*03ce13f7SAndroid Build Coastguard Worker }; 354*03ce13f7SAndroid Build Coastguard Worker using VariableString = StringID<VariableStringPoolTraits>; 355*03ce13f7SAndroid Build Coastguard Worker 356*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice 357*03ce13f7SAndroid Build Coastguard Worker 358*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICECFG_H 359