xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceCfgNode.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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