blob: b2d2de8b27c4cf3a86a465438224ffacaf68d068 [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- 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 Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares the CfgNode class, which represents a single basic block as
12/// its instruction list, in-edge list, and out-edge list.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
Jim Stichnothf7c9a142014-04-29 10:52:43 -070014//===----------------------------------------------------------------------===//
15
16#ifndef SUBZERO_SRC_ICECFGNODE_H
17#define SUBZERO_SRC_ICECFGNODE_H
18
19#include "IceDefs.h"
Jim Stichnoth607e9f02014-11-06 13:32:05 -080020#include "IceInst.h" // InstList traits
Jim Stichnoth467ffe52016-03-29 15:01:06 -070021#include "IceStringPool.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070022
23namespace Ice {
24
25class CfgNode {
Jim Stichnothc6ead202015-02-24 09:30:30 -080026 CfgNode() = delete;
Jim Stichnoth7b451a92014-10-15 14:39:23 -070027 CfgNode(const CfgNode &) = delete;
28 CfgNode &operator=(const CfgNode &) = delete;
29
Jim Stichnothf7c9a142014-04-29 10:52:43 -070030public:
Jim Stichnoth467ffe52016-03-29 15:01:06 -070031 static CfgNode *create(Cfg *Func, SizeT Number) {
32 return new (Func->allocate<CfgNode>()) CfgNode(Func, Number);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070033 }
34
Jim Stichnoth5bff61c2015-10-28 09:26:00 -070035 Cfg *getCfg() const { return Func; }
36
Andrew Scull9612d322015-07-06 14:53:25 -070037 /// Access the label number and name for this node.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070038 SizeT getIndex() const { return Number; }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -070039 void resetIndex(SizeT NewNumber) { Number = NewNumber; }
Jim Stichnotha91c3412016-04-05 15:31:43 -070040 std::string getName() const {
41 if (Name.hasStdString())
42 return Name.toString();
43 return "__" + std::to_string(NumberOrig);
44 }
Jim Stichnoth467ffe52016-03-29 15:01:06 -070045 void setName(const std::string &NewName) {
46 if (NewName.empty())
47 return;
48 Name = NodeString::createWithString(Func, NewName);
Karl Schimpfc132b762014-09-11 09:43:47 -070049 }
Jim Stichnoth467ffe52016-03-29 15:01:06 -070050 std::string getAsmName() const {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070051 return ".L" + Func->getFunctionName() + "$" + getName();
52 }
53
Andrew Scullaa6c1092015-09-03 17:50:30 -070054 void incrementLoopNestDepth() { ++LoopNestDepth; }
55 void setLoopNestDepth(SizeT NewDepth) { LoopNestDepth = NewDepth; }
56 SizeT getLoopNestDepth() const { return LoopNestDepth; }
57
Andrew Scull57e12682015-09-16 11:30:19 -070058 /// The HasReturn flag indicates that this node contains a return instruction
59 /// and therefore needs an epilog.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070060 void setHasReturn() { HasReturn = true; }
61 bool getHasReturn() const { return HasReturn; }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070062
Jim Stichnoth336f6c42014-10-30 15:01:31 -070063 void setNeedsPlacement(bool Value) { NeedsPlacement = Value; }
64 bool needsPlacement() const { return NeedsPlacement; }
65
Andrew Scull86df4e92015-07-30 13:54:44 -070066 void setNeedsAlignment() { NeedsAlignment = true; }
67 bool needsAlignment() const { return NeedsAlignment; }
68
Andrew Scull9612d322015-07-06 14:53:25 -070069 /// \name Access predecessor and successor edge lists.
70 /// @{
Jim Stichnothf7c9a142014-04-29 10:52:43 -070071 const NodeList &getInEdges() const { return InEdges; }
72 const NodeList &getOutEdges() const { return OutEdges; }
Andrew Scull9612d322015-07-06 14:53:25 -070073 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070074
Andrew Scull9612d322015-07-06 14:53:25 -070075 /// \name Manage the instruction list.
76 /// @{
Jim Stichnothf7c9a142014-04-29 10:52:43 -070077 InstList &getInsts() { return Insts; }
Jim Stichnoth98712a32014-10-24 10:59:02 -070078 PhiList &getPhis() { return Phis; }
Jim Stichnothb9a84722016-08-01 13:18:36 -070079 const InstList &getInsts() const { return Insts; }
80 const PhiList &getPhis() const { return Phis; }
Eric Holk085bdae2016-04-18 15:08:19 -070081 void appendInst(Inst *Instr);
Jim Stichnothd97c7df2014-06-04 11:57:08 -070082 void renumberInstructions();
Andrew Scull57e12682015-09-16 11:30:19 -070083 /// Rough and generally conservative estimate of the number of instructions in
84 /// the block. It is updated when an instruction is added, but not when
85 /// deleted. It is recomputed during renumberInstructions().
Jim Stichnoth47752552014-10-13 17:15:08 -070086 InstNumberT getInstCountEstimate() const { return InstCountEstimate; }
Andrew Scull9612d322015-07-06 14:53:25 -070087 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070088
Andrew Scull9612d322015-07-06 14:53:25 -070089 /// \name Manage predecessors and successors.
90 /// @{
91
Andrew Scull57e12682015-09-16 11:30:19 -070092 /// Add a predecessor edge to the InEdges list for each of this node's
93 /// successors.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070094 void computePredecessors();
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -070095 void computeSuccessors();
Jim Stichnoth336f6c42014-10-30 15:01:31 -070096 CfgNode *splitIncomingEdge(CfgNode *Pred, SizeT InEdgeIndex);
Andrew Scull9612d322015-07-06 14:53:25 -070097 /// @}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070098
David Sehr263ac522016-04-04 10:11:08 -070099 void enforcePhiConsistency();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700100 void placePhiLoads();
101 void placePhiStores();
102 void deletePhis();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700103 void advancedPhiLowering();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700104 void doAddressOpt();
Qining Luaee5fa82015-08-20 14:59:03 -0700105 void doNopInsertion(RandomNumberGenerator &RNG);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700106 void genCode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700107 void livenessLightweight();
108 bool liveness(Liveness *Liveness);
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800109 void livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum,
110 InstNumberT LastInstNum);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700111 void contractIfEmpty();
Jim Stichnothff9c7062014-09-18 04:50:49 -0700112 void doBranchOpt(const CfgNode *NextNode);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700113 void emit(Cfg *Func) const;
Jan Voung0faec4c2014-11-05 17:29:56 -0800114 void emitIAS(Cfg *Func) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700115 void dump(Cfg *Func) const;
116
John Portof8b4cc82015-06-09 18:06:19 -0700117 void profileExecutionCount(VariableDeclaration *Var);
118
Eric Holk16f80612016-04-04 17:07:42 -0700119 void addOutEdge(CfgNode *Out) { OutEdges.push_back(Out); }
120 void addInEdge(CfgNode *In) { InEdges.push_back(In); }
Manasij Mukherjee45f51a22016-06-27 16:12:37 -0700121 void replaceInEdge(CfgNode *Old, CfgNode *New);
122 void removeAllOutEdges() { OutEdges.clear(); }
123 void removeInEdge(CfgNode *In);
Eric Holk16f80612016-04-04 17:07:42 -0700124
125 bool hasSingleOutEdge() const {
126 return (getOutEdges().size() == 1 || getOutEdges()[0] == getOutEdges()[1]);
127 }
Manasij Mukherjee45f51a22016-06-27 16:12:37 -0700128 CfgNode *shortCircuit();
Eric Holk16f80612016-04-04 17:07:42 -0700129
Alexis Hetu932640b2018-06-20 15:35:53 -0400130 inline void* getExternalData() const { return externalData; }
131 inline void setExternalData(void* data) { externalData = data; }
132
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700133private:
Jim Stichnotha91c3412016-04-05 15:31:43 -0700134 CfgNode(Cfg *Func, SizeT Number)
135 : Func(Func), Number(Number), NumberOrig(Number),
136 Name(NodeString::createWithoutString(Func)) {}
Jim Stichnoth318f4cd2015-10-01 21:02:37 -0700137 bool livenessValidateIntervals(Liveness *Liveness) const;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700138 Cfg *const Func;
Jim Stichnotha91c3412016-04-05 15:31:43 -0700139 SizeT Number; /// invariant: Func->Nodes[Number]==this
140 const SizeT NumberOrig; /// used for name auto-generation
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700141 NodeString Name;
142 SizeT LoopNestDepth = 0; /// the loop nest depth of this node
143 bool HasReturn = false; /// does this block need an epilog?
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700144 bool NeedsPlacement = false;
Andrew Scull86df4e92015-07-30 13:54:44 -0700145 bool NeedsAlignment = false; /// is sandboxing required?
Andrew Scull9612d322015-07-06 14:53:25 -0700146 InstNumberT InstCountEstimate = 0; /// rough instruction count estimate
147 NodeList InEdges; /// in no particular order
148 NodeList OutEdges; /// in no particular order
149 PhiList Phis; /// unordered set of phi instructions
150 InstList Insts; /// ordered list of non-phi instructions
Alexis Hetu932640b2018-06-20 15:35:53 -0400151
152 /// External data can be set by an optimizer to compute and retain any
153 /// information related to the current node. All the memory used to
154 /// store this information must be managed by the optimizer.
155 void* externalData = nullptr;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700156};
157
158} // end of namespace Ice
159
160#endif // SUBZERO_SRC_ICECFGNODE_H