blob: 6cadcf65ec63f87139fc9c373caa748aa84b697a [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 Stichnoth668a7a32014-12-10 15:32:25 -080029CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber)
Jim Stichnothe7dbc0b2015-09-15 10:09:24 -070030 : Func(Func), Number(LabelNumber), LabelNumber(LabelNumber) {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070031
Andrew Scull57e12682015-09-16 11:30:19 -070032// Returns the name the node was created with. If no name was given, it
33// synthesizes a (hopefully) unique name.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070034IceString CfgNode::getName() const {
Jim Stichnoth668a7a32014-12-10 15:32:25 -080035 if (NameIndex >= 0)
Jim Stichnoth9a04c072014-12-11 15:51:42 -080036 return Func->getIdentifierName(NameIndex);
Jim Stichnothe7dbc0b2015-09-15 10:09:24 -070037 return "__" + std::to_string(LabelNumber);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070038}
39
Andrew Scull57e12682015-09-16 11:30:19 -070040// Adds an instruction to either the Phi list or the regular instruction list.
41// Validates that all Phis are added before all regular instructions.
Jim Stichnoth8cfeb692016-02-05 09:50:02 -080042void CfgNode::appendInst(Inst *Instr) {
Jim Stichnoth47752552014-10-13 17:15:08 -070043 ++InstCountEstimate;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -080044 if (auto *Phi = llvm::dyn_cast<InstPhi>(Instr)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -070045 if (!Insts.empty()) {
46 Func->setError("Phi instruction added to the middle of a block");
47 return;
48 }
49 Phis.push_back(Phi);
50 } else {
Jim Stichnoth8cfeb692016-02-05 09:50:02 -080051 Insts.push_back(Instr);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070052 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070053}
54
Andrew Scull57e12682015-09-16 11:30:19 -070055// Renumbers the non-deleted instructions in the node. This needs to be done in
56// preparation for live range analysis. The instruction numbers in a block must
57// be monotonically increasing. The range of instruction numbers in a block,
58// from lowest to highest, must not overlap with the range of any other block.
Jim Stichnothd97c7df2014-06-04 11:57:08 -070059void CfgNode::renumberInstructions() {
Jim Stichnoth47752552014-10-13 17:15:08 -070060 InstNumberT FirstNumber = Func->getNextInstNumber();
Jim Stichnoth29841e82014-12-23 12:26:24 -080061 for (Inst &I : Phis)
62 I.renumber(Func);
63 for (Inst &I : Insts)
64 I.renumber(Func);
Jim Stichnoth47752552014-10-13 17:15:08 -070065 InstCountEstimate = Func->getNextInstNumber() - FirstNumber;
Jim Stichnothd97c7df2014-06-04 11:57:08 -070066}
67
Andrew Scull57e12682015-09-16 11:30:19 -070068// When a node is created, the OutEdges are immediately known, but the InEdges
69// have to be built up incrementally. After the CFG has been constructed, the
70// computePredecessors() pass finalizes it by creating the InEdges list.
Jim Stichnothf7c9a142014-04-29 10:52:43 -070071void CfgNode::computePredecessors() {
Jim Stichnothf44f3712014-10-01 14:05:51 -070072 for (CfgNode *Succ : OutEdges)
73 Succ->InEdges.push_back(this);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070074}
75
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -070076void CfgNode::computeSuccessors() {
77 OutEdges = Insts.rbegin()->getTerminatorEdges();
78}
79
Andrew Scull57e12682015-09-16 11:30:19 -070080// Validate each Phi instruction in the node with respect to control flow. For
81// every phi argument, its label must appear in the predecessor list. For each
82// predecessor, there must be a phi argument with that label. We don't check
Jim Stichnoth1aca2302015-09-16 11:25:22 -070083// that phi arguments with the same label have the same value.
84void CfgNode::validatePhis() {
85 for (Inst &Instr : Phis) {
86 auto *Phi = llvm::cast<InstPhi>(&Instr);
Andrew Scull57e12682015-09-16 11:30:19 -070087 // We do a simple O(N^2) algorithm to check for consistency. Even so, it
88 // shows up as only about 0.2% of the total translation time. But if
89 // necessary, we could improve the complexity by using a hash table to
90 // count how many times each node is referenced in the Phi instruction, and
91 // how many times each node is referenced in the incoming edge list, and
92 // compare the two for equality.
Jim Stichnoth1aca2302015-09-16 11:25:22 -070093 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) {
94 CfgNode *Label = Phi->getLabel(i);
95 bool Found = false;
96 for (CfgNode *InNode : getInEdges()) {
97 if (InNode == Label) {
98 Found = true;
99 break;
100 }
101 }
102 if (!Found)
103 llvm::report_fatal_error("Phi error: label for bad incoming edge");
104 }
105 for (CfgNode *InNode : getInEdges()) {
106 bool Found = false;
107 for (SizeT i = 0; i < Phi->getSrcSize(); ++i) {
108 CfgNode *Label = Phi->getLabel(i);
109 if (InNode == Label) {
110 Found = true;
111 break;
112 }
113 }
114 if (!Found)
115 llvm::report_fatal_error("Phi error: missing label for incoming edge");
116 }
117 }
118}
119
Andrew Scull57e12682015-09-16 11:30:19 -0700120// This does part 1 of Phi lowering, by creating a new dest variable for each
121// Phi instruction, replacing the Phi instruction's dest with that variable,
122// and adding an explicit assignment of the old dest to the new dest. For
123// example,
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700124// a=phi(...)
125// changes to
126// "a_phi=phi(...); a=a_phi".
127//
Andrew Scull57e12682015-09-16 11:30:19 -0700128// This is in preparation for part 2 which deletes the Phi instructions and
129// appends assignment instructions to predecessor blocks. Note that this
130// transformation preserves SSA form.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700131void CfgNode::placePhiLoads() {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800132 for (Inst &I : Phis) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700133 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Jim Stichnoth1502e592014-12-11 09:22:45 -0800134 Insts.insert(Insts.begin(), Phi->lower(Func));
135 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700136}
137
Andrew Scull57e12682015-09-16 11:30:19 -0700138// This does part 2 of Phi lowering. For each Phi instruction at each out-edge,
139// create a corresponding assignment instruction, and add all the assignments
140// near the end of this block. They need to be added before any branch
141// instruction, and also if the block ends with a compare instruction followed
142// by a branch instruction that we may want to fuse, it's better to insert the
143// new assignments before the compare instruction. The
144// tryOptimizedCmpxchgCmpBr() method assumes this ordering of instructions.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700145//
Andrew Scull57e12682015-09-16 11:30:19 -0700146// Note that this transformation takes the Phi dest variables out of SSA form,
147// as there may be assignments to the dest variable in multiple blocks.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700148void CfgNode::placePhiStores() {
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700149 // Find the insertion point.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700150 InstList::iterator InsertionPoint = Insts.end();
Andrew Scull57e12682015-09-16 11:30:19 -0700151 // Every block must end in a terminator instruction, and therefore must have
152 // at least one instruction, so it's valid to decrement InsertionPoint (but
153 // assert just in case).
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700154 assert(InsertionPoint != Insts.begin());
155 --InsertionPoint;
Andrew Scull57e12682015-09-16 11:30:19 -0700156 // Confirm that InsertionPoint is a terminator instruction. Calling
157 // getTerminatorEdges() on a non-terminator instruction will cause an
158 // llvm_unreachable().
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800159 (void)InsertionPoint->getTerminatorEdges();
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700160 // SafeInsertionPoint is always immediately before the terminator
Andrew Scull57e12682015-09-16 11:30:19 -0700161 // instruction. If the block ends in a compare and conditional branch, it's
162 // better to place the Phi store before the compare so as not to interfere
163 // with compare/branch fusing. However, if the compare instruction's dest
164 // operand is the same as the new assignment statement's source operand, this
165 // can't be done due to data dependences, so we need to fall back to the
166 // SafeInsertionPoint. To illustrate:
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700167 // ; <label>:95
168 // %97 = load i8* %96, align 1
169 // %98 = icmp ne i8 %97, 0
170 // br i1 %98, label %99, label %2132
171 // ; <label>:99
172 // %100 = phi i8 [ %97, %95 ], [ %110, %108 ]
173 // %101 = phi i1 [ %98, %95 ], [ %111, %108 ]
174 // would be Phi-lowered as:
175 // ; <label>:95
176 // %97 = load i8* %96, align 1
177 // %100_phi = %97 ; can be at InsertionPoint
178 // %98 = icmp ne i8 %97, 0
179 // %101_phi = %98 ; must be at SafeInsertionPoint
180 // br i1 %98, label %99, label %2132
181 // ; <label>:99
182 // %100 = %100_phi
183 // %101 = %101_phi
184 //
Andrew Scull57e12682015-09-16 11:30:19 -0700185 // TODO(stichnot): It may be possible to bypass this whole SafeInsertionPoint
186 // mechanism. If a source basic block ends in a conditional branch:
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700187 // labelSource:
188 // ...
189 // br i1 %foo, label %labelTrue, label %labelFalse
190 // and a branch target has a Phi involving the branch operand:
191 // labelTrue:
192 // %bar = phi i1 [ %foo, %labelSource ], ...
193 // then we actually know the constant i1 value of the Phi operand:
194 // labelTrue:
195 // %bar = phi i1 [ true, %labelSource ], ...
Andrew Scull57e12682015-09-16 11:30:19 -0700196 // It seems that this optimization should be done by clang or opt, but we
197 // could also do it here.
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700198 InstList::iterator SafeInsertionPoint = InsertionPoint;
Andrew Scull57e12682015-09-16 11:30:19 -0700199 // Keep track of the dest variable of a compare instruction, so that we
200 // insert the new instruction at the SafeInsertionPoint if the compare's dest
201 // matches the Phi-lowered assignment's source.
Jim Stichnothae953202014-12-20 06:17:49 -0800202 Variable *CmpInstDest = nullptr;
Andrew Scull57e12682015-09-16 11:30:19 -0700203 // If the current insertion point is at a conditional branch instruction, and
204 // the previous instruction is a compare instruction, then we move the
205 // insertion point before the compare instruction so as not to interfere with
206 // compare/branch fusing.
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800207 if (auto *Branch = llvm::dyn_cast<InstBr>(InsertionPoint)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700208 if (!Branch->isUnconditional()) {
209 if (InsertionPoint != Insts.begin()) {
210 --InsertionPoint;
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800211 if (llvm::isa<InstIcmp>(InsertionPoint) ||
212 llvm::isa<InstFcmp>(InsertionPoint)) {
213 CmpInstDest = InsertionPoint->getDest();
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700214 } else {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700215 ++InsertionPoint;
216 }
217 }
218 }
219 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700220
221 // Consider every out-edge.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700222 for (CfgNode *Succ : OutEdges) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700223 // Consider every Phi instruction at the out-edge.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800224 for (Inst &I : Succ->Phis) {
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700225 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
Jim Stichnoth1502e592014-12-11 09:22:45 -0800226 Operand *Operand = Phi->getOperandForTarget(this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700227 assert(Operand);
Jim Stichnoth29841e82014-12-23 12:26:24 -0800228 Variable *Dest = I.getDest();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700229 assert(Dest);
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800230 auto *NewInst = InstAssign::create(Func, Dest, Operand);
Jim Stichnothe5a5be72014-09-10 11:51:38 -0700231 if (CmpInstDest == Operand)
232 Insts.insert(SafeInsertionPoint, NewInst);
233 else
234 Insts.insert(InsertionPoint, NewInst);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700235 }
236 }
237}
238
239// Deletes the phi instructions after the loads and stores are placed.
240void CfgNode::deletePhis() {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800241 for (Inst &I : Phis)
242 I.setDeleted();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700243}
244
Andrew Scull57e12682015-09-16 11:30:19 -0700245// Splits the edge from Pred to this node by creating a new node and hooking up
246// the in and out edges appropriately. (The EdgeIndex parameter is only used to
247// make the new node's name unique when there are multiple edges between the
248// same pair of nodes.) The new node's instruction list is initialized to the
249// empty list, with no terminator instruction. There must not be multiple edges
250// from Pred to this node so all Inst::getTerminatorEdges implementations must
Andrew Scull87f80c12015-07-20 10:19:16 -0700251// not contain duplicates.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700252CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) {
Jim Stichnoth668a7a32014-12-10 15:32:25 -0800253 CfgNode *NewNode = Func->makeNode();
Andrew Scullaa6c1092015-09-03 17:50:30 -0700254 // Depth is the minimum as it works if both are the same, but if one is
255 // outside the loop and the other is inside, the new node should be placed
256 // outside and not be executed multiple times within the loop.
257 NewNode->setLoopNestDepth(
258 std::min(getLoopNestDepth(), Pred->getLoopNestDepth()));
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700259 if (BuildDefs::dump())
Jim Stichnoth668a7a32014-12-10 15:32:25 -0800260 NewNode->setName("split_" + Pred->getName() + "_" + getName() + "_" +
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700261 std::to_string(EdgeIndex));
Andrew Scull57e12682015-09-16 11:30:19 -0700262 // The new node is added to the end of the node list, and will later need to
263 // be sorted into a reasonable topological order.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700264 NewNode->setNeedsPlacement(true);
265 // Repoint Pred's out-edge.
266 bool Found = false;
Andrew Scull87f80c12015-07-20 10:19:16 -0700267 for (CfgNode *&I : Pred->OutEdges) {
268 if (I == this) {
269 I = NewNode;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700270 NewNode->InEdges.push_back(Pred);
271 Found = true;
Andrew Scull87f80c12015-07-20 10:19:16 -0700272 break;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700273 }
274 }
275 assert(Found);
Jim Stichnotha8d47132015-09-08 14:43:38 -0700276 (void)Found;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700277 // Repoint this node's in-edge.
278 Found = false;
Andrew Scull87f80c12015-07-20 10:19:16 -0700279 for (CfgNode *&I : InEdges) {
280 if (I == Pred) {
281 I = NewNode;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700282 NewNode->OutEdges.push_back(this);
283 Found = true;
Andrew Scull87f80c12015-07-20 10:19:16 -0700284 break;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700285 }
286 }
287 assert(Found);
Jim Stichnotha8d47132015-09-08 14:43:38 -0700288 (void)Found;
Andrew Scull87f80c12015-07-20 10:19:16 -0700289 // Repoint all suitable branch instructions' target and return.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700290 Found = false;
Andrew Scull87f80c12015-07-20 10:19:16 -0700291 for (Inst &I : Pred->getInsts())
292 if (!I.isDeleted() && I.repointEdges(this, NewNode))
293 Found = true;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700294 assert(Found);
Jim Stichnotha8d47132015-09-08 14:43:38 -0700295 (void)Found;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700296 return NewNode;
297}
298
299namespace {
300
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800301// Helpers for advancedPhiLowering().
302
303class PhiDesc {
304 PhiDesc() = delete;
305 PhiDesc(const PhiDesc &) = delete;
306 PhiDesc &operator=(const PhiDesc &) = delete;
Jim Stichnothc59288b2015-11-09 11:38:40 -0800307
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800308public:
309 PhiDesc(InstPhi *Phi, Variable *Dest) : Phi(Phi), Dest(Dest) {}
310 PhiDesc(PhiDesc &&) = default;
311 InstPhi *Phi = nullptr;
312 Variable *Dest = nullptr;
313 Operand *Src = nullptr;
314 bool Processed = false;
315 size_t NumPred = 0; // number of entries whose Src is this Dest
316 int32_t Weight = 0; // preference for topological order
317};
318using PhiDescList = llvm::SmallVector<PhiDesc, 32>;
319
320// Always pick NumPred=0 over NumPred>0.
321constexpr int32_t WeightNoPreds = 4;
322// Prefer Src as a register because the register might free up.
323constexpr int32_t WeightSrcIsReg = 2;
324// Prefer Dest not as a register because the register stays free longer.
325constexpr int32_t WeightDestNotReg = 1;
326
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700327bool sameVarOrReg(TargetLowering *Target, const Variable *Var1,
328 const Operand *Opnd) {
329 if (Var1 == Opnd)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700330 return true;
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700331 const auto *Var2 = llvm::dyn_cast<Variable>(Opnd);
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700332 if (Var2 == nullptr)
333 return false;
334
335 // If either operand lacks a register, they cannot be the same.
336 if (!Var1->hasReg())
337 return false;
338 if (!Var2->hasReg())
339 return false;
340
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800341 const auto RegNum1 = Var1->getRegNum();
342 const auto RegNum2 = Var2->getRegNum();
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700343 // Quick common-case check.
344 if (RegNum1 == RegNum2)
345 return true;
346
347 assert(Target->getAliasesForRegister(RegNum1)[RegNum2] ==
348 Target->getAliasesForRegister(RegNum2)[RegNum1]);
349 return Target->getAliasesForRegister(RegNum1)[RegNum2];
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700350}
351
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800352// Update NumPred for all Phi assignments using Var as their Dest variable.
353// Also update Weight if NumPred dropped from 1 to 0.
354void updatePreds(PhiDescList &Desc, TargetLowering *Target, Variable *Var) {
355 for (PhiDesc &Item : Desc) {
356 if (!Item.Processed && sameVarOrReg(Target, Var, Item.Dest)) {
357 if (--Item.NumPred == 0) {
358 Item.Weight += WeightNoPreds;
359 }
360 }
361 }
362}
363
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700364} // end of anonymous namespace
365
Andrew Scull57e12682015-09-16 11:30:19 -0700366// This the "advanced" version of Phi lowering for a basic block, in contrast
367// to the simple version that lowers through assignments involving temporaries.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700368//
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700369// All Phi instructions in a basic block are conceptually executed in parallel.
370// However, if we lower Phis early and commit to a sequential ordering, we may
371// end up creating unnecessary interferences which lead to worse register
Andrew Scull57e12682015-09-16 11:30:19 -0700372// allocation. Delaying Phi scheduling until after register allocation can help
373// unless there are no free registers for shuffling registers or stack slots
374// and spilling becomes necessary.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700375//
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700376// The advanced Phi lowering starts by finding a topological sort of the Phi
Andrew Scull57e12682015-09-16 11:30:19 -0700377// instructions, where "A=B" comes before "B=C" due to the anti-dependence on
378// B. Preexisting register assignments are considered in the topological sort.
379// If a topological sort is not possible due to a cycle, the cycle is broken by
380// introducing a non-parallel temporary. For example, a cycle arising from a
381// 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 -0700382// equal, prefer to schedule assignments with register-allocated Src operands
383// earlier, in case that register becomes free afterwards, and prefer to
384// schedule assignments with register-allocated Dest variables later, to keep
385// that register free for longer.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700386//
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700387// Once the ordering is determined, the Cfg edge is split and the assignment
Andrew Scull57e12682015-09-16 11:30:19 -0700388// list is lowered by the target lowering layer. Since the assignment lowering
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700389// may create new infinite-weight temporaries, a follow-on register allocation
Andrew Scull57e12682015-09-16 11:30:19 -0700390// pass will be needed. To prepare for this, liveness (including live range
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700391// calculation) of the split nodes needs to be calculated, and liveness of the
392// original node need to be updated to "undo" the effects of the phi
393// assignments.
394
395// The specific placement of the new node within the Cfg node list is deferred
396// until later, including after empty node contraction.
397//
398// After phi assignments are lowered across all blocks, another register
399// allocation pass is run, focusing only on pre-colored and infinite-weight
400// variables, similar to Om1 register allocation (except without the need to
401// specially compute these variables' live ranges, since they have already been
Andrew Scull57e12682015-09-16 11:30:19 -0700402// precisely calculated). The register allocator in this mode needs the ability
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700403// to forcibly spill and reload registers in case none are naturally available.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700404void CfgNode::advancedPhiLowering() {
405 if (getPhis().empty())
406 return;
407
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800408 PhiDescList Desc;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700409
Jim Stichnoth29841e82014-12-23 12:26:24 -0800410 for (Inst &I : Phis) {
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800411 auto *Phi = llvm::dyn_cast<InstPhi>(&I);
412 if (!Phi->isDeleted()) {
413 Variable *Dest = Phi->getDest();
414 Desc.emplace_back(Phi, Dest);
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700415 // Undo the effect of the phi instruction on this node's live-in set by
416 // marking the phi dest variable as live on entry.
417 SizeT VarNum = Func->getLiveness()->getLiveIndex(Dest->getIndex());
418 assert(!Func->getLiveness()->getLiveIn(this)[VarNum]);
419 Func->getLiveness()->getLiveIn(this)[VarNum] = true;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800420 Phi->setDeleted();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700421 }
422 }
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800423 if (Desc.empty())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700424 return;
425
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700426 TargetLowering *Target = Func->getTarget();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700427 SizeT InEdgeIndex = 0;
428 for (CfgNode *Pred : InEdges) {
429 CfgNode *Split = splitIncomingEdge(Pred, InEdgeIndex++);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800430 SizeT Remaining = Desc.size();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700431
432 // First pass computes Src and initializes NumPred.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800433 for (PhiDesc &Item : Desc) {
434 Variable *Dest = Item.Dest;
435 Operand *Src = Item.Phi->getOperandForTarget(Pred);
436 Item.Src = Src;
437 Item.Processed = false;
438 Item.NumPred = 0;
Andrew Scull57e12682015-09-16 11:30:19 -0700439 // Cherry-pick any trivial assignments, so that they don't contribute to
440 // the running complexity of the topological sort.
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700441 if (sameVarOrReg(Target, Dest, Src)) {
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800442 Item.Processed = true;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700443 --Remaining;
444 if (Dest != Src)
Andrew Scull57e12682015-09-16 11:30:19 -0700445 // If Dest and Src are syntactically the same, don't bother adding
446 // the assignment, because in all respects it would be redundant, and
447 // if Dest/Src are on the stack, the target lowering may naively
448 // decide to lower it using a temporary register.
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700449 Split->appendInst(InstAssign::create(Func, Dest, Src));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700450 }
451 }
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800452 // Second pass computes NumPred by comparing every pair of Phi instructions.
453 for (PhiDesc &Item : Desc) {
454 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700455 continue;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800456 const Variable *Dest = Item.Dest;
457 for (PhiDesc &Item2 : Desc) {
458 if (Item2.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700459 continue;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800460 // There shouldn't be two different Phis with the same Dest variable or
Jim Stichnothc59288b2015-11-09 11:38:40 -0800461 // register.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800462 assert((&Item == &Item2) || !sameVarOrReg(Target, Dest, Item2.Dest));
463 if (sameVarOrReg(Target, Dest, Item2.Src))
464 ++Item.NumPred;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700465 }
466 }
467
468 // Another pass to compute initial Weight values.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800469 for (PhiDesc &Item : Desc) {
470 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700471 continue;
472 int32_t Weight = 0;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800473 if (Item.NumPred == 0)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700474 Weight += WeightNoPreds;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800475 if (auto *Var = llvm::dyn_cast<Variable>(Item.Src))
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700476 if (Var->hasReg())
477 Weight += WeightSrcIsReg;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800478 if (!Item.Dest->hasReg())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700479 Weight += WeightDestNotReg;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800480 Item.Weight = Weight;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700481 }
482
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800483 // Repeatedly choose and process the best candidate in the topological sort,
484 // until no candidates remain. This implementation is O(N^2) where N is the
485 // number of Phi instructions, but with a small constant factor compared to
486 // a likely implementation of O(N) topological sort.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700487 for (; Remaining; --Remaining) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700488 int32_t BestWeight = -1;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800489 PhiDesc *BestItem = nullptr;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700490 // Find the best candidate.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800491 for (PhiDesc &Item : Desc) {
492 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700493 continue;
494 int32_t Weight = 0;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800495 Weight = Item.Weight;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700496 if (Weight > BestWeight) {
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800497 BestItem = &Item;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700498 BestWeight = Weight;
499 }
500 }
501 assert(BestWeight >= 0);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800502 assert(BestItem->NumPred <= 1);
503 Variable *Dest = BestItem->Dest;
504 Operand *Src = BestItem->Src;
Jim Stichnoth1fb030c2015-10-15 11:10:38 -0700505 assert(!sameVarOrReg(Target, Dest, Src));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700506 // Break a cycle by introducing a temporary.
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800507 if (BestItem->NumPred) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700508 bool Found = false;
Andrew Scull57e12682015-09-16 11:30:19 -0700509 // If the target instruction "A=B" is part of a cycle, find the "X=A"
510 // assignment in the cycle because it will have to be rewritten as
511 // "X=tmp".
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800512 for (PhiDesc &Item : Desc) {
513 if (Item.Processed)
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700514 continue;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800515 Operand *OtherSrc = Item.Src;
516 if (Item.NumPred && sameVarOrReg(Target, Dest, OtherSrc)) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700517 SizeT VarNum = Func->getNumVariables();
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800518 Variable *Tmp = Func->makeVariable(OtherSrc->getType());
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700519 if (BuildDefs::dump())
Jim Stichnoth9a04c072014-12-11 15:51:42 -0800520 Tmp->setName(Func, "__split_" + std::to_string(VarNum));
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700521 Split->appendInst(InstAssign::create(Func, Tmp, OtherSrc));
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800522 Item.Src = Tmp;
523 updatePreds(Desc, Target, llvm::cast<Variable>(OtherSrc));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700524 Found = true;
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800525 break;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700526 }
527 }
528 assert(Found);
Jim Stichnothb0051df2016-01-13 11:39:15 -0800529 (void)Found;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700530 }
531 // Now that a cycle (if any) has been broken, create the actual
532 // assignment.
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700533 Split->appendInst(InstAssign::create(Func, Dest, Src));
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800534 if (auto *Var = llvm::dyn_cast<Variable>(Src))
535 updatePreds(Desc, Target, Var);
536 BestItem->Processed = true;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700537 }
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700538 Split->appendInst(InstBr::create(Func, this));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700539
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700540 Split->genCode();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700541 Func->getVMetadata()->addNode(Split);
Jim Stichnothea15bbe2015-11-09 11:19:11 -0800542 // Validate to be safe. All items should be marked as processed, and have
543 // no predecessors.
544 if (BuildDefs::asserts()) {
545 for (PhiDesc &Item : Desc) {
546 (void)Item;
547 assert(Item.Processed);
548 assert(Item.NumPred == 0);
549 }
550 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700551 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700552}
553
Andrew Scull57e12682015-09-16 11:30:19 -0700554// Does address mode optimization. Pass each instruction to the TargetLowering
555// object. If it returns a new instruction (representing the optimized address
556// mode), then insert the new instruction and delete the old.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700557void CfgNode::doAddressOpt() {
558 TargetLowering *Target = Func->getTarget();
559 LoweringContext &Context = Target->getContext();
560 Context.init(this);
561 while (!Context.atEnd()) {
562 Target->doAddressOpt();
563 }
564}
565
Qining Luaee5fa82015-08-20 14:59:03 -0700566void CfgNode::doNopInsertion(RandomNumberGenerator &RNG) {
Matt Walac3302742014-08-15 16:21:56 -0700567 TargetLowering *Target = Func->getTarget();
568 LoweringContext &Context = Target->getContext();
569 Context.init(this);
Qining Lu969f6a32015-07-31 09:58:34 -0700570 Context.setInsertPoint(Context.getCur());
571 // Do not insert nop in bundle locked instructions.
572 bool PauseNopInsertion = false;
Matt Walac3302742014-08-15 16:21:56 -0700573 while (!Context.atEnd()) {
Qining Lu969f6a32015-07-31 09:58:34 -0700574 if (llvm::isa<InstBundleLock>(Context.getCur())) {
575 PauseNopInsertion = true;
576 } else if (llvm::isa<InstBundleUnlock>(Context.getCur())) {
577 PauseNopInsertion = false;
578 }
579 if (!PauseNopInsertion)
Qining Luaee5fa82015-08-20 14:59:03 -0700580 Target->doNopInsertion(RNG);
Matt Walac3302742014-08-15 16:21:56 -0700581 // Ensure Cur=Next, so that the nops are inserted before the current
582 // instruction rather than after.
Matt Walac3302742014-08-15 16:21:56 -0700583 Context.advanceCur();
Qining Lu969f6a32015-07-31 09:58:34 -0700584 Context.advanceNext();
Matt Walac3302742014-08-15 16:21:56 -0700585 }
Matt Walac3302742014-08-15 16:21:56 -0700586}
587
Andrew Scull57e12682015-09-16 11:30:19 -0700588// Drives the target lowering. Passes the current instruction and the next
589// non-deleted instruction for target lowering.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700590void CfgNode::genCode() {
591 TargetLowering *Target = Func->getTarget();
592 LoweringContext &Context = Target->getContext();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700593 // Lower the regular instructions.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700594 Context.init(this);
Jim Stichnotha59ae6f2015-05-17 10:11:41 -0700595 Target->initNodeForLowering(this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700596 while (!Context.atEnd()) {
597 InstList::iterator Orig = Context.getCur();
598 if (llvm::isa<InstRet>(*Orig))
599 setHasReturn();
600 Target->lower();
601 // Ensure target lowering actually moved the cursor.
602 assert(Context.getCur() != Orig);
603 }
Jim Stichnoth318f4cd2015-10-01 21:02:37 -0700604 Context.availabilityReset();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700605 // Do preliminary lowering of the Phi instructions.
606 Target->prelowerPhis();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700607}
608
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700609void CfgNode::livenessLightweight() {
610 SizeT NumVars = Func->getNumVariables();
Jim Stichnoth47752552014-10-13 17:15:08 -0700611 LivenessBV Live(NumVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700612 // Process regular instructions in reverse order.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800613 for (Inst &I : reverse_range(Insts)) {
614 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700615 continue;
Jim Stichnoth7e571362015-01-09 11:43:26 -0800616 I.livenessLightweight(Func, Live);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700617 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800618 for (Inst &I : Phis) {
619 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700620 continue;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800621 I.livenessLightweight(Func, Live);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700622 }
623}
624
Andrew Scull57e12682015-09-16 11:30:19 -0700625// Performs liveness analysis on the block. Returns true if the incoming
626// liveness changed from before, false if it stayed the same. (If it changes,
627// the node's predecessors need to be processed again.)
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700628bool CfgNode::liveness(Liveness *Liveness) {
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800629 const SizeT NumVars = Liveness->getNumVarsInNode(this);
630 const SizeT NumGlobalVars = Liveness->getNumGlobalVars();
631 LivenessBV &Live = Liveness->getScratchBV();
632 Live.clear();
633
Jim Stichnothae953202014-12-20 06:17:49 -0800634 LiveBeginEndMap *LiveBegin = nullptr;
635 LiveBeginEndMap *LiveEnd = nullptr;
Andrew Scull57e12682015-09-16 11:30:19 -0700636 // Mark the beginning and ending of each variable's live range with the
637 // sentinel instruction number 0.
Jim Stichnoth47752552014-10-13 17:15:08 -0700638 if (Liveness->getMode() == Liveness_Intervals) {
639 LiveBegin = Liveness->getLiveBegin(this);
640 LiveEnd = Liveness->getLiveEnd(this);
641 LiveBegin->clear();
642 LiveEnd->clear();
Andrew Scull57e12682015-09-16 11:30:19 -0700643 // Guess that the number of live ranges beginning is roughly the number of
644 // instructions, and same for live ranges ending.
Jim Stichnoth47752552014-10-13 17:15:08 -0700645 LiveBegin->reserve(getInstCountEstimate());
646 LiveEnd->reserve(getInstCountEstimate());
647 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800648
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700649 // Initialize Live to be the union of all successors' LiveIn.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700650 for (CfgNode *Succ : OutEdges) {
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800651 const LivenessBV &LiveIn = Liveness->getLiveIn(Succ);
652 assert(LiveIn.empty() || LiveIn.size() == NumGlobalVars);
653 Live |= LiveIn;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700654 // Mark corresponding argument of phis in successor as live.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800655 for (Inst &I : Succ->Phis) {
Jim Stichnoth552490c2015-08-05 16:21:42 -0700656 if (I.isDeleted())
657 continue;
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800658 auto *Phi = llvm::cast<InstPhi>(&I);
Jim Stichnoth1502e592014-12-11 09:22:45 -0800659 Phi->livenessPhiOperand(Live, this, Liveness);
660 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700661 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800662 assert(Live.empty() || Live.size() == NumGlobalVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700663 Liveness->getLiveOut(this) = Live;
664
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800665 // Expand Live so it can hold locals in addition to globals.
666 Live.resize(NumVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700667 // Process regular instructions in reverse order.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800668 for (Inst &I : reverse_range(Insts)) {
669 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700670 continue;
Jim Stichnoth7e571362015-01-09 11:43:26 -0800671 I.liveness(I.getNumber(), Live, Liveness, LiveBegin, LiveEnd);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700672 }
Andrew Scull57e12682015-09-16 11:30:19 -0700673 // Process phis in forward order so that we can override the instruction
674 // number to be that of the earliest phi instruction in the block.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700675 SizeT NumNonDeadPhis = 0;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700676 InstNumberT FirstPhiNumber = Inst::NumberSentinel;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800677 for (Inst &I : Phis) {
678 if (I.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700679 continue;
680 if (FirstPhiNumber == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800681 FirstPhiNumber = I.getNumber();
682 if (I.liveness(FirstPhiNumber, Live, Liveness, LiveBegin, LiveEnd))
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700683 ++NumNonDeadPhis;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700684 }
685
Andrew Scull57e12682015-09-16 11:30:19 -0700686 // When using the sparse representation, after traversing the instructions in
687 // the block, the Live bitvector should only contain set bits for global
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800688 // variables upon block entry. We validate this by testing the upper bits of
689 // the Live bitvector.
690 if (Live.find_next(NumGlobalVars) != -1) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700691 if (BuildDefs::dump()) {
Andrew Scull57e12682015-09-16 11:30:19 -0700692 // This is a fatal liveness consistency error. Print some diagnostics and
693 // abort.
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700694 Ostream &Str = Func->getContext()->getStrDump();
695 Func->resetCurrentNode();
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800696 Str << "Invalid Live =";
697 for (SizeT i = NumGlobalVars; i < Live.size(); ++i) {
698 if (Live.test(i)) {
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700699 Str << " ";
700 Liveness->getVariable(i, this)->dump(Func);
701 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700702 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700703 Str << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700704 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700705 llvm::report_fatal_error("Fatal inconsistency in liveness analysis");
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700706 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800707 // Now truncate Live to prevent LiveIn from growing.
708 Live.resize(NumGlobalVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700709
710 bool Changed = false;
Jim Stichnoth47752552014-10-13 17:15:08 -0700711 LivenessBV &LiveIn = Liveness->getLiveIn(this);
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800712 assert(LiveIn.empty() || LiveIn.size() == NumGlobalVars);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700713 // Add in current LiveIn
714 Live |= LiveIn;
715 // Check result, set LiveIn=Live
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700716 SizeT &PrevNumNonDeadPhis = Liveness->getNumNonDeadPhis(this);
717 bool LiveInChanged = (Live != LiveIn);
718 Changed = (NumNonDeadPhis != PrevNumNonDeadPhis || LiveInChanged);
719 if (LiveInChanged)
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700720 LiveIn = Live;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700721 PrevNumNonDeadPhis = NumNonDeadPhis;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700722 return Changed;
723}
724
Jim Stichnoth230d4102015-09-25 17:40:32 -0700725// Validate the integrity of the live ranges in this block. If there are any
726// errors, it prints details and returns false. On success, it returns true.
Jim Stichnoth318f4cd2015-10-01 21:02:37 -0700727bool CfgNode::livenessValidateIntervals(Liveness *Liveness) const {
Jim Stichnoth230d4102015-09-25 17:40:32 -0700728 if (!BuildDefs::asserts())
729 return true;
730
731 // Verify there are no duplicates.
732 auto ComparePair =
733 [](const LiveBeginEndMapEntry &A, const LiveBeginEndMapEntry &B) {
734 return A.first == B.first;
735 };
736 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this);
737 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this);
738 if (std::adjacent_find(MapBegin.begin(), MapBegin.end(), ComparePair) ==
739 MapBegin.end() &&
740 std::adjacent_find(MapEnd.begin(), MapEnd.end(), ComparePair) ==
741 MapEnd.end())
742 return true;
743
744 // There is definitely a liveness error. All paths from here return false.
745 if (!BuildDefs::dump())
746 return false;
747
748 // Print all the errors.
749 if (BuildDefs::dump()) {
750 GlobalContext *Ctx = Func->getContext();
751 OstreamLocker L(Ctx);
752 Ostream &Str = Ctx->getStrDump();
753 if (Func->isVerbose()) {
754 Str << "Live range errors in the following block:\n";
755 dump(Func);
756 }
757 for (auto Start = MapBegin.begin();
758 (Start = std::adjacent_find(Start, MapBegin.end(), ComparePair)) !=
759 MapBegin.end();
760 ++Start) {
761 auto Next = Start + 1;
762 Str << "Duplicate LR begin, block " << getName() << ", instructions "
763 << Start->second << " & " << Next->second << ", variable "
764 << Liveness->getVariable(Start->first, this)->getName(Func) << "\n";
765 }
766 for (auto Start = MapEnd.begin();
767 (Start = std::adjacent_find(Start, MapEnd.end(), ComparePair)) !=
768 MapEnd.end();
769 ++Start) {
770 auto Next = Start + 1;
771 Str << "Duplicate LR end, block " << getName() << ", instructions "
772 << Start->second << " & " << Next->second << ", variable "
773 << Liveness->getVariable(Start->first, this)->getName(Func) << "\n";
774 }
775 }
776
777 return false;
778}
779
Andrew Scull57e12682015-09-16 11:30:19 -0700780// Once basic liveness is complete, compute actual live ranges. It is assumed
781// that within a single basic block, a live range begins at most once and ends
782// at most once. This is certainly true for pure SSA form. It is also true once
783// phis are lowered, since each assignment to the phi-based temporary is in a
784// different basic block, and there is a single read that ends the live in the
785// basic block that contained the actual phi instruction.
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800786void CfgNode::livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum,
787 InstNumberT LastInstNum) {
788 TimerMarker T1(TimerStack::TT_liveRange, Func);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700789
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800790 const SizeT NumVars = Liveness->getNumVarsInNode(this);
791 const LivenessBV &LiveIn = Liveness->getLiveIn(this);
792 const LivenessBV &LiveOut = Liveness->getLiveOut(this);
Jim Stichnoth47752552014-10-13 17:15:08 -0700793 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this);
794 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this);
795 std::sort(MapBegin.begin(), MapBegin.end());
796 std::sort(MapEnd.begin(), MapEnd.end());
Jim Stichnoth230d4102015-09-25 17:40:32 -0700797
798 if (!livenessValidateIntervals(Liveness)) {
799 llvm::report_fatal_error("livenessAddIntervals: Liveness error");
800 return;
801 }
Jim Stichnoth47752552014-10-13 17:15:08 -0700802
Jim Stichnoth1bdb7352016-02-29 16:58:15 -0800803 LivenessBV &LiveInAndOut = Liveness->getScratchBV();
804 LiveInAndOut = LiveIn;
Jim Stichnoth47752552014-10-13 17:15:08 -0700805 LiveInAndOut &= LiveOut;
806
807 // Iterate in parallel across the sorted MapBegin[] and MapEnd[].
808 auto IBB = MapBegin.begin(), IEB = MapEnd.begin();
809 auto IBE = MapBegin.end(), IEE = MapEnd.end();
810 while (IBB != IBE || IEB != IEE) {
811 SizeT i1 = IBB == IBE ? NumVars : IBB->first;
812 SizeT i2 = IEB == IEE ? NumVars : IEB->first;
813 SizeT i = std::min(i1, i2);
Andrew Scull57e12682015-09-16 11:30:19 -0700814 // i1 is the Variable number of the next MapBegin entry, and i2 is the
815 // Variable number of the next MapEnd entry. If i1==i2, then the Variable's
816 // live range begins and ends in this block. If i1<i2, then i1's live range
817 // begins at instruction IBB->second and extends through the end of the
818 // block. If i1>i2, then i2's live range begins at the first instruction of
819 // the block and ends at IEB->second. In any case, we choose the lesser of
820 // i1 and i2 and proceed accordingly.
Jim Stichnoth47752552014-10-13 17:15:08 -0700821 InstNumberT LB = i == i1 ? IBB->second : FirstInstNum;
822 InstNumberT LE = i == i2 ? IEB->second : LastInstNum + 1;
823
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700824 Variable *Var = Liveness->getVariable(i, this);
Jim Stichnothf9df4522015-08-06 17:50:14 -0700825 if (LB > LE) {
Andrew Scull11c9a322015-08-28 14:24:14 -0700826 Var->addLiveRange(FirstInstNum, LE);
827 Var->addLiveRange(LB, LastInstNum + 1);
Andrew Scull57e12682015-09-16 11:30:19 -0700828 // Assert that Var is a global variable by checking that its liveness
829 // index is less than the number of globals. This ensures that the
830 // LiveInAndOut[] access is valid.
Jim Stichnothf9df4522015-08-06 17:50:14 -0700831 assert(i < Liveness->getNumGlobalVars());
832 LiveInAndOut[i] = false;
833 } else {
Andrew Scull11c9a322015-08-28 14:24:14 -0700834 Var->addLiveRange(LB, LE);
Jim Stichnoth47752552014-10-13 17:15:08 -0700835 }
836 if (i == i1)
837 ++IBB;
838 if (i == i2)
839 ++IEB;
840 }
841 // Process the variables that are live across the entire block.
842 for (int i = LiveInAndOut.find_first(); i != -1;
843 i = LiveInAndOut.find_next(i)) {
844 Variable *Var = Liveness->getVariable(i, this);
Jim Stichnoth552490c2015-08-05 16:21:42 -0700845 if (Liveness->getRangeMask(Var->getIndex()))
Andrew Scull11c9a322015-08-28 14:24:14 -0700846 Var->addLiveRange(FirstInstNum, LastInstNum + 1);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700847 }
848}
849
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700850// If this node contains only deleted instructions, and ends in an
Andrew Scull57e12682015-09-16 11:30:19 -0700851// unconditional branch, contract the node by repointing all its in-edges to
852// its successor.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700853void CfgNode::contractIfEmpty() {
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800854 if (InEdges.empty())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700855 return;
Jim Stichnothae953202014-12-20 06:17:49 -0800856 Inst *Branch = nullptr;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800857 for (Inst &I : Insts) {
858 if (I.isDeleted())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700859 continue;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800860 if (I.isUnconditionalBranch())
861 Branch = &I;
862 else if (!I.isRedundantAssign())
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700863 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700864 }
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -0800865 // Make sure there is actually a successor to repoint in-edges to.
866 if (OutEdges.empty())
867 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700868 assert(OutEdges.size() == 1);
Jim Stichnoth1921fba2015-09-15 10:06:30 -0700869 // Don't try to delete a self-loop.
870 if (OutEdges[0] == this)
871 return;
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -0800872 // Make sure the node actually contains (ends with) an unconditional branch.
873 if (Branch == nullptr)
874 return;
Jim Stichnoth1921fba2015-09-15 10:06:30 -0700875
876 Branch->setDeleted();
Andrew Scull713278a2015-07-22 17:17:02 -0700877 CfgNode *Successor = OutEdges.front();
Andrew Scull57e12682015-09-16 11:30:19 -0700878 // Repoint all this node's in-edges to this node's successor, unless this
879 // node's successor is actually itself (in which case the statement
880 // "OutEdges.front()->InEdges.push_back(Pred)" could invalidate the iterator
881 // over this->InEdges).
Andrew Scull713278a2015-07-22 17:17:02 -0700882 if (Successor != this) {
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800883 for (CfgNode *Pred : InEdges) {
Andrew Scull713278a2015-07-22 17:17:02 -0700884 for (CfgNode *&I : Pred->OutEdges) {
885 if (I == this) {
886 I = Successor;
887 Successor->InEdges.push_back(Pred);
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800888 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700889 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800890 for (Inst &I : Pred->getInsts()) {
891 if (!I.isDeleted())
Andrew Scull713278a2015-07-22 17:17:02 -0700892 I.repointEdges(this, Successor);
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800893 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700894 }
Andrew Scull713278a2015-07-22 17:17:02 -0700895
896 // Remove the in-edge to the successor to allow node reordering to make
Andrew Scull57e12682015-09-16 11:30:19 -0700897 // better decisions. For example it's more helpful to place a node after a
898 // reachable predecessor than an unreachable one (like the one we just
Andrew Scull713278a2015-07-22 17:17:02 -0700899 // contracted).
900 Successor->InEdges.erase(
901 std::find(Successor->InEdges.begin(), Successor->InEdges.end(), this));
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700902 }
903 InEdges.clear();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700904}
905
Jim Stichnothff9c7062014-09-18 04:50:49 -0700906void CfgNode::doBranchOpt(const CfgNode *NextNode) {
907 TargetLowering *Target = Func->getTarget();
Andrew Scull713278a2015-07-22 17:17:02 -0700908 // Find the first opportunity for branch optimization (which will be the last
Andrew Scull57e12682015-09-16 11:30:19 -0700909 // instruction in the block) and stop. This is sufficient unless there is
910 // some target lowering where we have the possibility of multiple
911 // optimizations per block. Take care with switch lowering as there are
912 // multiple unconditional branches and only the last can be deleted.
Andrew Scull713278a2015-07-22 17:17:02 -0700913 for (Inst &I : reverse_range(Insts)) {
Jim Stichnoth29841e82014-12-23 12:26:24 -0800914 if (!I.isDeleted()) {
915 Target->doBranchOpt(&I, NextNode);
Andrew Scull713278a2015-07-22 17:17:02 -0700916 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700917 }
918 }
Jim Stichnothff9c7062014-09-18 04:50:49 -0700919}
920
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700921// ======================== Dump routines ======================== //
922
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700923namespace {
924
925// Helper functions for emit().
926
927void emitRegisterUsage(Ostream &Str, const Cfg *Func, const CfgNode *Node,
Andrew Scull00741a02015-09-16 19:04:09 -0700928 bool IsLiveIn, CfgVector<SizeT> &LiveRegCount) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700929 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800930 return;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700931 Liveness *Liveness = Func->getLiveness();
932 const LivenessBV *Live;
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800933 const auto StackReg = Func->getTarget()->getStackReg();
934 const auto FrameOrStackReg = Func->getTarget()->getFrameOrStackReg();
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700935 if (IsLiveIn) {
936 Live = &Liveness->getLiveIn(Node);
Jim Stichnoth751e27e2015-12-16 12:40:31 -0800937 Str << "\t\t\t\t/* LiveIn=";
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700938 } else {
939 Live = &Liveness->getLiveOut(Node);
Jim Stichnoth751e27e2015-12-16 12:40:31 -0800940 Str << "\t\t\t\t/* LiveOut=";
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700941 }
942 if (!Live->empty()) {
Andrew Scull00741a02015-09-16 19:04:09 -0700943 CfgVector<Variable *> LiveRegs;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700944 for (SizeT i = 0; i < Live->size(); ++i) {
Jim Stichnothe7418712015-10-09 06:54:02 -0700945 if (!(*Live)[i])
946 continue;
947 Variable *Var = Liveness->getVariable(i, Node);
948 if (!Var->hasReg())
949 continue;
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800950 const auto RegNum = Var->getRegNum();
Jim Stichnothe7418712015-10-09 06:54:02 -0700951 if (RegNum == StackReg || RegNum == FrameOrStackReg)
952 continue;
953 if (IsLiveIn)
954 ++LiveRegCount[RegNum];
955 LiveRegs.push_back(Var);
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700956 }
Andrew Scull57e12682015-09-16 11:30:19 -0700957 // Sort the variables by regnum so they are always printed in a familiar
958 // order.
Jim Stichnoth9a05aea2015-05-26 16:01:23 -0700959 std::sort(LiveRegs.begin(), LiveRegs.end(),
960 [](const Variable *V1, const Variable *V2) {
Jim Stichnoth8aa39662016-02-10 11:20:30 -0800961 return unsigned(V1->getRegNum()) < unsigned(V2->getRegNum());
Jim Stichnoth8e6bf6e2015-06-03 15:58:12 -0700962 });
Jim Stichnoth9a05aea2015-05-26 16:01:23 -0700963 bool First = true;
964 for (Variable *Var : LiveRegs) {
965 if (!First)
966 Str << ",";
967 First = false;
968 Var->emit(Func);
969 }
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700970 }
Jim Stichnoth751e27e2015-12-16 12:40:31 -0800971 Str << " */\n";
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700972}
973
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800974/// Returns true if some text was emitted - in which case the caller definitely
975/// needs to emit a newline character.
976bool emitLiveRangesEnded(Ostream &Str, const Cfg *Func, const Inst *Instr,
Andrew Scull00741a02015-09-16 19:04:09 -0700977 CfgVector<SizeT> &LiveRegCount) {
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800978 bool Printed = false;
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700979 if (!BuildDefs::dump())
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800980 return Printed;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700981 Variable *Dest = Instr->getDest();
Andrew Scull57e12682015-09-16 11:30:19 -0700982 // Normally we increment the live count for the dest register. But we
Jim Stichnoth230d4102015-09-25 17:40:32 -0700983 // shouldn't if the instruction's IsDestRedefined flag is set, because this
Andrew Scull57e12682015-09-16 11:30:19 -0700984 // means that the target lowering created this instruction as a non-SSA
985 // assignment; i.e., a different, previous instruction started the dest
986 // variable's live range.
Jim Stichnoth230d4102015-09-25 17:40:32 -0700987 if (!Instr->isDestRedefined() && Dest && Dest->hasReg())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700988 ++LiveRegCount[Dest->getRegNum()];
John Portoec3f5652015-08-31 15:07:09 -0700989 FOREACH_VAR_IN_INST(Var, *Instr) {
990 bool ShouldReport = Instr->isLastUse(Var);
991 if (ShouldReport && Var->hasReg()) {
992 // Don't report end of live range until the live count reaches 0.
993 SizeT NewCount = --LiveRegCount[Var->getRegNum()];
994 if (NewCount)
995 ShouldReport = false;
996 }
997 if (ShouldReport) {
Jim Stichnoth3e859b72015-11-10 14:39:51 -0800998 if (Printed)
John Portoec3f5652015-08-31 15:07:09 -0700999 Str << ",";
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001000 else
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001001 Str << " \t/* END=";
John Portoec3f5652015-08-31 15:07:09 -07001002 Var->emit(Func);
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001003 Printed = true;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001004 }
1005 }
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001006 if (Printed)
1007 Str << " */";
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001008 return Printed;
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001009}
1010
Jan Voung0faec4c2014-11-05 17:29:56 -08001011void updateStats(Cfg *Func, const Inst *I) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001012 if (!BuildDefs::dump())
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001013 return;
Andrew Scull57e12682015-09-16 11:30:19 -07001014 // Update emitted instruction count, plus fill/spill count for Variable
1015 // operands without a physical register.
Jan Voung0faec4c2014-11-05 17:29:56 -08001016 if (uint32_t Count = I->getEmitInstCount()) {
1017 Func->getContext()->statsUpdateEmitted(Count);
1018 if (Variable *Dest = I->getDest()) {
1019 if (!Dest->hasReg())
1020 Func->getContext()->statsUpdateFills();
1021 }
1022 for (SizeT S = 0; S < I->getSrcSize(); ++S) {
Jim Stichnoth54f3d512015-12-11 09:53:00 -08001023 if (auto *Src = llvm::dyn_cast<Variable>(I->getSrc(S))) {
Jan Voung0faec4c2014-11-05 17:29:56 -08001024 if (!Src->hasReg())
1025 Func->getContext()->statsUpdateSpills();
1026 }
1027 }
1028 }
1029}
1030
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001031} // end of anonymous namespace
1032
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001033void CfgNode::emit(Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001034 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001035 return;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001036 Func->setCurrentNode(this);
1037 Ostream &Str = Func->getContext()->getStrEmit();
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001038 Liveness *Liveness = Func->getLiveness();
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001039 const bool DecorateAsm =
Karl Schimpfdf80eb82015-02-09 14:20:22 -08001040 Liveness && Func->getContext()->getFlags().getDecorateAsm();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001041 Str << getAsmName() << ":\n";
Andrew Scull57e12682015-09-16 11:30:19 -07001042 // LiveRegCount keeps track of the number of currently live variables that
1043 // each register is assigned to. Normally that would be only 0 or 1, but the
1044 // register allocator's AllowOverlap inference allows it to be greater than 1
1045 // for short periods.
Andrew Scull00741a02015-09-16 19:04:09 -07001046 CfgVector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters());
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001047 if (DecorateAsm) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -07001048 constexpr bool IsLiveIn = true;
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001049 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount);
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001050 if (getInEdges().size()) {
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001051 Str << "\t\t\t\t/* preds=";
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001052 bool First = true;
1053 for (CfgNode *I : getInEdges()) {
1054 if (!First)
1055 Str << ",";
1056 First = false;
Jim Stichnoth9a63bab2015-10-05 11:13:59 -07001057 Str << "$" << I->getName();
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001058 }
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001059 Str << " */\n";
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001060 }
1061 if (getLoopNestDepth()) {
Jim Stichnoth751e27e2015-12-16 12:40:31 -08001062 Str << "\t\t\t\t/* loop depth=" << getLoopNestDepth() << " */\n";
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001063 }
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001064 }
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001065
Jim Stichnoth29841e82014-12-23 12:26:24 -08001066 for (const Inst &I : Phis) {
1067 if (I.isDeleted())
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001068 continue;
1069 // Emitting a Phi instruction should cause an error.
Jim Stichnoth29841e82014-12-23 12:26:24 -08001070 I.emit(Func);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001071 }
Jim Stichnoth29841e82014-12-23 12:26:24 -08001072 for (const Inst &I : Insts) {
1073 if (I.isDeleted())
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001074 continue;
Jim Stichnothb82baf22015-05-27 10:41:07 -07001075 if (I.isRedundantAssign()) {
Andrew Scull57e12682015-09-16 11:30:19 -07001076 // Usually, redundant assignments end the live range of the src variable
1077 // and begin the live range of the dest variable, with no net effect on
1078 // the liveness of their register. However, if the register allocator
1079 // infers the AllowOverlap condition, then this may be a redundant
1080 // assignment that does not end the src variable's live range, in which
1081 // case the active variable count for that register needs to be bumped.
1082 // That normally would have happened as part of emitLiveRangesEnded(),
1083 // but that isn't called for redundant assignments.
Jim Stichnothb82baf22015-05-27 10:41:07 -07001084 Variable *Dest = I.getDest();
Jim Stichnoth1fb030c2015-10-15 11:10:38 -07001085 if (DecorateAsm && Dest->hasReg()) {
Jim Stichnothb82baf22015-05-27 10:41:07 -07001086 ++LiveRegCount[Dest->getRegNum()];
Jim Stichnoth1fb030c2015-10-15 11:10:38 -07001087 if (I.isLastUse(I.getSrc(0)))
1088 --LiveRegCount[llvm::cast<Variable>(I.getSrc(0))->getRegNum()];
1089 }
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001090 continue;
Jim Stichnothb82baf22015-05-27 10:41:07 -07001091 }
Jim Stichnoth29841e82014-12-23 12:26:24 -08001092 I.emit(Func);
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001093 bool Printed = false;
Jan Voung0faec4c2014-11-05 17:29:56 -08001094 if (DecorateAsm)
Jim Stichnoth3e859b72015-11-10 14:39:51 -08001095 Printed = emitLiveRangesEnded(Str, Func, &I, LiveRegCount);
1096 if (Printed || llvm::isa<InstTarget>(&I))
1097 Str << "\n";
Jim Stichnoth29841e82014-12-23 12:26:24 -08001098 updateStats(Func, &I);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001099 }
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001100 if (DecorateAsm) {
Jim Stichnotha3f57b92015-07-30 12:46:04 -07001101 constexpr bool IsLiveIn = false;
Jim Stichnoth4175b2a2015-04-30 12:26:22 -07001102 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount);
1103 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001104}
1105
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001106// Helper class for emitIAS().
1107namespace {
1108class BundleEmitHelper {
1109 BundleEmitHelper() = delete;
1110 BundleEmitHelper(const BundleEmitHelper &) = delete;
1111 BundleEmitHelper &operator=(const BundleEmitHelper &) = delete;
1112
1113public:
David Sehr26217e32015-11-26 13:03:50 -08001114 BundleEmitHelper(Assembler *Asm, const InstList &Insts)
1115 : Asm(Asm), End(Insts.end()), BundleLockStart(End),
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001116 BundleSize(1 << Asm->getBundleAlignLog2Bytes()),
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001117 BundleMaskLo(BundleSize - 1), BundleMaskHi(~BundleMaskLo) {}
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001118 // Check whether we're currently within a bundle_lock region.
1119 bool isInBundleLockRegion() const { return BundleLockStart != End; }
Andrew Scull57e12682015-09-16 11:30:19 -07001120 // Check whether the current bundle_lock region has the align_to_end option.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001121 bool isAlignToEnd() const {
1122 assert(isInBundleLockRegion());
1123 return llvm::cast<InstBundleLock>(getBundleLockStart())->getOption() ==
1124 InstBundleLock::Opt_AlignToEnd;
1125 }
John Porto56958cb2016-01-14 09:18:18 -08001126 bool isPadToEnd() const {
1127 assert(isInBundleLockRegion());
1128 return llvm::cast<InstBundleLock>(getBundleLockStart())->getOption() ==
1129 InstBundleLock::Opt_PadToEnd;
1130 }
Andrew Scull57e12682015-09-16 11:30:19 -07001131 // Check whether the entire bundle_lock region falls within the same bundle.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001132 bool isSameBundle() const {
1133 assert(isInBundleLockRegion());
1134 return SizeSnapshotPre == SizeSnapshotPost ||
1135 (SizeSnapshotPre & BundleMaskHi) ==
1136 ((SizeSnapshotPost - 1) & BundleMaskHi);
1137 }
Andrew Scull57e12682015-09-16 11:30:19 -07001138 // Get the bundle alignment of the first instruction of the bundle_lock
1139 // region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001140 intptr_t getPreAlignment() const {
1141 assert(isInBundleLockRegion());
1142 return SizeSnapshotPre & BundleMaskLo;
1143 }
Andrew Scull57e12682015-09-16 11:30:19 -07001144 // Get the bundle alignment of the first instruction past the bundle_lock
1145 // region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001146 intptr_t getPostAlignment() const {
1147 assert(isInBundleLockRegion());
1148 return SizeSnapshotPost & BundleMaskLo;
1149 }
Andrew Scull57e12682015-09-16 11:30:19 -07001150 // Get the iterator pointing to the bundle_lock instruction, e.g. to roll
1151 // back the instruction iteration to that point.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001152 InstList::const_iterator getBundleLockStart() const {
1153 assert(isInBundleLockRegion());
1154 return BundleLockStart;
1155 }
Andrew Scull57e12682015-09-16 11:30:19 -07001156 // Set up bookkeeping when the bundle_lock instruction is first processed.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001157 void enterBundleLock(InstList::const_iterator I) {
1158 assert(!isInBundleLockRegion());
1159 BundleLockStart = I;
1160 SizeSnapshotPre = Asm->getBufferSize();
1161 Asm->setPreliminary(true);
1162 assert(isInBundleLockRegion());
1163 }
Andrew Scull57e12682015-09-16 11:30:19 -07001164 // Update bookkeeping when the bundle_unlock instruction is processed.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001165 void enterBundleUnlock() {
1166 assert(isInBundleLockRegion());
1167 SizeSnapshotPost = Asm->getBufferSize();
1168 }
Andrew Scull57e12682015-09-16 11:30:19 -07001169 // Update bookkeeping when we are completely finished with the bundle_lock
1170 // region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001171 void leaveBundleLockRegion() { BundleLockStart = End; }
Andrew Scull57e12682015-09-16 11:30:19 -07001172 // Check whether the instruction sequence fits within the current bundle, and
1173 // if not, add nop padding to the end of the current bundle.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001174 void padToNextBundle() {
1175 assert(isInBundleLockRegion());
1176 if (!isSameBundle()) {
1177 intptr_t PadToNextBundle = BundleSize - getPreAlignment();
1178 Asm->padWithNop(PadToNextBundle);
1179 SizeSnapshotPre += PadToNextBundle;
1180 SizeSnapshotPost += PadToNextBundle;
1181 assert((Asm->getBufferSize() & BundleMaskLo) == 0);
1182 assert(Asm->getBufferSize() == SizeSnapshotPre);
1183 }
1184 }
Andrew Scull57e12682015-09-16 11:30:19 -07001185 // If align_to_end is specified, add padding such that the instruction
1186 // sequences ends precisely at a bundle boundary.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001187 void padForAlignToEnd() {
1188 assert(isInBundleLockRegion());
1189 if (isAlignToEnd()) {
1190 if (intptr_t Offset = getPostAlignment()) {
1191 Asm->padWithNop(BundleSize - Offset);
1192 SizeSnapshotPre = Asm->getBufferSize();
1193 }
1194 }
1195 }
John Porto56958cb2016-01-14 09:18:18 -08001196 // If pad_to_end is specified, add padding such that the first instruction
1197 // after the instruction sequence starts at a bundle boundary.
1198 void padForPadToEnd() {
1199 assert(isInBundleLockRegion());
1200 if (isPadToEnd()) {
1201 if (intptr_t Offset = getPostAlignment()) {
1202 Asm->padWithNop(BundleSize - Offset);
1203 SizeSnapshotPre = Asm->getBufferSize();
1204 }
1205 }
1206 } // Update bookkeeping when rolling back for the second pass.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001207 void rollback() {
1208 assert(isInBundleLockRegion());
1209 Asm->setBufferSize(SizeSnapshotPre);
1210 Asm->setPreliminary(false);
1211 }
1212
1213private:
1214 Assembler *const Asm;
Andrew Scull57e12682015-09-16 11:30:19 -07001215 // End is a sentinel value such that BundleLockStart==End implies that we are
1216 // not in a bundle_lock region.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001217 const InstList::const_iterator End;
1218 InstList::const_iterator BundleLockStart;
1219 const intptr_t BundleSize;
1220 // Masking with BundleMaskLo identifies an address's bundle offset.
1221 const intptr_t BundleMaskLo;
1222 // Masking with BundleMaskHi identifies an address's bundle.
1223 const intptr_t BundleMaskHi;
Jim Stichnotheafb56c2015-06-22 10:35:22 -07001224 intptr_t SizeSnapshotPre = 0;
1225 intptr_t SizeSnapshotPost = 0;
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001226};
1227
1228} // end of anonymous namespace
1229
Jan Voung0faec4c2014-11-05 17:29:56 -08001230void CfgNode::emitIAS(Cfg *Func) const {
1231 Func->setCurrentNode(this);
Jim Stichnothbbca7542015-02-11 16:08:31 -08001232 Assembler *Asm = Func->getAssembler<>();
Andrew Scull57e12682015-09-16 11:30:19 -07001233 // TODO(stichnot): When sandboxing, defer binding the node label until just
1234 // before the first instruction is emitted, to reduce the chance that a
1235 // padding nop is a branch target.
Karl Schimpf50a33312015-10-23 09:19:48 -07001236 Asm->bindCfgNodeLabel(this);
Jim Stichnoth29841e82014-12-23 12:26:24 -08001237 for (const Inst &I : Phis) {
1238 if (I.isDeleted())
Jan Voung0faec4c2014-11-05 17:29:56 -08001239 continue;
1240 // Emitting a Phi instruction should cause an error.
Jim Stichnoth29841e82014-12-23 12:26:24 -08001241 I.emitIAS(Func);
Jan Voung0faec4c2014-11-05 17:29:56 -08001242 }
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001243
1244 // Do the simple emission if not sandboxed.
1245 if (!Func->getContext()->getFlags().getUseSandboxing()) {
1246 for (const Inst &I : Insts) {
1247 if (!I.isDeleted() && !I.isRedundantAssign()) {
1248 I.emitIAS(Func);
1249 updateStats(Func, &I);
1250 }
1251 }
1252 return;
Jan Voung0faec4c2014-11-05 17:29:56 -08001253 }
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001254
Andrew Scull57e12682015-09-16 11:30:19 -07001255 // The remainder of the function handles emission with sandboxing. There are
1256 // explicit bundle_lock regions delimited by bundle_lock and bundle_unlock
1257 // instructions. All other instructions are treated as an implicit
1258 // one-instruction bundle_lock region. Emission is done twice for each
1259 // bundle_lock region. The first pass is a preliminary pass, after which we
1260 // can figure out what nop padding is needed, then roll back, and make the
1261 // final pass.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001262 //
Andrew Scull57e12682015-09-16 11:30:19 -07001263 // Ideally, the first pass would be speculative and the second pass would
1264 // only be done if nop padding were needed, but the structure of the
1265 // integrated assembler makes it hard to roll back the state of label
1266 // bindings, label links, and relocation fixups. Instead, the first pass just
1267 // disables all mutation of that state.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001268
David Sehr26217e32015-11-26 13:03:50 -08001269 BundleEmitHelper Helper(Asm, Insts);
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001270 InstList::const_iterator End = Insts.end();
Andrew Scull57e12682015-09-16 11:30:19 -07001271 // Retrying indicates that we had to roll back to the bundle_lock instruction
1272 // to apply padding before the bundle_lock sequence.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001273 bool Retrying = false;
1274 for (InstList::const_iterator I = Insts.begin(); I != End; ++I) {
1275 if (I->isDeleted() || I->isRedundantAssign())
1276 continue;
1277
1278 if (llvm::isa<InstBundleLock>(I)) {
Andrew Scull57e12682015-09-16 11:30:19 -07001279 // Set up the initial bundle_lock state. This should not happen while
1280 // retrying, because the retry rolls back to the instruction following
1281 // the bundle_lock instruction.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001282 assert(!Retrying);
1283 Helper.enterBundleLock(I);
1284 continue;
1285 }
1286
1287 if (llvm::isa<InstBundleUnlock>(I)) {
1288 Helper.enterBundleUnlock();
1289 if (Retrying) {
1290 // Make sure all instructions are in the same bundle.
1291 assert(Helper.isSameBundle());
Andrew Scull57e12682015-09-16 11:30:19 -07001292 // If align_to_end is specified, make sure the next instruction begins
1293 // the bundle.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001294 assert(!Helper.isAlignToEnd() || Helper.getPostAlignment() == 0);
John Porto56958cb2016-01-14 09:18:18 -08001295 Helper.padForPadToEnd();
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001296 Helper.leaveBundleLockRegion();
1297 Retrying = false;
1298 } else {
1299 // This is the first pass, so roll back for the retry pass.
1300 Helper.rollback();
Andrew Scull57e12682015-09-16 11:30:19 -07001301 // Pad to the next bundle if the instruction sequence crossed a bundle
1302 // boundary.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001303 Helper.padToNextBundle();
1304 // Insert additional padding to make AlignToEnd work.
1305 Helper.padForAlignToEnd();
1306 // Prepare for the retry pass after padding is done.
1307 Retrying = true;
1308 I = Helper.getBundleLockStart();
1309 }
1310 continue;
1311 }
1312
1313 // I points to a non bundle_lock/bundle_unlock instruction.
1314 if (Helper.isInBundleLockRegion()) {
1315 I->emitIAS(Func);
1316 // Only update stats during the final pass.
1317 if (Retrying)
1318 updateStats(Func, I);
1319 } else {
1320 // Treat it as though there were an implicit bundle_lock and
1321 // bundle_unlock wrapping the instruction.
1322 Helper.enterBundleLock(I);
1323 I->emitIAS(Func);
1324 Helper.enterBundleUnlock();
1325 Helper.rollback();
1326 Helper.padToNextBundle();
1327 I->emitIAS(Func);
1328 updateStats(Func, I);
1329 Helper.leaveBundleLockRegion();
1330 }
1331 }
1332
Andrew Scull57e12682015-09-16 11:30:19 -07001333 // Don't allow bundle locking across basic blocks, to keep the backtracking
1334 // mechanism simple.
Jim Stichnoth9f42d8c2015-02-20 09:20:14 -08001335 assert(!Helper.isInBundleLockRegion());
1336 assert(!Retrying);
Jan Voung0faec4c2014-11-05 17:29:56 -08001337}
1338
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001339void CfgNode::dump(Cfg *Func) const {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001340 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001341 return;
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001342 Func->setCurrentNode(this);
1343 Ostream &Str = Func->getContext()->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001344 Liveness *Liveness = Func->getLiveness();
Andrew Scullaa6c1092015-09-03 17:50:30 -07001345 if (Func->isVerbose(IceV_Instructions) || Func->isVerbose(IceV_Loop))
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001346 Str << getName() << ":\n";
Andrew Scullaa6c1092015-09-03 17:50:30 -07001347 // Dump the loop nest depth
1348 if (Func->isVerbose(IceV_Loop))
1349 Str << " // LoopNestDepth = " << getLoopNestDepth() << "\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001350 // Dump list of predecessor nodes.
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001351 if (Func->isVerbose(IceV_Preds) && !InEdges.empty()) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001352 Str << " // preds = ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001353 bool First = true;
1354 for (CfgNode *I : InEdges) {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001355 if (!First)
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001356 Str << ", ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001357 First = false;
1358 Str << "%" << I->getName();
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001359 }
1360 Str << "\n";
1361 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001362 // Dump the live-in variables.
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001363 if (Func->isVerbose(IceV_Liveness)) {
1364 if (Liveness != nullptr && !Liveness->getLiveIn(this).empty()) {
1365 const LivenessBV &LiveIn = Liveness->getLiveIn(this);
1366 Str << " // LiveIn:";
1367 for (SizeT i = 0; i < LiveIn.size(); ++i) {
1368 if (LiveIn[i]) {
1369 Variable *Var = Liveness->getVariable(i, this);
1370 Str << " %" << Var->getName(Func);
1371 if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
1372 Str << ":"
1373 << Func->getTarget()->getRegName(Var->getRegNum(),
1374 Var->getType());
1375 }
Jim Stichnoth088b2be2014-10-23 12:02:08 -07001376 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001377 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001378 Str << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001379 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001380 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001381 // Dump each instruction.
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001382 if (Func->isVerbose(IceV_Instructions)) {
Jim Stichnoth29841e82014-12-23 12:26:24 -08001383 for (const Inst &I : Phis)
1384 I.dumpDecorated(Func);
1385 for (const Inst &I : Insts)
1386 I.dumpDecorated(Func);
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001387 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001388 // Dump the live-out variables.
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001389 if (Func->isVerbose(IceV_Liveness)) {
1390 if (Liveness != nullptr && !Liveness->getLiveOut(this).empty()) {
1391 const LivenessBV &LiveOut = Liveness->getLiveOut(this);
1392 Str << " // LiveOut:";
1393 for (SizeT i = 0; i < LiveOut.size(); ++i) {
1394 if (LiveOut[i]) {
1395 Variable *Var = Liveness->getVariable(i, this);
1396 Str << " %" << Var->getName(Func);
1397 if (Func->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
1398 Str << ":"
1399 << Func->getTarget()->getRegName(Var->getRegNum(),
1400 Var->getType());
1401 }
Jim Stichnoth088b2be2014-10-23 12:02:08 -07001402 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001403 }
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001404 Str << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001405 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001406 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001407 // Dump list of successor nodes.
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001408 if (Func->isVerbose(IceV_Succs)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001409 Str << " // succs = ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001410 bool First = true;
1411 for (CfgNode *I : OutEdges) {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001412 if (!First)
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001413 Str << ", ";
Jim Stichnothf44f3712014-10-01 14:05:51 -07001414 First = false;
1415 Str << "%" << I->getName();
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001416 }
1417 Str << "\n";
1418 }
1419}
1420
John Portof8b4cc82015-06-09 18:06:19 -07001421void CfgNode::profileExecutionCount(VariableDeclaration *Var) {
1422 constexpr char RMW_I64[] = "llvm.nacl.atomic.rmw.i64";
1423
1424 GlobalContext *Context = Func->getContext();
1425
1426 bool BadIntrinsic = false;
1427 const Intrinsics::FullIntrinsicInfo *Info =
1428 Context->getIntrinsicsInfo().find(RMW_I64, BadIntrinsic);
1429 assert(!BadIntrinsic);
1430 assert(Info != nullptr);
1431
1432 Operand *RMWI64Name = Context->getConstantExternSym(RMW_I64);
John Porto8b1a7052015-06-17 13:20:08 -07001433 constexpr RelocOffsetT Offset = 0;
1434 constexpr bool SuppressMangling = true;
1435 Constant *Counter =
1436 Context->getConstantSym(Offset, Var->getName(), SuppressMangling);
John Portof8b4cc82015-06-09 18:06:19 -07001437 Constant *AtomicRMWOp = Context->getConstantInt32(Intrinsics::AtomicAdd);
1438 Constant *One = Context->getConstantInt64(1);
1439 Constant *OrderAcquireRelease =
1440 Context->getConstantInt32(Intrinsics::MemoryOrderAcquireRelease);
1441
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001442 auto *Instr = InstIntrinsicCall::create(
John Portof8b4cc82015-06-09 18:06:19 -07001443 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info);
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001444 Instr->addArg(AtomicRMWOp);
1445 Instr->addArg(Counter);
1446 Instr->addArg(One);
1447 Instr->addArg(OrderAcquireRelease);
1448 Insts.push_front(Instr);
John Portof8b4cc82015-06-09 18:06:19 -07001449}
1450
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001451} // end of namespace Ice