blob: a87642d14c78a72370a6cd4393dfd8c3bc3141a0 [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===//
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 Implements the CfgNode class, including the complexities of
Andrew Scull57e12682015-09-16 11:30:19 -070012/// instruction insertion and in-edge calculation.
Andrew Scull9612d322015-07-06 14:53:25 -070013///
Jim Stichnothf7c9a142014-04-29 10:52:43 -070014//===----------------------------------------------------------------------===//
15
John Porto67f8de92015-06-25 10:14:17 -070016#include "IceCfgNode.h"
17
John Portoaff4ccf2015-06-10 16:35:06 -070018#include "IceAssembler.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070019#include "IceCfg.h"
John Portof8b4cc82015-06-09 18:06:19 -070020#include "IceGlobalInits.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070021#include "IceInst.h"
John Portoec3f5652015-08-31 15:07:09 -070022#include "IceInstVarIter.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070023#include "IceLiveness.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070024#include "IceOperand.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070025#include "IceTargetLowering.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070026
27namespace Ice {
28
Jim Stichnoth467ffe52016-03-29 15:01:06 -070029CfgNode::CfgNode(Cfg *Func, SizeT Number) : Func(Func), Number(Number) {
30 if (BuildDefs::dump()) {
31 Name =
32 NodeString::createWithString(Func, "__" + std::to_string(getIndex()));
33 } else {
34 Name = NodeString::createWithoutString(Func);
35 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070036}
37
Andrew Scull57e12682015-09-16 11:30:19 -070038// Adds an instruction to either the Phi list or the regular instruction list.
39// Validates that all Phis are added before all regular instructions.
Jim Stichnoth8cfeb692016-02-05 09:50:02 -080040void CfgNode::appendInst(Inst *Instr) {
Jim Stichnoth47752552014-10-13 17:15:08 -070041 ++InstCountEstimate;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -080042 if (auto *Phi = llvm::dyn_cast<InstPhi>(Instr)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -070043 if (!Insts.empty()) {
44 Func->setError("Phi instruction added to the middle of a block");
45 return;
46 }
47 Phis.push_back(Phi);
48 } else {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -080049 Insts.push_back(Instr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070050 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070051}
52
Jim Stichnoth76719b42016-03-14 08:37:52 -070053namespace {
54template <typename List> void removeDeletedAndRenumber(List *L, Cfg *Func) {
55 const bool DoDelete =
56 BuildDefs::minimal() || !GlobalContext::getFlags().getKeepDeletedInsts();
57 auto I = L->begin(), E = L->end(), Next = I;
58 for (++Next; I != E; I = Next++) {
59 if (DoDelete && I->isDeleted()) {
60 L->erase(I);
61 } else {
62 I->renumber(Func);
63 }
64 }
65}
66} // end of anonymous namespace
67
Jim Stichnothd97c7df2014-06-04 11:57:08 -070068void CfgNode::renumberInstructions() {
Jim Stichnoth47752552014-10-13 17:15:08 -070069 InstNumberT FirstNumber = Func->getNextInstNumber();
Jim Stichnoth76719b42016-03-14 08:37:52 -070070 removeDeletedAndRenumber(&Phis, Func);
71 removeDeletedAndRenumber(&Insts, Func);
Jim Stichnoth47752552014-10-13 17:15:08 -070072 InstCountEstimate = Func->getNextInstNumber() - FirstNumber;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070073}
74
Andrew Scull57e12682015-09-16 11:30:19 -070075// When a node is created, the OutEdges are immediately known, but the InEdges
76// have to be built up incrementally. After the CFG has been constructed, the
77// computePredecessors() pass finalizes it by creating the InEdges list.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070078void CfgNode::computePredecessors() {
Jim Stichnothf44f3712014-10-01 14:05:51 -070079 for (CfgNode *Succ : OutEdges)
80 Succ->InEdges.push_back(this);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070081}
82
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -070083void CfgNode::computeSuccessors() {
84 OutEdges = Insts.rbegin()->getTerminatorEdges();
85}
86
Andrew Scull57e12682015-09-16 11:30:19 -070087// Validate each Phi instruction in the node with respect to control flow. For
88// every phi argument, its label must appear in the predecessor list. For each
89// predecessor, there must be a phi argument with that label. We don't check
Jim Stichnoth1aca2302015-09-16 11:25:22 -070090// that phi arguments with the same label have the same value.
91void CfgNode::validatePhis() {
92 for (Inst &Instr : Phis) {
93 auto *Phi = llvm::cast<InstPhi>(&Instr);
Andrew Scull57e12682015-09-16 11:30:19 -070094 // We do a simple O(N^2) algorithm to check for consistency. Even so, it
95 // shows up as only about 0.2% of the total translation time. But if
96 // necessary, we could improve the complexity by using a hash table to
97 // count how many times each node is referenced in the Phi instruction, and
98 // how many times each node is referenced in the incoming edge list, and
99 // compare the two for equality.
Jim Stichnoth1aca2302015-09-16 11:25:22 -0700100 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) {
101 CfgNode *Label = Phi->getLabel(i);
102 bool Found = false;
103 for (CfgNode *InNode : getInEdges()) {
104 if (InNode == Label) {
105 Found = true;
106 break;
107 }
108 }
109 if (!Found)
110 llvm::report_fatal_error("Phi error: label for bad incoming edge");
111 }
112 for (CfgNode *InNode : getInEdges()) {
113 bool Found = false;
114 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) {
115 CfgNode *Label = Phi->getLabel(i);
116 if (InNode == Label) {
117 Found = true;
118 break;
119 }
120 }
121 if (!Found)
122 llvm::report_fatal_error("Phi error: missing label for incoming edge");
123 }
124 }
125}
126
Andrew Scull57e12682015-09-16 11:30:19 -0700127// This does part 1 of Phi lowering, by creating a new dest variable for each
128// Phi instruction, replacing the Phi instruction's dest with that variable,
129// and adding an explicit assignment of the old dest to the new dest. For
130// example,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700131// a=phi(...)
132// changes to
133// "a_phi=phi(...); a=a_phi".
134//
Andrew Scull57e12682015-09-16 11:30:19 -0700135// This is in preparation for part 2 which deletes the Phi instructions and
136// appends assignment instructions to predecessor blocks. Note that this
137// transformation preserves SSA form.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700138void CfgNode::placePhiLoads() {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800139 for (Inst &I : Phis) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700140 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Jim Stichnoth1502e592014-12-11 09:22:45 -0800141 Insts.insert(Insts.begin(), Phi->lower(Func));
142 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700143}
144
Andrew Scull57e12682015-09-16 11:30:19 -0700145// This does part 2 of Phi lowering. For each Phi instruction at each out-edge,
146// create a corresponding assignment instruction, and add all the assignments
147// near the end of this block. They need to be added before any branch
148// instruction, and also if the block ends with a compare instruction followed
149// by a branch instruction that we may want to fuse, it's better to insert the
150// new assignments before the compare instruction. The
151// tryOptimizedCmpxchgCmpBr() method assumes this ordering of instructions.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700152//
Andrew Scull57e12682015-09-16 11:30:19 -0700153// Note that this transformation takes the Phi dest variables out of SSA form,
154// as there may be assignments to the dest variable in multiple blocks.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700155void CfgNode::placePhiStores() {
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700156 // Find the insertion point.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700157 InstList::iterator InsertionPoint = Insts.end();
Andrew Scull57e12682015-09-16 11:30:19 -0700158 // Every block must end in a terminator instruction, and therefore must have
159 // at least one instruction, so it's valid to decrement InsertionPoint (but
160 // assert just in case).
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700161 assert(InsertionPoint != Insts.begin());
162 --InsertionPoint;
Andrew Scull57e12682015-09-16 11:30:19 -0700163 // Confirm that InsertionPoint is a terminator instruction. Calling
164 // getTerminatorEdges() on a non-terminator instruction will cause an
165 // llvm_unreachable().
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800166 (void)InsertionPoint->getTerminatorEdges();
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700167 // SafeInsertionPoint is always immediately before the terminator
Andrew Scull57e12682015-09-16 11:30:19 -0700168 // instruction. If the block ends in a compare and conditional branch, it's
169 // better to place the Phi store before the compare so as not to interfere
170 // with compare/branch fusing. However, if the compare instruction's dest
171 // operand is the same as the new assignment statement's source operand, this
172 // can't be done due to data dependences, so we need to fall back to the
173 // SafeInsertionPoint. To illustrate:
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700174 // ; <label>:95
175 // %97 = load i8* %96, align 1
176 // %98 = icmp ne i8 %97, 0
177 // br i1 %98, label %99, label %2132
178 // ; <label>:99
179 // %100 = phi i8 [ %97, %95 ], [ %110, %108 ]
180 // %101 = phi i1 [ %98, %95 ], [ %111, %108 ]
181 // would be Phi-lowered as:
182 // ; <label>:95
183 // %97 = load i8* %96, align 1
184 // %100_phi = %97 ; can be at InsertionPoint
185 // %98 = icmp ne i8 %97, 0
186 // %101_phi = %98 ; must be at SafeInsertionPoint
187 // br i1 %98, label %99, label %2132
188 // ; <label>:99
189 // %100 = %100_phi
190 // %101 = %101_phi
191 //
Andrew Scull57e12682015-09-16 11:30:19 -0700192 // TODO(stichnot): It may be possible to bypass this whole SafeInsertionPoint
193 // mechanism. If a source basic block ends in a conditional branch:
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700194 // labelSource:
195 // ...
196 // br i1 %foo, label %labelTrue, label %labelFalse
197 // and a branch target has a Phi involving the branch operand:
198 // labelTrue:
199 // %bar = phi i1 [ %foo, %labelSource ], ...
200 // then we actually know the constant i1 value of the Phi operand:
201 // labelTrue:
202 // %bar = phi i1 [ true, %labelSource ], ...
Andrew Scull57e12682015-09-16 11:30:19 -0700203 // It seems that this optimization should be done by clang or opt, but we
204 // could also do it here.
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700205 InstList::iterator SafeInsertionPoint = InsertionPoint;
Andrew Scull57e12682015-09-16 11:30:19 -0700206 // Keep track of the dest variable of a compare instruction, so that we
207 // insert the new instruction at the SafeInsertionPoint if the compare's dest
208 // matches the Phi-lowered assignment's source.
Jim Stichnothae953202014-12-20 06:17:49 -0800209 Variable *CmpInstDest = nullptr;
Andrew Scull57e12682015-09-16 11:30:19 -0700210 // If the current insertion point is at a conditional branch instruction, and
211 // the previous instruction is a compare instruction, then we move the
212 // insertion point before the compare instruction so as not to interfere with
213 // compare/branch fusing.
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800214 if (auto *Branch = llvm::dyn_cast<InstBr>(InsertionPoint)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700215 if (!Branch->isUnconditional()) {
216 if (InsertionPoint != Insts.begin()) {
217 --InsertionPoint;
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800218 if (llvm::isa<InstIcmp>(InsertionPoint) ||
219 llvm::isa<InstFcmp>(InsertionPoint)) {
220 CmpInstDest = InsertionPoint->getDest();
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700221 } else {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700222 ++InsertionPoint;
223 }
224 }
225 }
226 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700227
228 // Consider every out-edge.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700229 for (CfgNode *Succ : OutEdges) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700230 // Consider every Phi instruction at the out-edge.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800231 for (Inst &I : Succ->Phis) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700232 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Jim Stichnoth1502e592014-12-11 09:22:45 -0800233 Operand *Operand = Phi->getOperandForTarget(this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700234 assert(Operand);
Jim Stichnoth29841e82014-12-23 12:26:24 -0800235 Variable *Dest = I.getDest();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700236 assert(Dest);
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800237 auto *NewInst = InstAssign::create(Func, Dest, Operand);
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700238 if (CmpInstDest == Operand)
239 Insts.insert(SafeInsertionPoint, NewInst);
240 else
241 Insts.insert(InsertionPoint, NewInst);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700242 }
243 }
244}
245
246// Deletes the phi instructions after the loads and stores are placed.
247void CfgNode::deletePhis() {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800248 for (Inst &I : Phis)
249 I.setDeleted();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700250}
251
Andrew Scull57e12682015-09-16 11:30:19 -0700252// Splits the edge from Pred to this node by creating a new node and hooking up
253// the in and out edges appropriately. (The EdgeIndex parameter is only used to
254// make the new node's name unique when there are multiple edges between the
255// same pair of nodes.) The new node's instruction list is initialized to the
256// empty list, with no terminator instruction. There must not be multiple edges
257// from Pred to this node so all Inst::getTerminatorEdges implementations must
Andrew Scull87f80c12015-07-20 10:19:16 -0700258// not contain duplicates.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700259CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) {
Jim Stichnoth668a7a32014-12-10 15:32:25 -0800260 CfgNode *NewNode = Func->makeNode();
Andrew Scullaa6c1092015-09-03 17:50:30 -0700261 // Depth is the minimum as it works if both are the same, but if one is
262 // outside the loop and the other is inside, the new node should be placed
263 // outside and not be executed multiple times within the loop.
264 NewNode->setLoopNestDepth(
265 std::min(getLoopNestDepth(), Pred->getLoopNestDepth()));
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700266 if (BuildDefs::dump())
Jim Stichnoth668a7a32014-12-10 15:32:25 -0800267 NewNode->setName("split_" + Pred->getName() + "_" + getName() + "_" +
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700268 std::to_string(EdgeIndex));
Andrew Scull57e12682015-09-16 11:30:19 -0700269 // The new node is added to the end of the node list, and will later need to
270 // be sorted into a reasonable topological order.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700271 NewNode->setNeedsPlacement(true);
272 // Repoint Pred's out-edge.
273 bool Found = false;
Andrew Scull87f80c12015-07-20 10:19:16 -0700274 for (CfgNode *&I : Pred->OutEdges) {
275 if (I == this) {
276 I = NewNode;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700277 NewNode->InEdges.push_back(Pred);
278 Found = true;
Andrew Scull87f80c12015-07-20 10:19:16 -0700279 break;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700280 }
281 }
282 assert(Found);
Jim Stichnotha8d47132015-09-08 14:43:38 -0700283 (void)Found;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700284 // Repoint this node's in-edge.
285 Found = false;
Andrew Scull87f80c12015-07-20 10:19:16 -0700286 for (CfgNode *&I : InEdges) {
287 if (I == Pred) {
288 I = NewNode;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700289 NewNode->OutEdges.push_back(this);
290 Found = true;
Andrew Scull87f80c12015-07-20 10:19:16 -0700291 break;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700292 }
293 }
294 assert(Found);
Jim Stichnotha8d47132015-09-08 14:43:38 -0700295 (void)Found;
Andrew Scull87f80c12015-07-20 10:19:16 -0700296 // Repoint all suitable branch instructions' target and return.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700297 Found = false;
Andrew Scull87f80c12015-07-20 10:19:16 -0700298 for (Inst &I : Pred->getInsts())
299 if (!I.isDeleted() && I.repointEdges(this, NewNode))
300 Found = true;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700301 assert(Found);
Jim Stichnotha8d47132015-09-08 14:43:38 -0700302 (void)Found;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700303 return NewNode;
304}
305
306namespace {
307
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800308// Helpers for advancedPhiLowering().
309
310class PhiDesc {
311 PhiDesc() = delete;
312 PhiDesc(const PhiDesc &) = delete;
313 PhiDesc &operator=(const PhiDesc &) = delete;
Jim Stichnothc59288b2015-11-09 11:38:40 -0800314
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800315public:
316 PhiDesc(InstPhi *Phi, Variable *Dest) : Phi(Phi), Dest(Dest) {}
317 PhiDesc(PhiDesc &&) = default;
318 InstPhi *Phi = nullptr;
319 Variable *Dest = nullptr;
320 Operand *Src = nullptr;
321 bool Processed = false;
322 size_t NumPred = 0; // number of entries whose Src is this Dest
323 int32_t Weight = 0; // preference for topological order
324};
325using PhiDescList = llvm::SmallVector<PhiDesc, 32>;
326
327// Always pick NumPred=0 over NumPred>0.
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700328constexpr int32_t WeightNoPreds = 8;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800329// Prefer Src as a register because the register might free up.
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700330constexpr int32_t WeightSrcIsReg = 4;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800331// Prefer Dest not as a register because the register stays free longer.
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700332constexpr int32_t WeightDestNotReg = 2;
333// Prefer NumPred=1 over NumPred>1. This is used as a tiebreaker when a
334// dependency cycle must be broken so that hopefully only one temporary
335// assignment has to be added to break the cycle.
336constexpr int32_t WeightOnePred = 1;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800337
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700338bool sameVarOrReg(TargetLowering *Target, const Variable *Var1,
339 const Operand *Opnd) {
340 if (Var1 == Opnd)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700341 return true;
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700342 const auto *Var2 = llvm::dyn_cast<Variable>(Opnd);
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700343 if (Var2 == nullptr)
344 return false;
345
346 // If either operand lacks a register, they cannot be the same.
347 if (!Var1->hasReg())
348 return false;
349 if (!Var2->hasReg())
350 return false;
351
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800352 const auto RegNum1 = Var1->getRegNum();
353 const auto RegNum2 = Var2->getRegNum();
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700354 // Quick common-case check.
355 if (RegNum1 == RegNum2)
356 return true;
357
358 assert(Target->getAliasesForRegister(RegNum1)[RegNum2] ==
359 Target->getAliasesForRegister(RegNum2)[RegNum1]);
360 return Target->getAliasesForRegister(RegNum1)[RegNum2];
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700361}
362
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800363// Update NumPred for all Phi assignments using Var as their Dest variable.
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700364// Also update Weight if NumPred dropped from 2 to 1, or 1 to 0.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800365void updatePreds(PhiDescList &Desc, TargetLowering *Target, Variable *Var) {
366 for (PhiDesc &Item : Desc) {
367 if (!Item.Processed && sameVarOrReg(Target, Var, Item.Dest)) {
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700368 --Item.NumPred;
369 if (Item.NumPred == 1) {
370 // If NumPred changed from 2 to 1, add in WeightOnePred.
371 Item.Weight += WeightOnePred;
372 } else if (Item.NumPred == 0) {
373 // If NumPred changed from 1 to 0, subtract WeightOnePred and add in
374 // WeightNoPreds.
375 Item.Weight += (WeightNoPreds - WeightOnePred);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800376 }
377 }
378 }
379}
380
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700381} // end of anonymous namespace
382
Andrew Scull57e12682015-09-16 11:30:19 -0700383// This the "advanced" version of Phi lowering for a basic block, in contrast
384// to the simple version that lowers through assignments involving temporaries.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700385//
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700386// All Phi instructions in a basic block are conceptually executed in parallel.
387// However, if we lower Phis early and commit to a sequential ordering, we may
388// end up creating unnecessary interferences which lead to worse register
Andrew Scull57e12682015-09-16 11:30:19 -0700389// allocation. Delaying Phi scheduling until after register allocation can help
390// unless there are no free registers for shuffling registers or stack slots
391// and spilling becomes necessary.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700392//
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700393// The advanced Phi lowering starts by finding a topological sort of the Phi
Andrew Scull57e12682015-09-16 11:30:19 -0700394// instructions, where "A=B" comes before "B=C" due to the anti-dependence on
395// B. Preexisting register assignments are considered in the topological sort.
396// If a topological sort is not possible due to a cycle, the cycle is broken by
397// introducing a non-parallel temporary. For example, a cycle arising from a
398// permutation like "A=B;B=C;C=A" can become "T=A;A=B;B=C;C=T". All else being
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700399// equal, prefer to schedule assignments with register-allocated Src operands
400// earlier, in case that register becomes free afterwards, and prefer to
401// schedule assignments with register-allocated Dest variables later, to keep
402// that register free for longer.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700403//
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700404// Once the ordering is determined, the Cfg edge is split and the assignment
Andrew Scull57e12682015-09-16 11:30:19 -0700405// list is lowered by the target lowering layer. Since the assignment lowering
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700406// may create new infinite-weight temporaries, a follow-on register allocation
Andrew Scull57e12682015-09-16 11:30:19 -0700407// pass will be needed. To prepare for this, liveness (including live range
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700408// calculation) of the split nodes needs to be calculated, and liveness of the
409// original node need to be updated to "undo" the effects of the phi
410// assignments.
411
412// The specific placement of the new node within the Cfg node list is deferred
413// until later, including after empty node contraction.
414//
415// After phi assignments are lowered across all blocks, another register
416// allocation pass is run, focusing only on pre-colored and infinite-weight
417// variables, similar to Om1 register allocation (except without the need to
418// specially compute these variables' live ranges, since they have already been
Andrew Scull57e12682015-09-16 11:30:19 -0700419// precisely calculated). The register allocator in this mode needs the ability
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700420// to forcibly spill and reload registers in case none are naturally available.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700421void CfgNode::advancedPhiLowering() {
422 if (getPhis().empty())
423 return;
424
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800425 PhiDescList Desc;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700426
Jim Stichnoth29841e82014-12-23 12:26:24 -0800427 for (Inst &I : Phis) {
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800428 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
429 if (!Phi->isDeleted()) {
430 Variable *Dest = Phi->getDest();
431 Desc.emplace_back(Phi, Dest);
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700432 // Undo the effect of the phi instruction on this node's live-in set by
433 // marking the phi dest variable as live on entry.
434 SizeT VarNum = Func->getLiveness()->getLiveIndex(Dest->getIndex());
435 assert(!Func->getLiveness()->getLiveIn(this)[VarNum]);
436 Func->getLiveness()->getLiveIn(this)[VarNum] = true;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800437 Phi->setDeleted();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700438 }
439 }
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800440 if (Desc.empty())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700441 return;
442
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700443 TargetLowering *Target = Func->getTarget();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700444 SizeT InEdgeIndex = 0;
445 for (CfgNode *Pred : InEdges) {
446 CfgNode *Split = splitIncomingEdge(Pred, InEdgeIndex++);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800447 SizeT Remaining = Desc.size();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700448
449 // First pass computes Src and initializes NumPred.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800450 for (PhiDesc &Item : Desc) {
451 Variable *Dest = Item.Dest;
452 Operand *Src = Item.Phi->getOperandForTarget(Pred);
453 Item.Src = Src;
454 Item.Processed = false;
455 Item.NumPred = 0;
Andrew Scull57e12682015-09-16 11:30:19 -0700456 // Cherry-pick any trivial assignments, so that they don't contribute to
457 // the running complexity of the topological sort.
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700458 if (sameVarOrReg(Target, Dest, Src)) {
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800459 Item.Processed = true;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700460 --Remaining;
461 if (Dest != Src)
Andrew Scull57e12682015-09-16 11:30:19 -0700462 // If Dest and Src are syntactically the same, don't bother adding
463 // the assignment, because in all respects it would be redundant, and
464 // if Dest/Src are on the stack, the target lowering may naively
465 // decide to lower it using a temporary register.
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700466 Split->appendInst(InstAssign::create(Func, Dest, Src));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700467 }
468 }
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800469 // Second pass computes NumPred by comparing every pair of Phi instructions.
470 for (PhiDesc &Item : Desc) {
471 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700472 continue;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800473 const Variable *Dest = Item.Dest;
474 for (PhiDesc &Item2 : Desc) {
475 if (Item2.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700476 continue;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800477 // There shouldn't be two different Phis with the same Dest variable or
Jim Stichnothc59288b2015-11-09 11:38:40 -0800478 // register.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800479 assert((&Item == &Item2) || !sameVarOrReg(Target, Dest, Item2.Dest));
480 if (sameVarOrReg(Target, Dest, Item2.Src))
481 ++Item.NumPred;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700482 }
483 }
484
485 // Another pass to compute initial Weight values.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800486 for (PhiDesc &Item : Desc) {
487 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700488 continue;
489 int32_t Weight = 0;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800490 if (Item.NumPred == 0)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700491 Weight += WeightNoPreds;
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700492 if (Item.NumPred == 1)
493 Weight += WeightOnePred;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800494 if (auto *Var = llvm::dyn_cast<Variable>(Item.Src))
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700495 if (Var->hasReg())
496 Weight += WeightSrcIsReg;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800497 if (!Item.Dest->hasReg())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700498 Weight += WeightDestNotReg;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800499 Item.Weight = Weight;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700500 }
501
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800502 // Repeatedly choose and process the best candidate in the topological sort,
503 // until no candidates remain. This implementation is O(N^2) where N is the
504 // number of Phi instructions, but with a small constant factor compared to
505 // a likely implementation of O(N) topological sort.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700506 for (; Remaining; --Remaining) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700507 int32_t BestWeight = -1;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800508 PhiDesc *BestItem = nullptr;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700509 // Find the best candidate.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800510 for (PhiDesc &Item : Desc) {
511 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700512 continue;
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700513 const int32_t Weight = Item.Weight;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700514 if (Weight > BestWeight) {
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800515 BestItem = &Item;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700516 BestWeight = Weight;
517 }
518 }
519 assert(BestWeight >= 0);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800520 Variable *Dest = BestItem->Dest;
521 Operand *Src = BestItem->Src;
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700522 assert(!sameVarOrReg(Target, Dest, Src));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700523 // Break a cycle by introducing a temporary.
Jim Stichnothbbd449d2016-03-30 15:30:30 -0700524 while (BestItem->NumPred > 0) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700525 bool Found = false;
Andrew Scull57e12682015-09-16 11:30:19 -0700526 // If the target instruction "A=B" is part of a cycle, find the "X=A"
527 // assignment in the cycle because it will have to be rewritten as
528 // "X=tmp".
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800529 for (PhiDesc &Item : Desc) {
530 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700531 continue;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800532 Operand *OtherSrc = Item.Src;
533 if (Item.NumPred && sameVarOrReg(Target, Dest, OtherSrc)) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700534 SizeT VarNum = Func->getNumVariables();
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800535 Variable *Tmp = Func->makeVariable(OtherSrc->getType());
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700536 if (BuildDefs::dump())
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800537 Tmp->setName(Func, "__split_" + std::to_string(VarNum));
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700538 Split->appendInst(InstAssign::create(Func, Tmp, OtherSrc));
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800539 Item.Src = Tmp;
540 updatePreds(Desc, Target, llvm::cast<Variable>(OtherSrc));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700541 Found = true;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800542 break;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700543 }
544 }
545 assert(Found);
Jim Stichnothb0051df2016-01-13 11:39:15 -0800546 (void)Found;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700547 }
548 // Now that a cycle (if any) has been broken, create the actual
549 // assignment.
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700550 Split->appendInst(InstAssign::create(Func, Dest, Src));
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800551 if (auto *Var = llvm::dyn_cast<Variable>(Src))
552 updatePreds(Desc, Target, Var);
553 BestItem->Processed = true;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700554 }
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700555 Split->appendInst(InstBr::create(Func, this));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700556
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700557 Split->genCode();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700558 Func->getVMetadata()->addNode(Split);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800559 // Validate to be safe. All items should be marked as processed, and have
560 // no predecessors.
561 if (BuildDefs::asserts()) {
562 for (PhiDesc &Item : Desc) {
563 (void)Item;
564 assert(Item.Processed);
565 assert(Item.NumPred == 0);
566 }
567 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700568 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700569}
570
Andrew Scull57e12682015-09-16 11:30:19 -0700571// Does address mode optimization. Pass each instruction to the TargetLowering
572// object. If it returns a new instruction (representing the optimized address
573// mode), then insert the new instruction and delete the old.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700574void CfgNode::doAddressOpt() {
575 TargetLowering *Target = Func->getTarget();
576 LoweringContext &Context = Target->getContext();
577 Context.init(this);
578 while (!Context.atEnd()) {
579 Target->doAddressOpt();
580 }
581}
582
Qining Luaee5fa82015-08-20 14:59:03 -0700583void CfgNode::doNopInsertion(RandomNumberGenerator &RNG) {
Matt Walac3302742014-08-15 16:21:56 -0700584 TargetLowering *Target = Func->getTarget();
585 LoweringContext &Context = Target->getContext();
586 Context.init(this);
Qining Lu969f6a32015-07-31 09:58:34 -0700587 Context.setInsertPoint(Context.getCur());
588 // Do not insert nop in bundle locked instructions.
589 bool PauseNopInsertion = false;
Matt Walac3302742014-08-15 16:21:56 -0700590 while (!Context.atEnd()) {
Qining Lu969f6a32015-07-31 09:58:34 -0700591 if (llvm::isa<InstBundleLock>(Context.getCur())) {
592 PauseNopInsertion = true;
593 } else if (llvm::isa<InstBundleUnlock>(Context.getCur())) {
594 PauseNopInsertion = false;
595 }
596 if (!PauseNopInsertion)
Qining Luaee5fa82015-08-20 14:59:03 -0700597 Target->doNopInsertion(RNG);
Matt Walac3302742014-08-15 16:21:56 -0700598 // Ensure Cur=Next, so that the nops are inserted before the current
599 // instruction rather than after.
Matt Walac3302742014-08-15 16:21:56 -0700600 Context.advanceCur();
Qining Lu969f6a32015-07-31 09:58:34 -0700601 Context.advanceNext();
Matt Walac3302742014-08-15 16:21:56 -0700602 }
Matt Walac3302742014-08-15 16:21:56 -0700603}
604
Andrew Scull57e12682015-09-16 11:30:19 -0700605// Drives the target lowering. Passes the current instruction and the next
606// non-deleted instruction for target lowering.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700607void CfgNode::genCode() {
608 TargetLowering *Target = Func->getTarget();
609 LoweringContext &Context = Target->getContext();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700610 // Lower the regular instructions.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700611 Context.init(this);
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700612 Target->initNodeForLowering(this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700613 while (!Context.atEnd()) {
614 InstList::iterator Orig = Context.getCur();
615 if (llvm::isa<InstRet>(*Orig))
616 setHasReturn();
617 Target->lower();
618 // Ensure target lowering actually moved the cursor.
619 assert(Context.getCur() != Orig);
620 }
Jim Stichnoth318f4cd2015-10-01 21:02:37 -0700621 Context.availabilityReset();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700622 // Do preliminary lowering of the Phi instructions.
623 Target->prelowerPhis();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700624}
625
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700626void CfgNode::livenessLightweight() {
627 SizeT NumVars = Func->getNumVariables();
Jim Stichnoth47752552014-10-13 17:15:08 -0700628 LivenessBV Live(NumVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700629 // Process regular instructions in reverse order.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800630 for (Inst &I : reverse_range(Insts)) {
631 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700632 continue;
Jim Stichnoth7e571362015-01-09 11:43:26 -0800633 I.livenessLightweight(Func, Live);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700634 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800635 for (Inst &I : Phis) {
636 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700637 continue;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800638 I.livenessLightweight(Func, Live);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700639 }
640}
641
Andrew Scull57e12682015-09-16 11:30:19 -0700642// Performs liveness analysis on the block. Returns true if the incoming
643// liveness changed from before, false if it stayed the same. (If it changes,
644// the node's predecessors need to be processed again.)
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700645bool CfgNode::liveness(Liveness *Liveness) {
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800646 const SizeT NumVars = Liveness->getNumVarsInNode(this);
647 const SizeT NumGlobalVars = Liveness->getNumGlobalVars();
648 LivenessBV &Live = Liveness->getScratchBV();
649 Live.clear();
650
Jim Stichnothae953202014-12-20 06:17:49 -0800651 LiveBeginEndMap *LiveBegin = nullptr;
652 LiveBeginEndMap *LiveEnd = nullptr;
Andrew Scull57e12682015-09-16 11:30:19 -0700653 // Mark the beginning and ending of each variable's live range with the
654 // sentinel instruction number 0.
Jim Stichnoth47752552014-10-13 17:15:08 -0700655 if (Liveness->getMode() == Liveness_Intervals) {
656 LiveBegin = Liveness->getLiveBegin(this);
657 LiveEnd = Liveness->getLiveEnd(this);
658 LiveBegin->clear();
659 LiveEnd->clear();
Andrew Scull57e12682015-09-16 11:30:19 -0700660 // Guess that the number of live ranges beginning is roughly the number of
661 // instructions, and same for live ranges ending.
Jim Stichnoth47752552014-10-13 17:15:08 -0700662 LiveBegin->reserve(getInstCountEstimate());
663 LiveEnd->reserve(getInstCountEstimate());
664 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800665
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700666 // Initialize Live to be the union of all successors' LiveIn.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700667 for (CfgNode *Succ : OutEdges) {
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800668 const LivenessBV &LiveIn = Liveness->getLiveIn(Succ);
669 assert(LiveIn.empty() || LiveIn.size() == NumGlobalVars);
670 Live |= LiveIn;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700671 // Mark corresponding argument of phis in successor as live.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800672 for (Inst &I : Succ->Phis) {
Jim Stichnoth552490c2015-08-05 16:21:42 -0700673 if (I.isDeleted())
674 continue;
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800675 auto *Phi = llvm::cast<InstPhi>(&I);
Jim Stichnoth1502e592014-12-11 09:22:45 -0800676 Phi->livenessPhiOperand(Live, this, Liveness);
677 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700678 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800679 assert(Live.empty() || Live.size() == NumGlobalVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700680 Liveness->getLiveOut(this) = Live;
681
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800682 // Expand Live so it can hold locals in addition to globals.
683 Live.resize(NumVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700684 // Process regular instructions in reverse order.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800685 for (Inst &I : reverse_range(Insts)) {
686 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700687 continue;
Jim Stichnoth7e571362015-01-09 11:43:26 -0800688 I.liveness(I.getNumber(), Live, Liveness, LiveBegin, LiveEnd);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700689 }
Andrew Scull57e12682015-09-16 11:30:19 -0700690 // Process phis in forward order so that we can override the instruction
691 // number to be that of the earliest phi instruction in the block.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700692 SizeT NumNonDeadPhis = 0;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700693 InstNumberT FirstPhiNumber = Inst::NumberSentinel;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800694 for (Inst &I : Phis) {
695 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700696 continue;
697 if (FirstPhiNumber == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800698 FirstPhiNumber = I.getNumber();
699 if (I.liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd))
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700700 ++NumNonDeadPhis;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700701 }
702
Andrew Scull57e12682015-09-16 11:30:19 -0700703 // When using the sparse representation, after traversing the instructions in
704 // the block, the Live bitvector should only contain set bits for global
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800705 // variables upon block entry. We validate this by testing the upper bits of
706 // the Live bitvector.
707 if (Live.find_next(NumGlobalVars) != -1) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700708 if (BuildDefs::dump()) {
Andrew Scull57e12682015-09-16 11:30:19 -0700709 // This is a fatal liveness consistency error. Print some diagnostics and
710 // abort.
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700711 Ostream &Str = Func->getContext()->getStrDump();
712 Func->resetCurrentNode();
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800713 Str << "Invalid Live =";
714 for (SizeT i = NumGlobalVars; i < Live.size(); ++i) {
715 if (Live.test(i)) {
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700716 Str << " ";
717 Liveness->getVariable(i, this)->dump(Func);
718 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700719 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700720 Str << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700721 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700722 llvm::report_fatal_error("Fatal inconsistency in liveness analysis");
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700723 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800724 // Now truncate Live to prevent LiveIn from growing.
725 Live.resize(NumGlobalVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700726
727 bool Changed = false;
Jim Stichnoth47752552014-10-13 17:15:08 -0700728 LivenessBV &LiveIn = Liveness->getLiveIn(this);
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800729 assert(LiveIn.empty() || LiveIn.size() == NumGlobalVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700730 // Add in current LiveIn
731 Live |= LiveIn;
732 // Check result, set LiveIn=Live
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700733 SizeT &PrevNumNonDeadPhis = Liveness->getNumNonDeadPhis(this);
734 bool LiveInChanged = (Live != LiveIn);
735 Changed = (NumNonDeadPhis != PrevNumNonDeadPhis || LiveInChanged);
736 if (LiveInChanged)
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700737 LiveIn = Live;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700738 PrevNumNonDeadPhis = NumNonDeadPhis;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700739 return Changed;
740}
741
Jim Stichnoth230d4102015-09-25 17:40:32 -0700742// Validate the integrity of the live ranges in this block. If there are any
743// errors, it prints details and returns false. On success, it returns true.
Jim Stichnoth318f4cd2015-10-01 21:02:37 -0700744bool CfgNode::livenessValidateIntervals(Liveness *Liveness) const {
Jim Stichnoth230d4102015-09-25 17:40:32 -0700745 if (!BuildDefs::asserts())
746 return true;
747
748 // Verify there are no duplicates.
749 auto ComparePair =
750 [](const LiveBeginEndMapEntry &A, const LiveBeginEndMapEntry &B) {
751 return A.first == B.first;
752 };
753 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this);
754 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this);
755 if (std::adjacent_find(MapBegin.begin(), MapBegin.end(), ComparePair) ==
756 MapBegin.end() &&
757 std::adjacent_find(MapEnd.begin(), MapEnd.end(), ComparePair) ==
758 MapEnd.end())
759 return true;
760
761 // There is definitely a liveness error. All paths from here return false.
762 if (!BuildDefs::dump())
763 return false;
764
765 // Print all the errors.
766 if (BuildDefs::dump()) {
767 GlobalContext *Ctx = Func->getContext();
768 OstreamLocker L(Ctx);
769 Ostream &Str = Ctx->getStrDump();
770 if (Func->isVerbose()) {
771 Str << "Live range errors in the following block:\n";
772 dump(Func);
773 }
774 for (auto Start = MapBegin.begin();
775 (Start = std::adjacent_find(Start, MapBegin.end(), ComparePair)) !=
776 MapBegin.end();
777 ++Start) {
778 auto Next = Start + 1;
779 Str << "Duplicate LR begin, block " << getName() << ", instructions "
780 << Start->second << " & " << Next->second << ", variable "
781 << Liveness->getVariable(Start->first, this)->getName(Func) << "\n";
782 }
783 for (auto Start = MapEnd.begin();
784 (Start = std::adjacent_find(Start, MapEnd.end(), ComparePair)) !=
785 MapEnd.end();
786 ++Start) {
787 auto Next = Start + 1;
788 Str << "Duplicate LR end, block " << getName() << ", instructions "
789 << Start->second << " & " << Next->second << ", variable "
790 << Liveness->getVariable(Start->first, this)->getName(Func) << "\n";
791 }
792 }
793
794 return false;
795}
796
Andrew Scull57e12682015-09-16 11:30:19 -0700797// Once basic liveness is complete, compute actual live ranges. It is assumed
798// that within a single basic block, a live range begins at most once and ends
799// at most once. This is certainly true for pure SSA form. It is also true once
800// phis are lowered, since each assignment to the phi-based temporary is in a
801// different basic block, and there is a single read that ends the live in the
802// basic block that contained the actual phi instruction.
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800803void CfgNode::livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum,
804 InstNumberT LastInstNum) {
805 TimerMarker T1(TimerStack::TT_liveRange, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700806
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800807 const SizeT NumVars = Liveness->getNumVarsInNode(this);
808 const LivenessBV &LiveIn = Liveness->getLiveIn(this);
809 const LivenessBV &LiveOut = Liveness->getLiveOut(this);
Jim Stichnoth47752552014-10-13 17:15:08 -0700810 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this);
811 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this);
812 std::sort(MapBegin.begin(), MapBegin.end());
813 std::sort(MapEnd.begin(), MapEnd.end());
Jim Stichnoth230d4102015-09-25 17:40:32 -0700814
815 if (!livenessValidateIntervals(Liveness)) {
816 llvm::report_fatal_error("livenessAddIntervals: Liveness error");
817 return;
818 }
Jim Stichnoth47752552014-10-13 17:15:08 -0700819
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800820 LivenessBV &LiveInAndOut = Liveness->getScratchBV();
821 LiveInAndOut = LiveIn;
Jim Stichnoth47752552014-10-13 17:15:08 -0700822 LiveInAndOut &= LiveOut;
823
824 // Iterate in parallel across the sorted MapBegin[] and MapEnd[].
825 auto IBB = MapBegin.begin(), IEB = MapEnd.begin();
826 auto IBE = MapBegin.end(), IEE = MapEnd.end();
827 while (IBB != IBE || IEB != IEE) {
828 SizeT i1 = IBB == IBE ? NumVars : IBB->first;
829 SizeT i2 = IEB == IEE ? NumVars : IEB->first;
830 SizeT i = std::min(i1, i2);
Andrew Scull57e12682015-09-16 11:30:19 -0700831 // i1 is the Variable number of the next MapBegin entry, and i2 is the
832 // Variable number of the next MapEnd entry. If i1==i2, then the Variable's
833 // live range begins and ends in this block. If i1<i2, then i1's live range
834 // begins at instruction IBB->second and extends through the end of the
835 // block. If i1>i2, then i2's live range begins at the first instruction of
836 // the block and ends at IEB->second. In any case, we choose the lesser of
837 // i1 and i2 and proceed accordingly.
Jim Stichnoth47752552014-10-13 17:15:08 -0700838 InstNumberT LB = i == i1 ? IBB->second : FirstInstNum;
839 InstNumberT LE = i == i2 ? IEB->second : LastInstNum + 1;
840
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700841 Variable *Var = Liveness->getVariable(i, this);
Jim Stichnothf9df4522015-08-06 17:50:14 -0700842 if (LB > LE) {
Andrew Scull11c9a322015-08-28 14:24:14 -0700843 Var->addLiveRange(FirstInstNum, LE);
844 Var->addLiveRange(LB, LastInstNum + 1);
Andrew Scull57e12682015-09-16 11:30:19 -0700845 // Assert that Var is a global variable by checking that its liveness
846 // index is less than the number of globals. This ensures that the
847 // LiveInAndOut[] access is valid.
Jim Stichnothf9df4522015-08-06 17:50:14 -0700848 assert(i < Liveness->getNumGlobalVars());
849 LiveInAndOut[i] = false;
850 } else {
Andrew Scull11c9a322015-08-28 14:24:14 -0700851 Var->addLiveRange(LB, LE);
Jim Stichnoth47752552014-10-13 17:15:08 -0700852 }
853 if (i == i1)
854 ++IBB;
855 if (i == i2)
856 ++IEB;
857 }
858 // Process the variables that are live across the entire block.
859 for (int i = LiveInAndOut.find_first(); i != -1;
860 i = LiveInAndOut.find_next(i)) {
861 Variable *Var = Liveness->getVariable(i, this);
Jim Stichnoth552490c2015-08-05 16:21:42 -0700862 if (Liveness->getRangeMask(Var->getIndex()))
Andrew Scull11c9a322015-08-28 14:24:14 -0700863 Var->addLiveRange(FirstInstNum, LastInstNum + 1);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700864 }
865}
866
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700867// If this node contains only deleted instructions, and ends in an
Andrew Scull57e12682015-09-16 11:30:19 -0700868// unconditional branch, contract the node by repointing all its in-edges to
869// its successor.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700870void CfgNode::contractIfEmpty() {
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800871 if (InEdges.empty())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700872 return;
Jim Stichnothae953202014-12-20 06:17:49 -0800873 Inst *Branch = nullptr;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800874 for (Inst &I : Insts) {
875 if (I.isDeleted())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700876 continue;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800877 if (I.isUnconditionalBranch())
878 Branch = &I;
879 else if (!I.isRedundantAssign())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700880 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700881 }
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -0800882 // Make sure there is actually a successor to repoint in-edges to.
883 if (OutEdges.empty())
884 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700885 assert(OutEdges.size() == 1);
Jim Stichnoth1921fba2015-09-15 10:06:30 -0700886 // Don't try to delete a self-loop.
887 if (OutEdges[0] == this)
888 return;
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -0800889 // Make sure the node actually contains (ends with) an unconditional branch.
890 if (Branch == nullptr)
891 return;
Jim Stichnoth1921fba2015-09-15 10:06:30 -0700892
893 Branch->setDeleted();
Andrew Scull713278a2015-07-22 17:17:02 -0700894 CfgNode *Successor = OutEdges.front();
Andrew Scull57e12682015-09-16 11:30:19 -0700895 // Repoint all this node's in-edges to this node's successor, unless this
896 // node's successor is actually itself (in which case the statement
897 // "OutEdges.front()->InEdges.push_back(Pred)" could invalidate the iterator
898 // over this->InEdges).
Andrew Scull713278a2015-07-22 17:17:02 -0700899 if (Successor != this) {
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800900 for (CfgNode *Pred : InEdges) {
Andrew Scull713278a2015-07-22 17:17:02 -0700901 for (CfgNode *&I : Pred->OutEdges) {
902 if (I == this) {
903 I = Successor;
904 Successor->InEdges.push_back(Pred);
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800905 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700906 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800907 for (Inst &I : Pred->getInsts()) {
908 if (!I.isDeleted())
Andrew Scull713278a2015-07-22 17:17:02 -0700909 I.repointEdges(this, Successor);
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800910 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700911 }
Andrew Scull713278a2015-07-22 17:17:02 -0700912
913 // Remove the in-edge to the successor to allow node reordering to make
Andrew Scull57e12682015-09-16 11:30:19 -0700914 // better decisions. For example it's more helpful to place a node after a
915 // reachable predecessor than an unreachable one (like the one we just
Andrew Scull713278a2015-07-22 17:17:02 -0700916 // contracted).
917 Successor->InEdges.erase(
918 std::find(Successor->InEdges.begin(), Successor->InEdges.end(), this));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700919 }
920 InEdges.clear();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700921}
922
Jim Stichnothff9c7062014-09-18 04:50:49 -0700923void CfgNode::doBranchOpt(const CfgNode *NextNode) {
924 TargetLowering *Target = Func->getTarget();
Andrew Scull713278a2015-07-22 17:17:02 -0700925 // Find the first opportunity for branch optimization (which will be the last
Andrew Scull57e12682015-09-16 11:30:19 -0700926 // instruction in the block) and stop. This is sufficient unless there is
927 // some target lowering where we have the possibility of multiple
928 // optimizations per block. Take care with switch lowering as there are
929 // multiple unconditional branches and only the last can be deleted.
Andrew Scull713278a2015-07-22 17:17:02 -0700930 for (Inst &I : reverse_range(Insts)) {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800931 if (!I.isDeleted()) {
932 Target->doBranchOpt(&I, NextNode);
Andrew Scull713278a2015-07-22 17:17:02 -0700933 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700934 }
935 }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700936}
937
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700938// ======================== Dump routines ======================== //
939
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700940namespace {
941
942// Helper functions for emit().
943
944void emitRegisterUsage(Ostream &Str, const Cfg *Func, const CfgNode *Node,
Andrew Scull00741a02015-09-16 19:04:09 -0700945 bool IsLiveIn, CfgVector<SizeT> &LiveRegCount) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700946 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800947 return;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700948 Liveness *Liveness = Func->getLiveness();
949 const LivenessBV *Live;
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800950 const auto StackReg = Func->getTarget()->getStackReg();
951 const auto FrameOrStackReg = Func->getTarget()->getFrameOrStackReg();
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700952 if (IsLiveIn) {
953 Live = &Liveness->getLiveIn(Node);
Jim Stichnoth751e27e2015-12-16 12:40:31 -0800954 Str << "\t\t\t\t/* LiveIn=";
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700955 } else {
956 Live = &Liveness->getLiveOut(Node);
Jim Stichnoth751e27e2015-12-16 12:40:31 -0800957 Str << "\t\t\t\t/* LiveOut=";
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700958 }
959 if (!Live->empty()) {
Andrew Scull00741a02015-09-16 19:04:09 -0700960 CfgVector<Variable *> LiveRegs;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700961 for (SizeT i = 0; i < Live->size(); ++i) {
Jim Stichnothe7418712015-10-09 06:54:02 -0700962 if (!(*Live)[i])
963 continue;
964 Variable *Var = Liveness->getVariable(i, Node);
965 if (!Var->hasReg())
966 continue;
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800967 const auto RegNum = Var->getRegNum();
Jim Stichnothe7418712015-10-09 06:54:02 -0700968 if (RegNum == StackReg || RegNum == FrameOrStackReg)
969 continue;
970 if (IsLiveIn)
971 ++LiveRegCount[RegNum];
972 LiveRegs.push_back(Var);
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700973 }
Andrew Scull57e12682015-09-16 11:30:19 -0700974 // Sort the variables by regnum so they are always printed in a familiar
975 // order.
Jim Stichnoth9a05aea2015-05-26 16:01:23 -0700976 std::sort(LiveRegs.begin(), LiveRegs.end(),
977 [](const Variable *V1, const Variable *V2) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800978 return unsigned(V1->getRegNum()) < unsigned(V2->getRegNum());
Jim Stichnoth8e6bf6e2015-06-03 15:58:12 -0700979 });
Jim Stichnoth9a05aea2015-05-26 16:01:23 -0700980 bool First = true;
981 for (Variable *Var : LiveRegs) {
982 if (!First)
983 Str << ",";
984 First = false;
985 Var->emit(Func);
986 }
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700987 }
Jim Stichnoth751e27e2015-12-16 12:40:31 -0800988 Str << " */\n";
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700989}
990
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800991/// Returns true if some text was emitted - in which case the caller definitely
992/// needs to emit a newline character.
993bool emitLiveRangesEnded(Ostream &Str, const Cfg *Func, const Inst *Instr,
Andrew Scull00741a02015-09-16 19:04:09 -0700994 CfgVector<SizeT> &LiveRegCount) {
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800995 bool Printed = false;
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700996 if (!BuildDefs::dump())
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800997 return Printed;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700998 Variable *Dest = Instr->getDest();
Andrew Scull57e12682015-09-16 11:30:19 -0700999 // Normally we increment the live count for the dest register. But we
Jim Stichnoth230d4102015-09-25 17:40:32 -07001000 // shouldn't if the instruction's IsDestRedefined flag is set, because this
Andrew Scull57e12682015-09-16 11:30:19 -07001001 // means that the target lowering created this instruction as a non-SSA
1002 // assignment; i.e., a different, previous instruction started the dest
1003 // variable's live range.
Jim Stichnoth230d4102015-09-25 17:40:32 -07001004 if (!Instr->isDestRedefined() && Dest && Dest->hasReg())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001005 ++LiveRegCount[Dest->getRegNum()];
John Portoec3f5652015-08-31 15:07:09 -07001006 FOREACH_VAR_IN_INST(Var, *Instr) {
1007 bool ShouldReport = Instr->isLastUse(Var);
1008 if (ShouldReport && Var->hasReg()) {
1009 // Don't report end of live range until the live count reaches 0.
1010 SizeT NewCount = --LiveRegCount[Var->getRegNum()];
1011 if (NewCount)
1012 ShouldReport = false;
1013 }
1014 if (ShouldReport) {
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001015 if (Printed)
John Portoec3f5652015-08-31 15:07:09 -07001016 Str << ",";
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001017 else
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001018 Str << " \t/* END=";
John Portoec3f5652015-08-31 15:07:09 -07001019 Var->emit(Func);
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001020 Printed = true;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001021 }
1022 }
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001023 if (Printed)
1024 Str << " */";
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001025 return Printed;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001026}
1027
Jan Voung0faec4c2014-11-05 17:29:56 -08001028void updateStats(Cfg *Func, const Inst *I) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001029 if (!BuildDefs::dump())
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001030 return;
Andrew Scull57e12682015-09-16 11:30:19 -07001031 // Update emitted instruction count, plus fill/spill count for Variable
1032 // operands without a physical register.
Jan Voung0faec4c2014-11-05 17:29:56 -08001033 if (uint32_t Count = I->getEmitInstCount()) {
1034 Func->getContext()->statsUpdateEmitted(Count);
1035 if (Variable *Dest = I->getDest()) {
1036 if (!Dest->hasReg())
1037 Func->getContext()->statsUpdateFills();
1038 }
1039 for (SizeT S = 0; S < I->getSrcSize(); ++S) {
Jim Stichnoth54f3d512015-12-11 09:53:00 -08001040 if (auto *Src = llvm::dyn_cast<Variable>(I->getSrc(S))) {
Jan Voung0faec4c2014-11-05 17:29:56 -08001041 if (!Src->hasReg())
1042 Func->getContext()->statsUpdateSpills();
1043 }
1044 }
1045 }
1046}
1047
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001048} // end of anonymous namespace
1049
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001050void CfgNode::emit(Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001051 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001052 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001053 Func->setCurrentNode(this);
1054 Ostream &Str = Func->getContext()->getStrEmit();
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001055 Liveness *Liveness = Func->getLiveness();
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001056 const bool DecorateAsm =
Karl Schimpfdf80eb82015-02-09 14:20:22 -08001057 Liveness && Func->getContext()->getFlags().getDecorateAsm();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001058 Str << getAsmName() << ":\n";
Andrew Scull57e12682015-09-16 11:30:19 -07001059 // LiveRegCount keeps track of the number of currently live variables that
1060 // each register is assigned to. Normally that would be only 0 or 1, but the
1061 // register allocator's AllowOverlap inference allows it to be greater than 1
1062 // for short periods.
Andrew Scull00741a02015-09-16 19:04:09 -07001063 CfgVector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters());
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001064 if (DecorateAsm) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -07001065 constexpr bool IsLiveIn = true;
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001066 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount);
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001067 if (getInEdges().size()) {
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001068 Str << "\t\t\t\t/* preds=";
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001069 bool First = true;
1070 for (CfgNode *I : getInEdges()) {
1071 if (!First)
1072 Str << ",";
1073 First = false;
Jim Stichnoth9a63bab2015-10-05 11:13:59 -07001074 Str << "$" << I->getName();
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001075 }
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001076 Str << " */\n";
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001077 }
1078 if (getLoopNestDepth()) {
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001079 Str << "\t\t\t\t/* loop depth=" << getLoopNestDepth() << " */\n";
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001080 }
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001081 }
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001082
Jim Stichnoth29841e82014-12-23 12:26:24 -08001083 for (const Inst &I : Phis) {
1084 if (I.isDeleted())
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001085 continue;
1086 // Emitting a Phi instruction should cause an error.
Jim Stichnoth29841e82014-12-23 12:26:24 -08001087 I.emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001088 }
Jim Stichnoth29841e82014-12-23 12:26:24 -08001089 for (const Inst &I : Insts) {
1090 if (I.isDeleted())
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001091 continue;
Jim Stichnothb82baf22015-05-27 10:41:07 -07001092 if (I.isRedundantAssign()) {
Andrew Scull57e12682015-09-16 11:30:19 -07001093 // Usually, redundant assignments end the live range of the src variable
1094 // and begin the live range of the dest variable, with no net effect on
1095 // the liveness of their register. However, if the register allocator
1096 // infers the AllowOverlap condition, then this may be a redundant
1097 // assignment that does not end the src variable's live range, in which
1098 // case the active variable count for that register needs to be bumped.
1099 // That normally would have happened as part of emitLiveRangesEnded(),
1100 // but that isn't called for redundant assignments.
Jim Stichnothb82baf22015-05-27 10:41:07 -07001101 Variable *Dest = I.getDest();
Jim Stichnoth1fb030c2015-10-15 11:10:38 -07001102 if (DecorateAsm && Dest->hasReg()) {
Jim Stichnothb82baf22015-05-27 10:41:07 -07001103 ++LiveRegCount[Dest->getRegNum()];
Jim Stichnoth1fb030c2015-10-15 11:10:38 -07001104 if (I.isLastUse(I.getSrc(0)))
1105 --LiveRegCount[llvm::cast<Variable>(I.getSrc(0))->getRegNum()];
1106 }
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001107 continue;
Jim Stichnothb82baf22015-05-27 10:41:07 -07001108 }
Jim Stichnoth29841e82014-12-23 12:26:24 -08001109 I.emit(Func);
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001110 bool Printed = false;
Jan Voung0faec4c2014-11-05 17:29:56 -08001111 if (DecorateAsm)
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001112 Printed = emitLiveRangesEnded(Str, Func, &I, LiveRegCount);
1113 if (Printed || llvm::isa<InstTarget>(&I))
1114 Str << "\n";
Jim Stichnoth29841e82014-12-23 12:26:24 -08001115 updateStats(Func, &I);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001116 }
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001117 if (DecorateAsm) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -07001118 constexpr bool IsLiveIn = false;
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001119 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount);
1120 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001121}
1122
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001123// Helper class for emitIAS().
1124namespace {
1125class BundleEmitHelper {
1126 BundleEmitHelper() = delete;
1127 BundleEmitHelper(const BundleEmitHelper &) = delete;
1128 BundleEmitHelper &operator=(const BundleEmitHelper &) = delete;
1129
1130public:
David Sehr26217e32015-11-26 13:03:50 -08001131 BundleEmitHelper(Assembler *Asm, const InstList &Insts)
1132 : Asm(Asm), End(Insts.end()), BundleLockStart(End),
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001133 BundleSize(1 << Asm->getBundleAlignLog2Bytes()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001134 BundleMaskLo(BundleSize - 1), BundleMaskHi(~BundleMaskLo) {}
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001135 // Check whether we're currently within a bundle_lock region.
1136 bool isInBundleLockRegion() const { return BundleLockStart != End; }
Andrew Scull57e12682015-09-16 11:30:19 -07001137 // Check whether the current bundle_lock region has the align_to_end option.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001138 bool isAlignToEnd() const {
1139 assert(isInBundleLockRegion());
1140 return llvm::cast<InstBundleLock>(getBundleLockStart())->getOption() ==
1141 InstBundleLock::Opt_AlignToEnd;
1142 }
John Porto56958cb2016-01-14 09:18:18 -08001143 bool isPadToEnd() const {
1144 assert(isInBundleLockRegion());
1145 return llvm::cast<InstBundleLock>(getBundleLockStart())->getOption() ==
1146 InstBundleLock::Opt_PadToEnd;
1147 }
Andrew Scull57e12682015-09-16 11:30:19 -07001148 // Check whether the entire bundle_lock region falls within the same bundle.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001149 bool isSameBundle() const {
1150 assert(isInBundleLockRegion());
1151 return SizeSnapshotPre == SizeSnapshotPost ||
1152 (SizeSnapshotPre & BundleMaskHi) ==
1153 ((SizeSnapshotPost - 1) & BundleMaskHi);
1154 }
Andrew Scull57e12682015-09-16 11:30:19 -07001155 // Get the bundle alignment of the first instruction of the bundle_lock
1156 // region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001157 intptr_t getPreAlignment() const {
1158 assert(isInBundleLockRegion());
1159 return SizeSnapshotPre & BundleMaskLo;
1160 }
Andrew Scull57e12682015-09-16 11:30:19 -07001161 // Get the bundle alignment of the first instruction past the bundle_lock
1162 // region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001163 intptr_t getPostAlignment() const {
1164 assert(isInBundleLockRegion());
1165 return SizeSnapshotPost & BundleMaskLo;
1166 }
Andrew Scull57e12682015-09-16 11:30:19 -07001167 // Get the iterator pointing to the bundle_lock instruction, e.g. to roll
1168 // back the instruction iteration to that point.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001169 InstList::const_iterator getBundleLockStart() const {
1170 assert(isInBundleLockRegion());
1171 return BundleLockStart;
1172 }
Andrew Scull57e12682015-09-16 11:30:19 -07001173 // Set up bookkeeping when the bundle_lock instruction is first processed.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001174 void enterBundleLock(InstList::const_iterator I) {
1175 assert(!isInBundleLockRegion());
1176 BundleLockStart = I;
1177 SizeSnapshotPre = Asm->getBufferSize();
1178 Asm->setPreliminary(true);
1179 assert(isInBundleLockRegion());
1180 }
Andrew Scull57e12682015-09-16 11:30:19 -07001181 // Update bookkeeping when the bundle_unlock instruction is processed.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001182 void enterBundleUnlock() {
1183 assert(isInBundleLockRegion());
1184 SizeSnapshotPost = Asm->getBufferSize();
1185 }
Andrew Scull57e12682015-09-16 11:30:19 -07001186 // Update bookkeeping when we are completely finished with the bundle_lock
1187 // region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001188 void leaveBundleLockRegion() { BundleLockStart = End; }
Andrew Scull57e12682015-09-16 11:30:19 -07001189 // Check whether the instruction sequence fits within the current bundle, and
1190 // if not, add nop padding to the end of the current bundle.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001191 void padToNextBundle() {
1192 assert(isInBundleLockRegion());
1193 if (!isSameBundle()) {
1194 intptr_t PadToNextBundle = BundleSize - getPreAlignment();
1195 Asm->padWithNop(PadToNextBundle);
1196 SizeSnapshotPre += PadToNextBundle;
1197 SizeSnapshotPost += PadToNextBundle;
1198 assert((Asm->getBufferSize() & BundleMaskLo) == 0);
1199 assert(Asm->getBufferSize() == SizeSnapshotPre);
1200 }
1201 }
Andrew Scull57e12682015-09-16 11:30:19 -07001202 // If align_to_end is specified, add padding such that the instruction
1203 // sequences ends precisely at a bundle boundary.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001204 void padForAlignToEnd() {
1205 assert(isInBundleLockRegion());
1206 if (isAlignToEnd()) {
1207 if (intptr_t Offset = getPostAlignment()) {
1208 Asm->padWithNop(BundleSize - Offset);
1209 SizeSnapshotPre = Asm->getBufferSize();
1210 }
1211 }
1212 }
John Porto56958cb2016-01-14 09:18:18 -08001213 // If pad_to_end is specified, add padding such that the first instruction
1214 // after the instruction sequence starts at a bundle boundary.
1215 void padForPadToEnd() {
1216 assert(isInBundleLockRegion());
1217 if (isPadToEnd()) {
1218 if (intptr_t Offset = getPostAlignment()) {
1219 Asm->padWithNop(BundleSize - Offset);
1220 SizeSnapshotPre = Asm->getBufferSize();
1221 }
1222 }
1223 } // Update bookkeeping when rolling back for the second pass.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001224 void rollback() {
1225 assert(isInBundleLockRegion());
1226 Asm->setBufferSize(SizeSnapshotPre);
1227 Asm->setPreliminary(false);
1228 }
1229
1230private:
1231 Assembler *const Asm;
Andrew Scull57e12682015-09-16 11:30:19 -07001232 // End is a sentinel value such that BundleLockStart==End implies that we are
1233 // not in a bundle_lock region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001234 const InstList::const_iterator End;
1235 InstList::const_iterator BundleLockStart;
1236 const intptr_t BundleSize;
1237 // Masking with BundleMaskLo identifies an address's bundle offset.
1238 const intptr_t BundleMaskLo;
1239 // Masking with BundleMaskHi identifies an address's bundle.
1240 const intptr_t BundleMaskHi;
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001241 intptr_t SizeSnapshotPre = 0;
1242 intptr_t SizeSnapshotPost = 0;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001243};
1244
1245} // end of anonymous namespace
1246
Jan Voung0faec4c2014-11-05 17:29:56 -08001247void CfgNode::emitIAS(Cfg *Func) const {
1248 Func->setCurrentNode(this);
Jim Stichnothbbca7542015-02-11 16:08:31 -08001249 Assembler *Asm = Func->getAssembler<>();
Andrew Scull57e12682015-09-16 11:30:19 -07001250 // TODO(stichnot): When sandboxing, defer binding the node label until just
1251 // before the first instruction is emitted, to reduce the chance that a
1252 // padding nop is a branch target.
Karl Schimpf50a33312015-10-23 09:19:48 -07001253 Asm->bindCfgNodeLabel(this);
Jim Stichnoth29841e82014-12-23 12:26:24 -08001254 for (const Inst &I : Phis) {
1255 if (I.isDeleted())
Jan Voung0faec4c2014-11-05 17:29:56 -08001256 continue;
1257 // Emitting a Phi instruction should cause an error.
Jim Stichnoth29841e82014-12-23 12:26:24 -08001258 I.emitIAS(Func);
Jan Voung0faec4c2014-11-05 17:29:56 -08001259 }
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001260
1261 // Do the simple emission if not sandboxed.
1262 if (!Func->getContext()->getFlags().getUseSandboxing()) {
1263 for (const Inst &I : Insts) {
1264 if (!I.isDeleted() && !I.isRedundantAssign()) {
1265 I.emitIAS(Func);
1266 updateStats(Func, &I);
1267 }
1268 }
1269 return;
Jan Voung0faec4c2014-11-05 17:29:56 -08001270 }
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001271
Andrew Scull57e12682015-09-16 11:30:19 -07001272 // The remainder of the function handles emission with sandboxing. There are
1273 // explicit bundle_lock regions delimited by bundle_lock and bundle_unlock
1274 // instructions. All other instructions are treated as an implicit
1275 // one-instruction bundle_lock region. Emission is done twice for each
1276 // bundle_lock region. The first pass is a preliminary pass, after which we
1277 // can figure out what nop padding is needed, then roll back, and make the
1278 // final pass.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001279 //
Andrew Scull57e12682015-09-16 11:30:19 -07001280 // Ideally, the first pass would be speculative and the second pass would
1281 // only be done if nop padding were needed, but the structure of the
1282 // integrated assembler makes it hard to roll back the state of label
1283 // bindings, label links, and relocation fixups. Instead, the first pass just
1284 // disables all mutation of that state.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001285
David Sehr26217e32015-11-26 13:03:50 -08001286 BundleEmitHelper Helper(Asm, Insts);
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001287 InstList::const_iterator End = Insts.end();
Andrew Scull57e12682015-09-16 11:30:19 -07001288 // Retrying indicates that we had to roll back to the bundle_lock instruction
1289 // to apply padding before the bundle_lock sequence.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001290 bool Retrying = false;
1291 for (InstList::const_iterator I = Insts.begin(); I != End; ++I) {
1292 if (I->isDeleted() || I->isRedundantAssign())
1293 continue;
1294
1295 if (llvm::isa<InstBundleLock>(I)) {
Andrew Scull57e12682015-09-16 11:30:19 -07001296 // Set up the initial bundle_lock state. This should not happen while
1297 // retrying, because the retry rolls back to the instruction following
1298 // the bundle_lock instruction.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001299 assert(!Retrying);
1300 Helper.enterBundleLock(I);
1301 continue;
1302 }
1303
1304 if (llvm::isa<InstBundleUnlock>(I)) {
1305 Helper.enterBundleUnlock();
1306 if (Retrying) {
1307 // Make sure all instructions are in the same bundle.
1308 assert(Helper.isSameBundle());
Andrew Scull57e12682015-09-16 11:30:19 -07001309 // If align_to_end is specified, make sure the next instruction begins
1310 // the bundle.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001311 assert(!Helper.isAlignToEnd() || Helper.getPostAlignment() == 0);
John Porto56958cb2016-01-14 09:18:18 -08001312 Helper.padForPadToEnd();
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001313 Helper.leaveBundleLockRegion();
1314 Retrying = false;
1315 } else {
1316 // This is the first pass, so roll back for the retry pass.
1317 Helper.rollback();
Andrew Scull57e12682015-09-16 11:30:19 -07001318 // Pad to the next bundle if the instruction sequence crossed a bundle
1319 // boundary.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001320 Helper.padToNextBundle();
1321 // Insert additional padding to make AlignToEnd work.
1322 Helper.padForAlignToEnd();
1323 // Prepare for the retry pass after padding is done.
1324 Retrying = true;
1325 I = Helper.getBundleLockStart();
1326 }
1327 continue;
1328 }
1329
1330 // I points to a non bundle_lock/bundle_unlock instruction.
1331 if (Helper.isInBundleLockRegion()) {
1332 I->emitIAS(Func);
1333 // Only update stats during the final pass.
1334 if (Retrying)
1335 updateStats(Func, I);
1336 } else {
1337 // Treat it as though there were an implicit bundle_lock and
1338 // bundle_unlock wrapping the instruction.
1339 Helper.enterBundleLock(I);
1340 I->emitIAS(Func);
1341 Helper.enterBundleUnlock();
1342 Helper.rollback();
1343 Helper.padToNextBundle();
1344 I->emitIAS(Func);
1345 updateStats(Func, I);
1346 Helper.leaveBundleLockRegion();
1347 }
1348 }
1349
Andrew Scull57e12682015-09-16 11:30:19 -07001350 // Don't allow bundle locking across basic blocks, to keep the backtracking
1351 // mechanism simple.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001352 assert(!Helper.isInBundleLockRegion());
1353 assert(!Retrying);
Jan Voung0faec4c2014-11-05 17:29:56 -08001354}
1355
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001356void CfgNode::dump(Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001357 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001358 return;
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001359 Func->setCurrentNode(this);
1360 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001361 Liveness *Liveness = Func->getLiveness();
Andrew Scullaa6c1092015-09-03 17:50:30 -07001362 if (Func->isVerbose(IceV_Instructions) || Func->isVerbose(IceV_Loop))
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001363 Str << getName() << ":\n";
Andrew Scullaa6c1092015-09-03 17:50:30 -07001364 // Dump the loop nest depth
1365 if (Func->isVerbose(IceV_Loop))
1366 Str << " // LoopNestDepth = " << getLoopNestDepth() << "\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001367 // Dump list of predecessor nodes.
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001368 if (Func->isVerbose(IceV_Preds) && !InEdges.empty()) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001369 Str << " // preds = ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001370 bool First = true;
1371 for (CfgNode *I : InEdges) {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001372 if (!First)
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001373 Str << ", ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001374 First = false;
1375 Str << "%" << I->getName();
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001376 }
1377 Str << "\n";
1378 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001379 // Dump the live-in variables.
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001380 if (Func->isVerbose(IceV_Liveness)) {
1381 if (Liveness != nullptr && !Liveness->getLiveIn(this).empty()) {
1382 const LivenessBV &LiveIn = Liveness->getLiveIn(this);
1383 Str << " // LiveIn:";
1384 for (SizeT i = 0; i < LiveIn.size(); ++i) {
1385 if (LiveIn[i]) {
1386 Variable *Var = Liveness->getVariable(i, this);
1387 Str << " %" << Var->getName(Func);
1388 if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
1389 Str << ":"
1390 << Func->getTarget()->getRegName(Var->getRegNum(),
1391 Var->getType());
1392 }
Jim Stichnoth088b2be2014-10-23 12:02:08 -07001393 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001394 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001395 Str << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001396 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001397 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001398 // Dump each instruction.
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001399 if (Func->isVerbose(IceV_Instructions)) {
Jim Stichnoth29841e82014-12-23 12:26:24 -08001400 for (const Inst &I : Phis)
1401 I.dumpDecorated(Func);
1402 for (const Inst &I : Insts)
1403 I.dumpDecorated(Func);
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001404 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001405 // Dump the live-out variables.
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001406 if (Func->isVerbose(IceV_Liveness)) {
1407 if (Liveness != nullptr && !Liveness->getLiveOut(this).empty()) {
1408 const LivenessBV &LiveOut = Liveness->getLiveOut(this);
1409 Str << " // LiveOut:";
1410 for (SizeT i = 0; i < LiveOut.size(); ++i) {
1411 if (LiveOut[i]) {
1412 Variable *Var = Liveness->getVariable(i, this);
1413 Str << " %" << Var->getName(Func);
1414 if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
1415 Str << ":"
1416 << Func->getTarget()->getRegName(Var->getRegNum(),
1417 Var->getType());
1418 }
Jim Stichnoth088b2be2014-10-23 12:02:08 -07001419 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001420 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001421 Str << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001422 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001423 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001424 // Dump list of successor nodes.
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001425 if (Func->isVerbose(IceV_Succs)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001426 Str << " // succs = ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001427 bool First = true;
1428 for (CfgNode *I : OutEdges) {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001429 if (!First)
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001430 Str << ", ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001431 First = false;
1432 Str << "%" << I->getName();
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001433 }
1434 Str << "\n";
1435 }
1436}
1437
John Portof8b4cc82015-06-09 18:06:19 -07001438void CfgNode::profileExecutionCount(VariableDeclaration *Var) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001439 GlobalContext *Ctx = Func->getContext();
1440 GlobalString RMW_I64 = Ctx->getGlobalString("llvm.nacl.atomic.rmw.i64");
John Portof8b4cc82015-06-09 18:06:19 -07001441
1442 bool BadIntrinsic = false;
1443 const Intrinsics::FullIntrinsicInfo *Info =
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001444 Ctx->getIntrinsicsInfo().find(RMW_I64, BadIntrinsic);
John Portof8b4cc82015-06-09 18:06:19 -07001445 assert(!BadIntrinsic);
1446 assert(Info != nullptr);
1447
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001448 Operand *RMWI64Name = Ctx->getConstantExternSym(RMW_I64);
John Porto8b1a7052015-06-17 13:20:08 -07001449 constexpr RelocOffsetT Offset = 0;
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001450 Constant *Counter = Ctx->getConstantSym(Offset, Var->getName());
1451 Constant *AtomicRMWOp = Ctx->getConstantInt32(Intrinsics::AtomicAdd);
1452 Constant *One = Ctx->getConstantInt64(1);
John Portof8b4cc82015-06-09 18:06:19 -07001453 Constant *OrderAcquireRelease =
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001454 Ctx->getConstantInt32(Intrinsics::MemoryOrderAcquireRelease);
John Portof8b4cc82015-06-09 18:06:19 -07001455
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001456 auto *Instr = InstIntrinsicCall::create(
John Portof8b4cc82015-06-09 18:06:19 -07001457 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info);
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001458 Instr->addArg(AtomicRMWOp);
1459 Instr->addArg(Counter);
1460 Instr->addArg(One);
1461 Instr->addArg(OrderAcquireRelease);
1462 Insts.push_front(Instr);
John Portof8b4cc82015-06-09 18:06:19 -07001463}
1464
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001465} // end of namespace Ice