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