1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/src/IceCfgNode.h - Control flow graph node -------*- 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 CfgNode class, which represents a single basic block as 12*03ce13f7SAndroid Build Coastguard Worker /// its instruction list, in-edge list, and out-edge list. 13*03ce13f7SAndroid Build Coastguard Worker /// 14*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*03ce13f7SAndroid Build Coastguard Worker 16*03ce13f7SAndroid Build Coastguard Worker #ifndef SUBZERO_SRC_ICECFGNODE_H 17*03ce13f7SAndroid Build Coastguard Worker #define SUBZERO_SRC_ICECFGNODE_H 18*03ce13f7SAndroid Build Coastguard Worker 19*03ce13f7SAndroid Build Coastguard Worker #include "IceDefs.h" 20*03ce13f7SAndroid Build Coastguard Worker #include "IceInst.h" // InstList traits 21*03ce13f7SAndroid Build Coastguard Worker #include "IceStringPool.h" 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker namespace Ice { 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard Worker class CfgNode { 26*03ce13f7SAndroid Build Coastguard Worker CfgNode() = delete; 27*03ce13f7SAndroid Build Coastguard Worker CfgNode(const CfgNode &) = delete; 28*03ce13f7SAndroid Build Coastguard Worker CfgNode &operator=(const CfgNode &) = delete; 29*03ce13f7SAndroid Build Coastguard Worker 30*03ce13f7SAndroid Build Coastguard Worker public: create(Cfg * Func,SizeT Number)31*03ce13f7SAndroid Build Coastguard Worker static CfgNode *create(Cfg *Func, SizeT Number) { 32*03ce13f7SAndroid Build Coastguard Worker return new (Func->allocate<CfgNode>()) CfgNode(Func, Number); 33*03ce13f7SAndroid Build Coastguard Worker } 34*03ce13f7SAndroid Build Coastguard Worker getCfg()35*03ce13f7SAndroid Build Coastguard Worker Cfg *getCfg() const { return Func; } 36*03ce13f7SAndroid Build Coastguard Worker 37*03ce13f7SAndroid Build Coastguard Worker /// Access the label number and name for this node. getIndex()38*03ce13f7SAndroid Build Coastguard Worker SizeT getIndex() const { return Number; } resetIndex(SizeT NewNumber)39*03ce13f7SAndroid Build Coastguard Worker void resetIndex(SizeT NewNumber) { Number = NewNumber; } getName()40*03ce13f7SAndroid Build Coastguard Worker std::string getName() const { 41*03ce13f7SAndroid Build Coastguard Worker if (Name.hasStdString()) 42*03ce13f7SAndroid Build Coastguard Worker return Name.toString(); 43*03ce13f7SAndroid Build Coastguard Worker return "__" + std::to_string(NumberOrig); 44*03ce13f7SAndroid Build Coastguard Worker } setName(const std::string & NewName)45*03ce13f7SAndroid Build Coastguard Worker void setName(const std::string &NewName) { 46*03ce13f7SAndroid Build Coastguard Worker if (NewName.empty()) 47*03ce13f7SAndroid Build Coastguard Worker return; 48*03ce13f7SAndroid Build Coastguard Worker Name = NodeString::createWithString(Func, NewName); 49*03ce13f7SAndroid Build Coastguard Worker } getAsmName()50*03ce13f7SAndroid Build Coastguard Worker std::string getAsmName() const { 51*03ce13f7SAndroid Build Coastguard Worker return ".L" + Func->getFunctionName() + "$" + getName(); 52*03ce13f7SAndroid Build Coastguard Worker } 53*03ce13f7SAndroid Build Coastguard Worker incrementLoopNestDepth()54*03ce13f7SAndroid Build Coastguard Worker void incrementLoopNestDepth() { ++LoopNestDepth; } setLoopNestDepth(SizeT NewDepth)55*03ce13f7SAndroid Build Coastguard Worker void setLoopNestDepth(SizeT NewDepth) { LoopNestDepth = NewDepth; } getLoopNestDepth()56*03ce13f7SAndroid Build Coastguard Worker SizeT getLoopNestDepth() const { return LoopNestDepth; } 57*03ce13f7SAndroid Build Coastguard Worker 58*03ce13f7SAndroid Build Coastguard Worker /// The HasReturn flag indicates that this node contains a return instruction 59*03ce13f7SAndroid Build Coastguard Worker /// and therefore needs an epilog. setHasReturn()60*03ce13f7SAndroid Build Coastguard Worker void setHasReturn() { HasReturn = true; } getHasReturn()61*03ce13f7SAndroid Build Coastguard Worker bool getHasReturn() const { return HasReturn; } 62*03ce13f7SAndroid Build Coastguard Worker setNeedsPlacement(bool Value)63*03ce13f7SAndroid Build Coastguard Worker void setNeedsPlacement(bool Value) { NeedsPlacement = Value; } needsPlacement()64*03ce13f7SAndroid Build Coastguard Worker bool needsPlacement() const { return NeedsPlacement; } 65*03ce13f7SAndroid Build Coastguard Worker setNeedsAlignment()66*03ce13f7SAndroid Build Coastguard Worker void setNeedsAlignment() { NeedsAlignment = true; } needsAlignment()67*03ce13f7SAndroid Build Coastguard Worker bool needsAlignment() const { return NeedsAlignment; } 68*03ce13f7SAndroid Build Coastguard Worker 69*03ce13f7SAndroid Build Coastguard Worker /// \name Access predecessor and successor edge lists. 70*03ce13f7SAndroid Build Coastguard Worker /// @{ getInEdges()71*03ce13f7SAndroid Build Coastguard Worker const NodeList &getInEdges() const { return InEdges; } getOutEdges()72*03ce13f7SAndroid Build Coastguard Worker const NodeList &getOutEdges() const { return OutEdges; } 73*03ce13f7SAndroid Build Coastguard Worker /// @} 74*03ce13f7SAndroid Build Coastguard Worker 75*03ce13f7SAndroid Build Coastguard Worker /// \name Manage the instruction list. 76*03ce13f7SAndroid Build Coastguard Worker /// @{ getInsts()77*03ce13f7SAndroid Build Coastguard Worker InstList &getInsts() { return Insts; } getPhis()78*03ce13f7SAndroid Build Coastguard Worker PhiList &getPhis() { return Phis; } getInsts()79*03ce13f7SAndroid Build Coastguard Worker const InstList &getInsts() const { return Insts; } getPhis()80*03ce13f7SAndroid Build Coastguard Worker const PhiList &getPhis() const { return Phis; } 81*03ce13f7SAndroid Build Coastguard Worker void appendInst(Inst *Instr); 82*03ce13f7SAndroid Build Coastguard Worker void renumberInstructions(); 83*03ce13f7SAndroid Build Coastguard Worker /// Rough and generally conservative estimate of the number of instructions in 84*03ce13f7SAndroid Build Coastguard Worker /// the block. It is updated when an instruction is added, but not when 85*03ce13f7SAndroid Build Coastguard Worker /// deleted. It is recomputed during renumberInstructions(). getInstCountEstimate()86*03ce13f7SAndroid Build Coastguard Worker InstNumberT getInstCountEstimate() const { return InstCountEstimate; } 87*03ce13f7SAndroid Build Coastguard Worker /// @} 88*03ce13f7SAndroid Build Coastguard Worker 89*03ce13f7SAndroid Build Coastguard Worker /// \name Manage predecessors and successors. 90*03ce13f7SAndroid Build Coastguard Worker /// @{ 91*03ce13f7SAndroid Build Coastguard Worker 92*03ce13f7SAndroid Build Coastguard Worker /// Add a predecessor edge to the InEdges list for each of this node's 93*03ce13f7SAndroid Build Coastguard Worker /// successors. 94*03ce13f7SAndroid Build Coastguard Worker void computePredecessors(); 95*03ce13f7SAndroid Build Coastguard Worker void computeSuccessors(); 96*03ce13f7SAndroid Build Coastguard Worker CfgNode *splitIncomingEdge(CfgNode *Pred, SizeT InEdgeIndex); 97*03ce13f7SAndroid Build Coastguard Worker /// @} 98*03ce13f7SAndroid Build Coastguard Worker 99*03ce13f7SAndroid Build Coastguard Worker void enforcePhiConsistency(); 100*03ce13f7SAndroid Build Coastguard Worker void placePhiLoads(); 101*03ce13f7SAndroid Build Coastguard Worker void placePhiStores(); 102*03ce13f7SAndroid Build Coastguard Worker void deletePhis(); 103*03ce13f7SAndroid Build Coastguard Worker void advancedPhiLowering(); 104*03ce13f7SAndroid Build Coastguard Worker void doAddressOpt(); 105*03ce13f7SAndroid Build Coastguard Worker void genCode(); 106*03ce13f7SAndroid Build Coastguard Worker void livenessLightweight(); 107*03ce13f7SAndroid Build Coastguard Worker bool liveness(Liveness *Liveness); 108*03ce13f7SAndroid Build Coastguard Worker void livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum, 109*03ce13f7SAndroid Build Coastguard Worker InstNumberT LastInstNum); 110*03ce13f7SAndroid Build Coastguard Worker void contractIfEmpty(); 111*03ce13f7SAndroid Build Coastguard Worker void doBranchOpt(const CfgNode *NextNode); 112*03ce13f7SAndroid Build Coastguard Worker void emit(Cfg *Func) const; 113*03ce13f7SAndroid Build Coastguard Worker void emitIAS(Cfg *Func) const; 114*03ce13f7SAndroid Build Coastguard Worker void dump(Cfg *Func) const; 115*03ce13f7SAndroid Build Coastguard Worker 116*03ce13f7SAndroid Build Coastguard Worker void profileExecutionCount(VariableDeclaration *Var); 117*03ce13f7SAndroid Build Coastguard Worker addOutEdge(CfgNode * Out)118*03ce13f7SAndroid Build Coastguard Worker void addOutEdge(CfgNode *Out) { OutEdges.push_back(Out); } addInEdge(CfgNode * In)119*03ce13f7SAndroid Build Coastguard Worker void addInEdge(CfgNode *In) { InEdges.push_back(In); } 120*03ce13f7SAndroid Build Coastguard Worker void replaceInEdge(CfgNode *Old, CfgNode *New); removeAllOutEdges()121*03ce13f7SAndroid Build Coastguard Worker void removeAllOutEdges() { OutEdges.clear(); } 122*03ce13f7SAndroid Build Coastguard Worker void removeInEdge(CfgNode *In); 123*03ce13f7SAndroid Build Coastguard Worker hasSingleOutEdge()124*03ce13f7SAndroid Build Coastguard Worker bool hasSingleOutEdge() const { 125*03ce13f7SAndroid Build Coastguard Worker return (getOutEdges().size() == 1 || getOutEdges()[0] == getOutEdges()[1]); 126*03ce13f7SAndroid Build Coastguard Worker } 127*03ce13f7SAndroid Build Coastguard Worker CfgNode *shortCircuit(); 128*03ce13f7SAndroid Build Coastguard Worker getExternalData()129*03ce13f7SAndroid Build Coastguard Worker inline void *getExternalData() const { return externalData; } setExternalData(void * data)130*03ce13f7SAndroid Build Coastguard Worker inline void setExternalData(void *data) { externalData = data; } 131*03ce13f7SAndroid Build Coastguard Worker 132*03ce13f7SAndroid Build Coastguard Worker private: CfgNode(Cfg * Func,SizeT Number)133*03ce13f7SAndroid Build Coastguard Worker CfgNode(Cfg *Func, SizeT Number) 134*03ce13f7SAndroid Build Coastguard Worker : Func(Func), Number(Number), NumberOrig(Number), 135*03ce13f7SAndroid Build Coastguard Worker Name(NodeString::createWithoutString(Func)) {} 136*03ce13f7SAndroid Build Coastguard Worker bool livenessValidateIntervals(Liveness *Liveness) const; 137*03ce13f7SAndroid Build Coastguard Worker Cfg *const Func; 138*03ce13f7SAndroid Build Coastguard Worker SizeT Number; /// invariant: Func->Nodes[Number]==this 139*03ce13f7SAndroid Build Coastguard Worker const SizeT NumberOrig; /// used for name auto-generation 140*03ce13f7SAndroid Build Coastguard Worker NodeString Name; 141*03ce13f7SAndroid Build Coastguard Worker SizeT LoopNestDepth = 0; /// the loop nest depth of this node 142*03ce13f7SAndroid Build Coastguard Worker bool HasReturn = false; /// does this block need an epilog? 143*03ce13f7SAndroid Build Coastguard Worker bool NeedsPlacement = false; 144*03ce13f7SAndroid Build Coastguard Worker bool NeedsAlignment = false; /// is sandboxing required? 145*03ce13f7SAndroid Build Coastguard Worker InstNumberT InstCountEstimate = 0; /// rough instruction count estimate 146*03ce13f7SAndroid Build Coastguard Worker NodeList InEdges; /// in no particular order 147*03ce13f7SAndroid Build Coastguard Worker NodeList OutEdges; /// in no particular order 148*03ce13f7SAndroid Build Coastguard Worker PhiList Phis; /// unordered set of phi instructions 149*03ce13f7SAndroid Build Coastguard Worker InstList Insts; /// ordered list of non-phi instructions 150*03ce13f7SAndroid Build Coastguard Worker 151*03ce13f7SAndroid Build Coastguard Worker /// External data can be set by an optimizer to compute and retain any 152*03ce13f7SAndroid Build Coastguard Worker /// information related to the current node. All the memory used to 153*03ce13f7SAndroid Build Coastguard Worker /// store this information must be managed by the optimizer. 154*03ce13f7SAndroid Build Coastguard Worker void *externalData = nullptr; 155*03ce13f7SAndroid Build Coastguard Worker }; 156*03ce13f7SAndroid Build Coastguard Worker 157*03ce13f7SAndroid Build Coastguard Worker } // end of namespace Ice 158*03ce13f7SAndroid Build Coastguard Worker 159*03ce13f7SAndroid Build Coastguard Worker #endif // SUBZERO_SRC_ICECFGNODE_H 160