Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 1 | //===- subzero/src/IceCfgNode.h - Control flow graph node -------*- 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 Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
| 11 | /// This file declares the CfgNode class, which represents a single |
| 12 | /// basic block as its instruction list, in-edge list, and out-edge |
| 13 | /// list. |
| 14 | /// |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 15 | //===----------------------------------------------------------------------===// |
| 16 | |
| 17 | #ifndef SUBZERO_SRC_ICECFGNODE_H |
| 18 | #define SUBZERO_SRC_ICECFGNODE_H |
| 19 | |
| 20 | #include "IceDefs.h" |
Jim Stichnoth | 607e9f0 | 2014-11-06 13:32:05 -0800 | [diff] [blame] | 21 | #include "IceInst.h" // InstList traits |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 22 | |
| 23 | namespace Ice { |
| 24 | |
| 25 | class CfgNode { |
Jim Stichnoth | c6ead20 | 2015-02-24 09:30:30 -0800 | [diff] [blame] | 26 | CfgNode() = delete; |
Jim Stichnoth | 7b451a9 | 2014-10-15 14:39:23 -0700 | [diff] [blame] | 27 | CfgNode(const CfgNode &) = delete; |
| 28 | CfgNode &operator=(const CfgNode &) = delete; |
| 29 | |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 30 | public: |
Jim Stichnoth | 668a7a3 | 2014-12-10 15:32:25 -0800 | [diff] [blame] | 31 | static CfgNode *create(Cfg *Func, SizeT LabelIndex) { |
| 32 | return new (Func->allocate<CfgNode>()) CfgNode(Func, LabelIndex); |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 33 | } |
| 34 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 35 | /// Access the label number and name for this node. |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 36 | SizeT getIndex() const { return Number; } |
Jim Stichnoth | 69d3f9c | 2015-03-23 10:33:38 -0700 | [diff] [blame] | 37 | void resetIndex(SizeT NewNumber) { Number = NewNumber; } |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 38 | IceString getName() const; |
Jim Stichnoth | 668a7a3 | 2014-12-10 15:32:25 -0800 | [diff] [blame] | 39 | void setName(const IceString &NewName) { |
Karl Schimpf | c132b76 | 2014-09-11 09:43:47 -0700 | [diff] [blame] | 40 | // Make sure that the name can only be set once. |
Jim Stichnoth | 9a04c07 | 2014-12-11 15:51:42 -0800 | [diff] [blame] | 41 | assert(NameIndex == Cfg::IdentifierIndexInvalid); |
Jim Stichnoth | 668a7a3 | 2014-12-10 15:32:25 -0800 | [diff] [blame] | 42 | if (!NewName.empty()) |
Jim Stichnoth | 9a04c07 | 2014-12-11 15:51:42 -0800 | [diff] [blame] | 43 | NameIndex = Func->addIdentifierName(NewName); |
Karl Schimpf | c132b76 | 2014-09-11 09:43:47 -0700 | [diff] [blame] | 44 | } |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 45 | IceString getAsmName() const { |
| 46 | return ".L" + Func->getFunctionName() + "$" + getName(); |
| 47 | } |
| 48 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 49 | /// The HasReturn flag indicates that this node contains a return |
| 50 | /// instruction and therefore needs an epilog. |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 51 | void setHasReturn() { HasReturn = true; } |
| 52 | bool getHasReturn() const { return HasReturn; } |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 53 | |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 54 | void setNeedsPlacement(bool Value) { NeedsPlacement = Value; } |
| 55 | bool needsPlacement() const { return NeedsPlacement; } |
| 56 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 57 | /// \name Access predecessor and successor edge lists. |
| 58 | /// @{ |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 59 | const NodeList &getInEdges() const { return InEdges; } |
| 60 | const NodeList &getOutEdges() const { return OutEdges; } |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 61 | /// @} |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 62 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 63 | /// \name Manage the instruction list. |
| 64 | /// @{ |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 65 | InstList &getInsts() { return Insts; } |
Jim Stichnoth | 98712a3 | 2014-10-24 10:59:02 -0700 | [diff] [blame] | 66 | PhiList &getPhis() { return Phis; } |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 67 | void appendInst(Inst *Inst); |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 68 | void renumberInstructions(); |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 69 | /// Rough and generally conservative estimate of the number of |
| 70 | /// instructions in the block. It is updated when an instruction is |
| 71 | /// added, but not when deleted. It is recomputed during |
| 72 | /// renumberInstructions(). |
Jim Stichnoth | 4775255 | 2014-10-13 17:15:08 -0700 | [diff] [blame] | 73 | InstNumberT getInstCountEstimate() const { return InstCountEstimate; } |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 74 | /// @} |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 75 | |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 76 | /// \name Manage predecessors and successors. |
| 77 | /// @{ |
| 78 | |
| 79 | /// Add a predecessor edge to the InEdges list for each of this |
| 80 | /// node's successors. |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 81 | void computePredecessors(); |
Jim Stichnoth | 69d3f9c | 2015-03-23 10:33:38 -0700 | [diff] [blame] | 82 | void computeSuccessors(); |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 83 | CfgNode *splitIncomingEdge(CfgNode *Pred, SizeT InEdgeIndex); |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 84 | /// @} |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 85 | |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 86 | void placePhiLoads(); |
| 87 | void placePhiStores(); |
| 88 | void deletePhis(); |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 89 | void advancedPhiLowering(); |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 90 | void doAddressOpt(); |
Matt Wala | c330274 | 2014-08-15 16:21:56 -0700 | [diff] [blame] | 91 | void doNopInsertion(); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 92 | void genCode(); |
Jim Stichnoth | d97c7df | 2014-06-04 11:57:08 -0700 | [diff] [blame] | 93 | void livenessLightweight(); |
| 94 | bool liveness(Liveness *Liveness); |
Jim Stichnoth | e5b73e6 | 2014-12-15 09:58:51 -0800 | [diff] [blame] | 95 | void livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum, |
| 96 | InstNumberT LastInstNum); |
Jim Stichnoth | 336f6c4 | 2014-10-30 15:01:31 -0700 | [diff] [blame] | 97 | void contractIfEmpty(); |
Jim Stichnoth | ff9c706 | 2014-09-18 04:50:49 -0700 | [diff] [blame] | 98 | void doBranchOpt(const CfgNode *NextNode); |
Jim Stichnoth | 5bc2b1d | 2014-05-22 13:38:48 -0700 | [diff] [blame] | 99 | void emit(Cfg *Func) const; |
Jan Voung | 0faec4c | 2014-11-05 17:29:56 -0800 | [diff] [blame] | 100 | void emitIAS(Cfg *Func) const; |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 101 | void dump(Cfg *Func) const; |
| 102 | |
John Porto | f8b4cc8 | 2015-06-09 18:06:19 -0700 | [diff] [blame] | 103 | void profileExecutionCount(VariableDeclaration *Var); |
| 104 | |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 105 | private: |
Jim Stichnoth | 668a7a3 | 2014-12-10 15:32:25 -0800 | [diff] [blame] | 106 | CfgNode(Cfg *Func, SizeT LabelIndex); |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 107 | Cfg *const Func; |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 108 | SizeT Number; /// label index |
Jim Stichnoth | eafb56c | 2015-06-22 10:35:22 -0700 | [diff] [blame] | 109 | Cfg::IdentifierIndexType NameIndex = |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 110 | Cfg::IdentifierIndexInvalid; /// index into Cfg::NodeNames table |
| 111 | bool HasReturn = false; /// does this block need an epilog? |
Jim Stichnoth | eafb56c | 2015-06-22 10:35:22 -0700 | [diff] [blame] | 112 | bool NeedsPlacement = false; |
Andrew Scull | 9612d32 | 2015-07-06 14:53:25 -0700 | [diff] [blame] | 113 | InstNumberT InstCountEstimate = 0; /// rough instruction count estimate |
| 114 | NodeList InEdges; /// in no particular order |
| 115 | NodeList OutEdges; /// in no particular order |
| 116 | PhiList Phis; /// unordered set of phi instructions |
| 117 | InstList Insts; /// ordered list of non-phi instructions |
Jim Stichnoth | f7c9a14 | 2014-04-29 10:52:43 -0700 | [diff] [blame] | 118 | }; |
| 119 | |
| 120 | } // end of namespace Ice |
| 121 | |
| 122 | #endif // SUBZERO_SRC_ICECFGNODE_H |