blob: 65844b9f9872c03ddf45bfa00be1d0cee6b2eda3 [file] [log] [blame]
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001//===- subzero/src/IceCfg.cpp - Control flow graph 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
Andrew Scull57e12682015-09-16 11:30:19 -070011/// This file implements the Cfg class, including constant pool management.
Andrew Scull9612d322015-07-06 14:53:25 -070012///
Jim Stichnothf7c9a142014-04-29 10:52:43 -070013//===----------------------------------------------------------------------===//
14
15#include "IceCfg.h"
John Porto67f8de92015-06-25 10:14:17 -070016
17#include "IceAssembler.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070018#include "IceCfgNode.h"
Jim Stichnoth989a7032014-08-08 10:13:44 -070019#include "IceClFlags.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070020#include "IceDefs.h"
Jan Voungec270732015-01-12 17:00:22 -080021#include "IceELFObjectWriter.h"
John Portof8b4cc82015-06-09 18:06:19 -070022#include "IceGlobalInits.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070023#include "IceInst.h"
John Portoec3f5652015-08-31 15:07:09 -070024#include "IceInstVarIter.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070025#include "IceLiveness.h"
Andrew Scullaa6c1092015-09-03 17:50:30 -070026#include "IceLoopAnalyzer.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070027#include "IceOperand.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070028#include "IceTargetLowering.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070029
30namespace Ice {
31
Jim Stichnotha5fe17a2015-01-26 11:10:03 -080032ICE_TLS_DEFINE_FIELD(const Cfg *, Cfg, CurrentCfg);
Jim Stichnoth31c95592014-12-19 12:51:35 -080033
Jan Voung1d62cf02015-01-09 14:57:32 -080034ArenaAllocator<> *getCurrentCfgAllocator() {
Jim Stichnoth31c95592014-12-19 12:51:35 -080035 return Cfg::getCurrentCfgAllocator();
36}
37
Jim Stichnothbbca7542015-02-11 16:08:31 -080038Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
Jan Voung1f47ad02015-03-20 15:01:26 -070039 : Ctx(Ctx), SequenceNumber(SequenceNumber),
Jim Stichnotheafb56c2015-06-22 10:35:22 -070040 VMask(Ctx->getFlags().getVerbose()), NextInstNumber(Inst::NumberInitial),
41 Allocator(new ArenaAllocator<>()), Live(nullptr),
42 Target(TargetLowering::createLowering(Ctx->getFlags().getTargetArch(),
43 this)),
Jan Voung8acded02014-09-22 18:02:25 -070044 VMetadata(new VariablesMetadata(this)),
Jan Voung1f47ad02015-03-20 15:01:26 -070045 TargetAssembler(TargetLowering::createAssembler(
Jim Stichnotheafb56c2015-06-22 10:35:22 -070046 Ctx->getFlags().getTargetArch(), this)) {
Qining Luaee5fa82015-08-20 14:59:03 -070047 if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Randomize) {
Andrew Scull57e12682015-09-16 11:30:19 -070048 // If -randomize-pool-immediates=randomize, create a random number
49 // generator to generate a cookie for constant blinding.
Qining Luaee5fa82015-08-20 14:59:03 -070050 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
Qining Lu360e3192015-08-20 17:13:07 -070051 RPE_ConstantBlinding, this->SequenceNumber);
Qining Luaee5fa82015-08-20 14:59:03 -070052 ConstantBlindingCookie =
Qining Lu360e3192015-08-20 17:13:07 -070053 (uint32_t)RNG.next((uint64_t)std::numeric_limits<uint32_t>::max() + 1);
Qining Luaee5fa82015-08-20 14:59:03 -070054 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -080055}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070056
Jim Stichnoth8e928382015-02-02 17:03:08 -080057Cfg::~Cfg() { assert(ICE_TLS_GET_FIELD(CurrentCfg) == nullptr); }
Jim Stichnothf7c9a142014-04-29 10:52:43 -070058
59void Cfg::setError(const IceString &Message) {
60 HasError = true;
61 ErrorMessage = Message;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070062}
63
Jim Stichnoth668a7a32014-12-10 15:32:25 -080064CfgNode *Cfg::makeNode() {
Jim Stichnothf7c9a142014-04-29 10:52:43 -070065 SizeT LabelIndex = Nodes.size();
Jim Stichnoth668a7a32014-12-10 15:32:25 -080066 CfgNode *Node = CfgNode::create(this, LabelIndex);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067 Nodes.push_back(Node);
68 return Node;
69}
70
Karl Schimpfac7d7342015-08-06 12:55:23 -070071void Cfg::swapNodes(NodeList &NewNodes) {
Jim Stichnothe7dbc0b2015-09-15 10:09:24 -070072 assert(Nodes.size() == NewNodes.size());
Karl Schimpfac7d7342015-08-06 12:55:23 -070073 Nodes.swap(NewNodes);
74 for (SizeT I = 0, NumNodes = getNumNodes(); I < NumNodes; ++I)
75 Nodes[I]->resetIndex(I);
76}
77
John Portoa83bfde2015-09-18 08:43:02 -070078template <> Variable *Cfg::makeVariable<Variable>(Type Ty) {
Andrew Scull6d47bcd2015-09-17 17:10:05 -070079 SizeT Index = Variables.size();
80 Variable *Var = Target->shouldSplitToVariable64On32(Ty)
81 ? Variable64On32::create(this, Ty, Index)
82 : Variable::create(this, Ty, Index);
83 Variables.push_back(Var);
84 return Var;
85}
86
Jim Stichnothf7c9a142014-04-29 10:52:43 -070087void Cfg::addArg(Variable *Arg) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -070088 Arg->setIsArg();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070089 Args.push_back(Arg);
90}
91
Jim Stichnoth144cdce2014-09-22 16:02:59 -070092void Cfg::addImplicitArg(Variable *Arg) {
93 Arg->setIsImplicitArg();
94 ImplicitArgs.push_back(Arg);
95}
96
Andrew Scull57e12682015-09-16 11:30:19 -070097// Returns whether the stack frame layout has been computed yet. This is used
98// for dumping the stack frame location of Variables.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070099bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); }
100
John Portof8b4cc82015-06-09 18:06:19 -0700101namespace {
102constexpr char BlockNameGlobalPrefix[] = ".L$profiler$block_name$";
103constexpr char BlockStatsGlobalPrefix[] = ".L$profiler$block_info$";
104
John Porto1bec8bc2015-06-22 10:51:13 -0700105VariableDeclaration *nodeNameDeclaration(GlobalContext *Ctx,
106 const IceString &NodeAsmName) {
107 VariableDeclaration *Var = VariableDeclaration::create(Ctx);
John Portof8b4cc82015-06-09 18:06:19 -0700108 Var->setName(BlockNameGlobalPrefix + NodeAsmName);
109 Var->setIsConstant(true);
John Porto1bec8bc2015-06-22 10:51:13 -0700110 Var->addInitializer(VariableDeclaration::DataInitializer::create(
John Portof8b4cc82015-06-09 18:06:19 -0700111 NodeAsmName.data(), NodeAsmName.size() + 1));
112 const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
113 Var->setAlignment(Int64ByteSize); // Wasteful, 32-bit could use 4 bytes.
114 return Var;
115}
116
117VariableDeclaration *
John Porto1bec8bc2015-06-22 10:51:13 -0700118blockProfilingInfoDeclaration(GlobalContext *Ctx, const IceString &NodeAsmName,
John Portof8b4cc82015-06-09 18:06:19 -0700119 VariableDeclaration *NodeNameDeclaration) {
John Porto1bec8bc2015-06-22 10:51:13 -0700120 VariableDeclaration *Var = VariableDeclaration::create(Ctx);
John Portof8b4cc82015-06-09 18:06:19 -0700121 Var->setName(BlockStatsGlobalPrefix + NodeAsmName);
122 const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
John Porto1bec8bc2015-06-22 10:51:13 -0700123 Var->addInitializer(
124 VariableDeclaration::ZeroInitializer::create(Int64ByteSize));
John Portof8b4cc82015-06-09 18:06:19 -0700125
126 const RelocOffsetT NodeNameDeclarationOffset = 0;
John Porto1bec8bc2015-06-22 10:51:13 -0700127 Var->addInitializer(VariableDeclaration::RelocInitializer::create(
John Portof8b4cc82015-06-09 18:06:19 -0700128 NodeNameDeclaration, NodeNameDeclarationOffset));
129 Var->setAlignment(Int64ByteSize);
130 return Var;
131}
John Portof8b4cc82015-06-09 18:06:19 -0700132} // end of anonymous namespace
133
134void Cfg::profileBlocks() {
135 if (GlobalInits == nullptr)
136 GlobalInits.reset(new VariableDeclarationList());
137
138 for (CfgNode *Node : Nodes) {
139 IceString NodeAsmName = Node->getAsmName();
John Porto1bec8bc2015-06-22 10:51:13 -0700140 GlobalInits->push_back(nodeNameDeclaration(Ctx, NodeAsmName));
John Portof8b4cc82015-06-09 18:06:19 -0700141 GlobalInits->push_back(
John Porto1bec8bc2015-06-22 10:51:13 -0700142 blockProfilingInfoDeclaration(Ctx, NodeAsmName, GlobalInits->back()));
John Portof8b4cc82015-06-09 18:06:19 -0700143 Node->profileExecutionCount(GlobalInits->back());
144 }
145}
146
147bool Cfg::isProfileGlobal(const VariableDeclaration &Var) {
148 return Var.getName().find(BlockStatsGlobalPrefix) == 0;
149}
150
151void Cfg::addCallToProfileSummary() {
152 // The call(s) to __Sz_profile_summary are added by the profiler in functions
153 // that cause the program to exit. This function is defined in
154 // runtime/szrt_profiler.c.
155 Constant *ProfileSummarySym =
156 Ctx->getConstantExternSym("__Sz_profile_summary");
157 constexpr SizeT NumArgs = 0;
158 constexpr Variable *Void = nullptr;
159 constexpr bool HasTailCall = false;
160 auto *Call =
161 InstCall::create(this, NumArgs, Void, ProfileSummarySym, HasTailCall);
162 getEntryNode()->getInsts().push_front(Call);
163}
164
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700165void Cfg::translate() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700166 if (hasError())
167 return;
Andrew Scull57e12682015-09-16 11:30:19 -0700168 // FunctionTimer conditionally pushes/pops a TimerMarker if TimeEachFunction
169 // is enabled.
Jim Stichnoth380d7b92015-01-30 13:10:39 -0800170 std::unique_ptr<TimerMarker> FunctionTimer;
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700171 if (BuildDefs::dump()) {
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800172 const IceString &TimingFocusOn =
173 getContext()->getFlags().getTimingFocusOn();
Jim Stichnoth380d7b92015-01-30 13:10:39 -0800174 const IceString &Name = getFunctionName();
175 if (TimingFocusOn == "*" || TimingFocusOn == Name) {
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800176 setFocusedTiming();
177 getContext()->resetTimer(GlobalContext::TSK_Default);
Jim Stichnoth380d7b92015-01-30 13:10:39 -0800178 getContext()->setTimerName(GlobalContext::TSK_Default, Name);
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800179 }
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800180 if (getContext()->getFlags().getTimeEachFunction())
Jim Stichnoth380d7b92015-01-30 13:10:39 -0800181 FunctionTimer.reset(new TimerMarker(
182 getContext()->getTimerID(GlobalContext::TSK_Funcs, Name),
183 getContext(), GlobalContext::TSK_Funcs));
Jim Stichnotha5229652015-11-12 10:25:21 -0800184 if (isVerbose(IceV_Status))
185 getContext()->getStrDump() << ">>>Translating " << Name << "\n";
Jim Stichnothd14b1a02014-10-08 08:28:36 -0700186 }
Jim Stichnoth8363a062014-10-07 10:02:38 -0700187 TimerMarker T(TimerStack::TT_translate, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700188
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700189 dump("Initial CFG");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700190
John Portof8b4cc82015-06-09 18:06:19 -0700191 if (getContext()->getFlags().getEnableBlockProfile()) {
192 profileBlocks();
Andrew Scull57e12682015-09-16 11:30:19 -0700193 // TODO(jpp): this is fragile, at best. Figure out a better way of
194 // detecting exit functions.
John Portof8b4cc82015-06-09 18:06:19 -0700195 if (GlobalContext::matchSymbolName(getFunctionName(), "exit")) {
196 addCallToProfileSummary();
197 }
198 dump("Profiled CFG");
199 }
200
Jim Stichnothbe87b2e2015-09-18 15:43:59 -0700201 // Create the Hi and Lo variables where a split was needed
202 for (Variable *Var : Variables)
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700203 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Var))
Jim Stichnothbe87b2e2015-09-18 15:43:59 -0700204 Var64On32->initHiLo(this);
205
Andrew Scull57e12682015-09-16 11:30:19 -0700206 // The set of translation passes and their order are determined by the
207 // target.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700208 getTarget()->translate();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700209
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700210 dump("Final output");
Jim Stichnoth8363a062014-10-07 10:02:38 -0700211 if (getFocusedTiming())
212 getContext()->dumpTimers();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700213}
214
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700215void Cfg::computeInOutEdges() {
216 // Compute the out-edges.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700217 for (CfgNode *Node : Nodes)
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700218 Node->computeSuccessors();
219
220 // Prune any unreachable nodes before computing in-edges.
221 SizeT NumNodes = getNumNodes();
222 llvm::BitVector Reachable(NumNodes);
223 llvm::BitVector Pending(NumNodes);
224 Pending.set(getEntryNode()->getIndex());
225 while (true) {
226 int Index = Pending.find_first();
227 if (Index == -1)
228 break;
229 Pending.reset(Index);
230 Reachable.set(Index);
231 CfgNode *Node = Nodes[Index];
232 assert(Node->getIndex() == (SizeT)Index);
233 for (CfgNode *Succ : Node->getOutEdges()) {
234 SizeT SuccIndex = Succ->getIndex();
235 if (!Reachable.test(SuccIndex))
236 Pending.set(SuccIndex);
237 }
238 }
239 SizeT Dest = 0;
240 for (SizeT Source = 0; Source < NumNodes; ++Source) {
241 if (Reachable.test(Source)) {
242 Nodes[Dest] = Nodes[Source];
243 Nodes[Dest]->resetIndex(Dest);
244 // Compute the in-edges.
245 Nodes[Dest]->computePredecessors();
246 ++Dest;
247 }
248 }
249 Nodes.resize(Dest);
Jim Stichnoth1aca2302015-09-16 11:25:22 -0700250
251 TimerMarker T(TimerStack::TT_phiValidation, this);
252 for (CfgNode *Node : Nodes)
253 Node->validatePhis();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700254}
255
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700256void Cfg::renumberInstructions() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700257 TimerMarker T(TimerStack::TT_renumberInstructions, this);
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800258 NextInstNumber = Inst::NumberInitial;
Jim Stichnothf44f3712014-10-01 14:05:51 -0700259 for (CfgNode *Node : Nodes)
260 Node->renumberInstructions();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700261}
262
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700263// placePhiLoads() must be called before placePhiStores().
264void Cfg::placePhiLoads() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700265 TimerMarker T(TimerStack::TT_placePhiLoads, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700266 for (CfgNode *Node : Nodes)
267 Node->placePhiLoads();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700268}
269
270// placePhiStores() must be called after placePhiLoads().
271void Cfg::placePhiStores() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700272 TimerMarker T(TimerStack::TT_placePhiStores, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700273 for (CfgNode *Node : Nodes)
274 Node->placePhiStores();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700275}
276
277void Cfg::deletePhis() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700278 TimerMarker T(TimerStack::TT_deletePhis, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700279 for (CfgNode *Node : Nodes)
280 Node->deletePhis();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700281}
282
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700283void Cfg::advancedPhiLowering() {
284 TimerMarker T(TimerStack::TT_advancedPhiLowering, this);
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700285 // Clear all previously computed live ranges (but not live-in/live-out bit
286 // vectors or last-use markers), because the follow-on register allocation is
287 // only concerned with live ranges across the newly created blocks.
288 for (Variable *Var : Variables) {
289 Var->getLiveRange().reset();
290 }
Andrew Scull57e12682015-09-16 11:30:19 -0700291 // This splits edges and appends new nodes to the end of the node list. This
292 // can invalidate iterators, so don't use an iterator.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700293 SizeT NumNodes = getNumNodes();
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700294 SizeT NumVars = getNumVariables();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700295 for (SizeT I = 0; I < NumNodes; ++I)
296 Nodes[I]->advancedPhiLowering();
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700297
298 TimerMarker TT(TimerStack::TT_lowerPhiAssignments, this);
299 if (true) {
Andrew Scull57e12682015-09-16 11:30:19 -0700300 // The following code does an in-place update of liveness and live ranges
301 // as a result of adding the new phi edge split nodes.
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700302 getLiveness()->initPhiEdgeSplits(Nodes.begin() + NumNodes,
303 Variables.begin() + NumVars);
304 TimerMarker TTT(TimerStack::TT_liveness, this);
305 // Iterate over the newly added nodes to add their liveness info.
306 for (auto I = Nodes.begin() + NumNodes, E = Nodes.end(); I != E; ++I) {
307 InstNumberT FirstInstNum = getNextInstNumber();
308 (*I)->renumberInstructions();
309 InstNumberT LastInstNum = getNextInstNumber() - 1;
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700310 (*I)->liveness(getLiveness());
311 (*I)->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
312 }
313 } else {
314 // The following code does a brute-force recalculation of live ranges as a
Andrew Scull57e12682015-09-16 11:30:19 -0700315 // result of adding the new phi edge split nodes. The liveness calculation
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700316 // is particularly expensive because the new nodes are not yet in a proper
317 // topological order and so convergence is slower.
318 //
319 // This code is kept here for reference and can be temporarily enabled in
320 // case the incremental code is under suspicion.
321 renumberInstructions();
322 liveness(Liveness_Intervals);
323 getVMetadata()->init(VMK_All);
324 }
325 Target->regAlloc(RAK_Phi);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700326}
327
Andrew Scull57e12682015-09-16 11:30:19 -0700328// Find a reasonable placement for nodes that have not yet been placed, while
329// maintaining the same relative ordering among already placed nodes.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700330void Cfg::reorderNodes() {
Andrew Scull57e12682015-09-16 11:30:19 -0700331 // TODO(ascull): it would be nice if the switch tests were always followed by
332 // the default case to allow for fall through.
Andrew Scull00741a02015-09-16 19:04:09 -0700333 using PlacedList = CfgList<CfgNode *>;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700334 PlacedList Placed; // Nodes with relative placement locked down
335 PlacedList Unreachable; // Unreachable nodes
336 PlacedList::iterator NoPlace = Placed.end();
Andrew Scull57e12682015-09-16 11:30:19 -0700337 // Keep track of where each node has been tentatively placed so that we can
338 // manage insertions into the middle.
Andrew Scull00741a02015-09-16 19:04:09 -0700339 CfgVector<PlacedList::iterator> PlaceIndex(Nodes.size(), NoPlace);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700340 for (CfgNode *Node : Nodes) {
Andrew Scull57e12682015-09-16 11:30:19 -0700341 // The "do ... while(0);" construct is to factor out the --PlaceIndex and
342 // assert() statements before moving to the next node.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700343 do {
Andrew Scull713278a2015-07-22 17:17:02 -0700344 if (Node != getEntryNode() && Node->getInEdges().empty()) {
Andrew Scull57e12682015-09-16 11:30:19 -0700345 // The node has essentially been deleted since it is not a successor of
346 // any other node.
Andrew Scull713278a2015-07-22 17:17:02 -0700347 Unreachable.push_back(Node);
348 PlaceIndex[Node->getIndex()] = Unreachable.end();
349 Node->setNeedsPlacement(false);
350 continue;
351 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700352 if (!Node->needsPlacement()) {
353 // Add to the end of the Placed list.
354 Placed.push_back(Node);
355 PlaceIndex[Node->getIndex()] = Placed.end();
356 continue;
357 }
358 Node->setNeedsPlacement(false);
Andrew Scull57e12682015-09-16 11:30:19 -0700359 // Assume for now that the unplaced node is from edge-splitting and
360 // therefore has 1 in-edge and 1 out-edge (actually, possibly more than 1
361 // in-edge if the predecessor node was contracted). If this changes in
362 // the future, rethink the strategy.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700363 assert(Node->getInEdges().size() >= 1);
364 assert(Node->getOutEdges().size() == 1);
365
366 // If it's a (non-critical) edge where the successor has a single
367 // in-edge, then place it before the successor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800368 CfgNode *Succ = Node->getOutEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700369 if (Succ->getInEdges().size() == 1 &&
370 PlaceIndex[Succ->getIndex()] != NoPlace) {
371 Placed.insert(PlaceIndex[Succ->getIndex()], Node);
372 PlaceIndex[Node->getIndex()] = PlaceIndex[Succ->getIndex()];
373 continue;
374 }
375
376 // Otherwise, place it after the (first) predecessor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800377 CfgNode *Pred = Node->getInEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700378 auto PredPosition = PlaceIndex[Pred->getIndex()];
Andrew Scull57e12682015-09-16 11:30:19 -0700379 // It shouldn't be the case that PredPosition==NoPlace, but if that
380 // somehow turns out to be true, we just insert Node before
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700381 // PredPosition=NoPlace=Placed.end() .
382 if (PredPosition != NoPlace)
383 ++PredPosition;
384 Placed.insert(PredPosition, Node);
385 PlaceIndex[Node->getIndex()] = PredPosition;
386 } while (0);
387
388 --PlaceIndex[Node->getIndex()];
389 assert(*PlaceIndex[Node->getIndex()] == Node);
390 }
391
392 // Reorder Nodes according to the built-up lists.
Karl Schimpfac7d7342015-08-06 12:55:23 -0700393 NodeList Reordered;
394 Reordered.reserve(Placed.size() + Unreachable.size());
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700395 for (CfgNode *Node : Placed)
Karl Schimpfac7d7342015-08-06 12:55:23 -0700396 Reordered.push_back(Node);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700397 for (CfgNode *Node : Unreachable)
Karl Schimpfac7d7342015-08-06 12:55:23 -0700398 Reordered.push_back(Node);
399 assert(getNumNodes() == Reordered.size());
400 swapNodes(Reordered);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700401}
402
Qining Lu969f6a32015-07-31 09:58:34 -0700403namespace {
404void getRandomPostOrder(CfgNode *Node, llvm::BitVector &ToVisit,
405 Ice::NodeList &PostOrder,
406 Ice::RandomNumberGenerator *RNG) {
407 assert(ToVisit[Node->getIndex()]);
408 ToVisit[Node->getIndex()] = false;
409 NodeList Outs = Node->getOutEdges();
410 Ice::RandomShuffle(Outs.begin(), Outs.end(),
411 [RNG](int N) { return RNG->next(N); });
412 for (CfgNode *Next : Outs) {
413 if (ToVisit[Next->getIndex()])
414 getRandomPostOrder(Next, ToVisit, PostOrder, RNG);
415 }
416 PostOrder.push_back(Node);
417}
418} // end of anonymous namespace
419
420void Cfg::shuffleNodes() {
421 if (!Ctx->getFlags().shouldReorderBasicBlocks())
422 return;
423
424 NodeList ReversedReachable;
425 NodeList Unreachable;
426 llvm::BitVector ToVisit(Nodes.size(), true);
Qining Luaee5fa82015-08-20 14:59:03 -0700427 // Create Random number generator for function reordering
428 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
429 RPE_BasicBlockReordering, SequenceNumber);
Qining Lu969f6a32015-07-31 09:58:34 -0700430 // Traverse from entry node.
Qining Luaee5fa82015-08-20 14:59:03 -0700431 getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable, &RNG);
Qining Lu969f6a32015-07-31 09:58:34 -0700432 // Collect the unreachable nodes.
433 for (CfgNode *Node : Nodes)
434 if (ToVisit[Node->getIndex()])
435 Unreachable.push_back(Node);
436 // Copy the layout list to the Nodes.
Karl Schimpfac7d7342015-08-06 12:55:23 -0700437 NodeList Shuffled;
438 Shuffled.reserve(ReversedReachable.size() + Unreachable.size());
Qining Lu969f6a32015-07-31 09:58:34 -0700439 for (CfgNode *Node : reverse_range(ReversedReachable))
Karl Schimpfac7d7342015-08-06 12:55:23 -0700440 Shuffled.push_back(Node);
441 for (CfgNode *Node : Unreachable)
442 Shuffled.push_back(Node);
443 assert(Nodes.size() == Shuffled.size());
444 swapNodes(Shuffled);
Qining Lu969f6a32015-07-31 09:58:34 -0700445
446 dump("After basic block shuffling");
447}
448
Matt Wala45a06232014-07-09 16:33:22 -0700449void Cfg::doArgLowering() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700450 TimerMarker T(TimerStack::TT_doArgLowering, this);
Matt Wala45a06232014-07-09 16:33:22 -0700451 getTarget()->lowerArguments();
452}
453
David Sehr4318a412015-11-11 15:01:55 -0800454void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas,
455 uint32_t CombinedAlignment, InstList &Insts,
456 AllocaBaseVariableType BaseVariableType) {
David Sehre39d0ca2015-11-06 11:25:41 -0800457 if (Allocas.empty())
458 return;
David Sehr4318a412015-11-11 15:01:55 -0800459 // Sort by decreasing alignment.
Jim Stichnothc59288b2015-11-09 11:38:40 -0800460 std::sort(Allocas.begin(), Allocas.end(), [](Inst *I1, Inst *I2) {
461 auto *A1 = llvm::dyn_cast<InstAlloca>(I1);
462 auto *A2 = llvm::dyn_cast<InstAlloca>(I2);
463 return A1->getAlignInBytes() > A2->getAlignInBytes();
464 });
David Sehr4318a412015-11-11 15:01:55 -0800465 // Process the allocas in order of decreasing stack alignment. This allows
466 // us to pack less-aligned pieces after more-aligned ones, resulting in less
467 // stack growth. It also allows there to be at most one stack alignment "and"
468 // instruction for a whole list of allocas.
469 uint32_t CurrentOffset = 0;
470 CfgVector<int32_t> Offsets;
Jim Stichnothc59288b2015-11-09 11:38:40 -0800471 for (Inst *Instr : Allocas) {
David Sehre39d0ca2015-11-06 11:25:41 -0800472 auto *Alloca = llvm::cast<InstAlloca>(Instr);
David Sehr4318a412015-11-11 15:01:55 -0800473 // Adjust the size of the allocation up to the next multiple of the
474 // object's alignment.
475 uint32_t Alignment = std::max(Alloca->getAlignInBytes(), 1u);
476 auto *ConstSize =
477 llvm::dyn_cast<ConstantInteger32>(Alloca->getSizeInBytes());
478 uint32_t Size = Utils::applyAlignment(ConstSize->getValue(), Alignment);
479 if (BaseVariableType == BVT_FramePointer) {
480 // Addressing is relative to the frame pointer. Subtract the offset after
481 // adding the size of the alloca, because it grows downwards from the
482 // frame pointer.
483 Offsets.push_back(-(CurrentOffset + Size));
484 } else {
485 // Addressing is relative to the stack pointer or to a user pointer. Add
486 // the offset before adding the size of the object, because it grows
487 // upwards from the stack pointer.
488 Offsets.push_back(CurrentOffset);
489 }
490 // Update the running offset of the fused alloca region.
491 CurrentOffset += Size;
492 }
493 // Round the offset up to the alignment granularity to use as the size.
494 uint32_t TotalSize = Utils::applyAlignment(CurrentOffset, CombinedAlignment);
495 // Ensure every alloca was assigned an offset.
496 assert(Allocas.size() == Offsets.size());
David Sehr2f3b8ec2015-11-16 16:51:39 -0800497
498 switch (BaseVariableType) {
499 case BVT_UserPointer: {
500 Variable *BaseVariable = makeVariable(IceType_i32);
501 for (SizeT i = 0; i < Allocas.size(); ++i) {
502 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
David Sehr4318a412015-11-11 15:01:55 -0800503 // Emit a new addition operation to replace the alloca.
504 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]);
505 InstArithmetic *Add =
506 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(),
507 BaseVariable, AllocaOffset);
508 Insts.push_front(Add);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800509 Alloca->setDeleted();
510 }
511 Operand *AllocaSize = Ctx->getConstantInt32(TotalSize);
512 InstAlloca *CombinedAlloca =
513 InstAlloca::create(this, BaseVariable, AllocaSize, CombinedAlignment);
514 CombinedAlloca->setKnownFrameOffset();
515 Insts.push_front(CombinedAlloca);
516 } break;
517 case BVT_StackPointer:
518 case BVT_FramePointer: {
519 for (SizeT i = 0; i < Allocas.size(); ++i) {
520 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
David Sehr4318a412015-11-11 15:01:55 -0800521 // Emit a fake definition of the rematerializable variable.
522 Variable *Dest = Alloca->getDest();
523 InstFakeDef *Def = InstFakeDef::create(this, Dest);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800524 if (BaseVariableType == BVT_StackPointer)
525 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]);
526 else
527 Dest->setRematerializable(getTarget()->getFrameReg(), Offsets[i]);
David Sehr4318a412015-11-11 15:01:55 -0800528 Insts.push_front(Def);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800529 Alloca->setDeleted();
David Sehr4318a412015-11-11 15:01:55 -0800530 }
David Sehr2f3b8ec2015-11-16 16:51:39 -0800531 // Allocate the fixed area in the function prolog.
532 getTarget()->reserveFixedAllocaArea(TotalSize, CombinedAlignment);
David Sehr4318a412015-11-11 15:01:55 -0800533 } break;
David Sehr4318a412015-11-11 15:01:55 -0800534 }
David Sehre39d0ca2015-11-06 11:25:41 -0800535}
536
David Sehr4318a412015-11-11 15:01:55 -0800537void Cfg::processAllocas(bool SortAndCombine) {
David Sehre39d0ca2015-11-06 11:25:41 -0800538 const uint32_t StackAlignment = getTarget()->getStackAlignment();
539 CfgNode *EntryNode = getEntryNode();
David Sehre39d0ca2015-11-06 11:25:41 -0800540 // LLVM enforces power of 2 alignment.
541 assert(llvm::isPowerOf2_32(StackAlignment));
David Sehr4318a412015-11-11 15:01:55 -0800542 // Determine if there are large alignment allocations in the entry block or
543 // dynamic allocations (variable size in the entry block).
544 bool HasLargeAlignment = false;
545 bool HasDynamicAllocation = false;
David Sehre39d0ca2015-11-06 11:25:41 -0800546 for (Inst &Instr : EntryNode->getInsts()) {
547 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
David Sehre39d0ca2015-11-06 11:25:41 -0800548 uint32_t AlignmentParam = Alloca->getAlignInBytes();
David Sehr4318a412015-11-11 15:01:55 -0800549 if (AlignmentParam > StackAlignment)
550 HasLargeAlignment = true;
551 if (llvm::isa<Constant>(Alloca->getSizeInBytes()))
552 Alloca->setKnownFrameOffset();
553 else {
554 HasDynamicAllocation = true;
555 // If Allocas are not sorted, the first dynamic allocation causes
556 // later Allocas to be at unknown offsets relative to the stack/frame.
557 if (!SortAndCombine)
558 break;
559 }
David Sehre39d0ca2015-11-06 11:25:41 -0800560 }
561 }
David Sehr4318a412015-11-11 15:01:55 -0800562 // Don't do the heavyweight sorting and layout for low optimization levels.
563 if (!SortAndCombine)
564 return;
565 // Any alloca outside the entry block is a dynamic allocation.
David Sehre39d0ca2015-11-06 11:25:41 -0800566 for (CfgNode *Node : Nodes) {
567 if (Node == EntryNode)
568 continue;
569 for (Inst &Instr : Node->getInsts()) {
570 if (llvm::isa<InstAlloca>(&Instr)) {
571 // Allocations outside the entry block require a frame pointer.
David Sehr4318a412015-11-11 15:01:55 -0800572 HasDynamicAllocation = true;
David Sehre39d0ca2015-11-06 11:25:41 -0800573 break;
574 }
575 }
David Sehr4318a412015-11-11 15:01:55 -0800576 if (HasDynamicAllocation)
David Sehre39d0ca2015-11-06 11:25:41 -0800577 break;
578 }
579 // Mark the target as requiring a frame pointer.
David Sehr4318a412015-11-11 15:01:55 -0800580 if (HasLargeAlignment || HasDynamicAllocation)
David Sehre39d0ca2015-11-06 11:25:41 -0800581 getTarget()->setHasFramePointer();
David Sehr4318a412015-11-11 15:01:55 -0800582 // Collect the Allocas into the two vectors.
583 // Allocas in the entry block that have constant size and alignment less
584 // than or equal to the function's stack alignment.
585 CfgVector<Inst *> FixedAllocas;
586 // Allocas in the entry block that have constant size and alignment greater
587 // than the function's stack alignment.
588 CfgVector<Inst *> AlignedAllocas;
David Sehr2f3b8ec2015-11-16 16:51:39 -0800589 // Maximum alignment used by any alloca.
David Sehr4318a412015-11-11 15:01:55 -0800590 uint32_t MaxAlignment = StackAlignment;
591 for (Inst &Instr : EntryNode->getInsts()) {
592 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
593 if (!llvm::isa<Constant>(Alloca->getSizeInBytes()))
594 continue;
595 uint32_t AlignmentParam = Alloca->getAlignInBytes();
596 // For default align=0, set it to the real value 1, to avoid any
597 // bit-manipulation problems below.
598 AlignmentParam = std::max(AlignmentParam, 1u);
599 assert(llvm::isPowerOf2_32(AlignmentParam));
600 if (HasDynamicAllocation && AlignmentParam > StackAlignment) {
601 // If we have both dynamic allocations and large stack alignments,
602 // high-alignment allocations are pulled out with their own base.
603 AlignedAllocas.push_back(Alloca);
604 } else {
605 FixedAllocas.push_back(Alloca);
606 }
607 MaxAlignment = std::max(AlignmentParam, MaxAlignment);
608 }
609 }
David Sehre39d0ca2015-11-06 11:25:41 -0800610 // Add instructions to the head of the entry block in reverse order.
611 InstList &Insts = getEntryNode()->getInsts();
David Sehr4318a412015-11-11 15:01:55 -0800612 if (HasDynamicAllocation && HasLargeAlignment) {
613 // We are using a frame pointer, but fixed large-alignment alloca addresses,
614 // do not have a known offset from either the stack or frame pointer.
615 // They grow up from a user pointer from an alloca.
616 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800617 // Fixed size allocas are addressed relative to the frame pointer.
618 sortAndCombineAllocas(FixedAllocas, StackAlignment, Insts,
619 BVT_FramePointer);
620 } else {
621 // Otherwise, fixed size allocas are addressed relative to the stack unless
622 // there are dynamic allocas.
623 const AllocaBaseVariableType BasePointerType =
624 (HasDynamicAllocation ? BVT_FramePointer : BVT_StackPointer);
625 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType);
David Sehr4318a412015-11-11 15:01:55 -0800626 }
Jim Stichnoth3607b6c2015-11-13 14:28:23 -0800627 if (!FixedAllocas.empty() || !AlignedAllocas.empty())
628 // No use calling findRematerializable() unless there is some
629 // rematerializable alloca instruction to seed it.
630 findRematerializable();
631}
632
633namespace {
634
635// Helpers for findRematerializable(). For each of them, if a suitable
636// rematerialization is found, the instruction's Dest variable is set to be
637// rematerializable and it returns true, otherwise it returns false.
638
639bool rematerializeArithmetic(const Inst *Instr) {
640 // Check that it's an Arithmetic instruction with an Add operation.
641 auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr);
642 if (Arith == nullptr || Arith->getOp() != InstArithmetic::Add)
643 return false;
644 // Check that Src(0) is rematerializable.
645 auto *Src0Var = llvm::dyn_cast<Variable>(Arith->getSrc(0));
646 if (Src0Var == nullptr || !Src0Var->isRematerializable())
647 return false;
648 // Check that Src(1) is an immediate.
649 auto *Src1Imm = llvm::dyn_cast<ConstantInteger32>(Arith->getSrc(1));
650 if (Src1Imm == nullptr)
651 return false;
652 Arith->getDest()->setRematerializable(
653 Src0Var->getRegNum(), Src0Var->getStackOffset() + Src1Imm->getValue());
654 return true;
655}
656
657bool rematerializeAssign(const Inst *Instr) {
658 // An InstAssign only originates from an inttoptr or ptrtoint instruction,
659 // which never occurs in a MINIMAL build.
660 if (BuildDefs::minimal())
661 return false;
662 // Check that it's an Assign instruction.
663 if (!llvm::isa<InstAssign>(Instr))
664 return false;
665 // Check that Src(0) is rematerializable.
666 auto *Src0Var = llvm::dyn_cast<Variable>(Instr->getSrc(0));
667 if (Src0Var == nullptr || !Src0Var->isRematerializable())
668 return false;
669 Instr->getDest()->setRematerializable(Src0Var->getRegNum(),
670 Src0Var->getStackOffset());
671 return true;
672}
673
674bool rematerializeCast(const Inst *Instr) {
675 // An pointer-type bitcast never occurs in a MINIMAL build.
676 if (BuildDefs::minimal())
677 return false;
678 // Check that it's a Cast instruction with a Bitcast operation.
679 auto *Cast = llvm::dyn_cast<InstCast>(Instr);
680 if (Cast == nullptr || Cast->getCastKind() != InstCast::Bitcast)
681 return false;
682 // Check that Src(0) is rematerializable.
683 auto *Src0Var = llvm::dyn_cast<Variable>(Cast->getSrc(0));
684 if (Src0Var == nullptr || !Src0Var->isRematerializable())
685 return false;
686 // Check that Dest and Src(0) have the same type.
687 Variable *Dest = Cast->getDest();
688 if (Dest->getType() != Src0Var->getType())
689 return false;
690 Dest->setRematerializable(Src0Var->getRegNum(), Src0Var->getStackOffset());
691 return true;
692}
693
694} // end of anonymous namespace
695
696/// Scan the function to find additional rematerializable variables. This is
697/// possible when the source operand of an InstAssignment is a rematerializable
698/// variable, or the same for a pointer-type InstCast::Bitcast, or when an
699/// InstArithmetic is an add of a rematerializable variable and an immediate.
700/// Note that InstAssignment instructions and pointer-type InstCast::Bitcast
701/// instructions generally only come about from the IceConverter's treatment of
702/// inttoptr, ptrtoint, and bitcast instructions. TODO(stichnot): Consider
703/// other possibilities, however unlikely, such as InstArithmetic::Sub, or
704/// commutativity.
705void Cfg::findRematerializable() {
706 // Scan the instructions in order, and repeat until no new opportunities are
707 // found. It may take more than one iteration because a variable's defining
708 // block may happen to come after a block where it is used, depending on the
709 // CfgNode linearization order.
710 bool FoundNewAssignment;
711 do {
712 FoundNewAssignment = false;
713 for (CfgNode *Node : getNodes()) {
714 // No need to process Phi instructions.
715 for (Inst &Instr : Node->getInsts()) {
716 if (Instr.isDeleted())
717 continue;
718 Variable *Dest = Instr.getDest();
719 if (Dest == nullptr || Dest->isRematerializable())
720 continue;
721 if (rematerializeArithmetic(&Instr) || rematerializeAssign(&Instr) ||
722 rematerializeCast(&Instr)) {
723 FoundNewAssignment = true;
724 }
725 }
726 }
727 } while (FoundNewAssignment);
David Sehre39d0ca2015-11-06 11:25:41 -0800728}
729
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700730void Cfg::doAddressOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700731 TimerMarker T(TimerStack::TT_doAddressOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700732 for (CfgNode *Node : Nodes)
733 Node->doAddressOpt();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700734}
735
Matt Walac3302742014-08-15 16:21:56 -0700736void Cfg::doNopInsertion() {
Qining Lu969f6a32015-07-31 09:58:34 -0700737 if (!Ctx->getFlags().shouldDoNopInsertion())
738 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700739 TimerMarker T(TimerStack::TT_doNopInsertion, this);
Qining Luaee5fa82015-08-20 14:59:03 -0700740 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), RPE_NopInsertion,
741 SequenceNumber);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700742 for (CfgNode *Node : Nodes)
Qining Luaee5fa82015-08-20 14:59:03 -0700743 Node->doNopInsertion(RNG);
Matt Walac3302742014-08-15 16:21:56 -0700744}
745
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700746void Cfg::genCode() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700747 TimerMarker T(TimerStack::TT_genCode, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700748 for (CfgNode *Node : Nodes)
749 Node->genCode();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700750}
751
752// Compute the stack frame layout.
753void Cfg::genFrame() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700754 TimerMarker T(TimerStack::TT_genFrame, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700755 getTarget()->addProlog(Entry);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700756 for (CfgNode *Node : Nodes)
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700757 if (Node->getHasReturn())
758 getTarget()->addEpilog(Node);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700759}
760
Andrew Scullaa6c1092015-09-03 17:50:30 -0700761void Cfg::computeLoopNestDepth() {
762 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this);
763 LoopAnalyzer LA(this);
764 LA.computeLoopNestDepth();
765}
766
Andrew Scull57e12682015-09-16 11:30:19 -0700767// This is a lightweight version of live-range-end calculation. Marks the last
Andrew Scullaa6c1092015-09-03 17:50:30 -0700768// use of only those variables whose definition and uses are completely with a
Andrew Scull57e12682015-09-16 11:30:19 -0700769// single block. It is a quick single pass and doesn't need to iterate until
Andrew Scullaa6c1092015-09-03 17:50:30 -0700770// convergence.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700771void Cfg::livenessLightweight() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700772 TimerMarker T(TimerStack::TT_livenessLightweight, this);
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700773 getVMetadata()->init(VMK_Uses);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700774 for (CfgNode *Node : Nodes)
775 Node->livenessLightweight();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700776}
777
778void Cfg::liveness(LivenessMode Mode) {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700779 TimerMarker T(TimerStack::TT_liveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700780 Live.reset(new Liveness(this, Mode));
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700781 getVMetadata()->init(VMK_Uses);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700782 Live->init();
783 // Initialize with all nodes needing to be processed.
784 llvm::BitVector NeedToProcess(Nodes.size(), true);
785 while (NeedToProcess.any()) {
786 // Iterate in reverse topological order to speed up convergence.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800787 for (CfgNode *Node : reverse_range(Nodes)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700788 if (NeedToProcess[Node->getIndex()]) {
789 NeedToProcess[Node->getIndex()] = false;
790 bool Changed = Node->liveness(getLiveness());
791 if (Changed) {
792 // If the beginning-of-block liveness changed since the last
793 // iteration, mark all in-edges as needing to be processed.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700794 for (CfgNode *Pred : Node->getInEdges())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700795 NeedToProcess[Pred->getIndex()] = true;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700796 }
797 }
798 }
799 }
800 if (Mode == Liveness_Intervals) {
801 // Reset each variable's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700802 for (Variable *Var : Variables)
803 Var->resetLiveRange();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700804 }
Andrew Scull57e12682015-09-16 11:30:19 -0700805 // Make a final pass over each node to delete dead instructions, collect the
806 // first and last instruction numbers, and add live range segments for that
807 // node.
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800808 for (CfgNode *Node : Nodes) {
809 InstNumberT FirstInstNum = Inst::NumberSentinel;
810 InstNumberT LastInstNum = Inst::NumberSentinel;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800811 for (Inst &I : Node->getPhis()) {
812 I.deleteIfDead();
813 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800814 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800815 FirstInstNum = I.getNumber();
816 assert(I.getNumber() > LastInstNum);
817 LastInstNum = I.getNumber();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700818 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800819 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800820 for (Inst &I : Node->getInsts()) {
821 I.deleteIfDead();
822 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800823 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800824 FirstInstNum = I.getNumber();
825 assert(I.getNumber() > LastInstNum);
826 LastInstNum = I.getNumber();
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800827 }
828 }
829 if (Mode == Liveness_Intervals) {
Andrew Scull57e12682015-09-16 11:30:19 -0700830 // Special treatment for live in-args. Their liveness needs to extend
831 // beyond the beginning of the function, otherwise an arg whose only use
832 // is in the first instruction will end up having the trivial live range
833 // [2,2) and will *not* interfere with other arguments. So if the first
834 // instruction of the method is "r=arg1+arg2", both args may be assigned
835 // the same register. This is accomplished by extending the entry block's
836 // instruction range from [2,n) to [1,n) which will transform the
837 // problematic [2,2) live ranges into [1,2).
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700838 if (Node == getEntryNode()) {
Andrew Scull57e12682015-09-16 11:30:19 -0700839 // TODO(stichnot): Make it a strict requirement that the entry node
840 // gets the lowest instruction numbers, so that extending the live
841 // range for in-args is guaranteed to work.
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800842 FirstInstNum = Inst::NumberExtended;
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700843 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800844 Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700845 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700846 }
847}
848
Andrew Scull57e12682015-09-16 11:30:19 -0700849// Traverse every Variable of every Inst and verify that it appears within the
850// Variable's computed live range.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700851bool Cfg::validateLiveness() const {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700852 TimerMarker T(TimerStack::TT_validateLiveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700853 bool Valid = true;
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800854 OstreamLocker L(Ctx);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700855 Ostream &Str = Ctx->getStrDump();
Jim Stichnothf44f3712014-10-01 14:05:51 -0700856 for (CfgNode *Node : Nodes) {
Jim Stichnothae953202014-12-20 06:17:49 -0800857 Inst *FirstInst = nullptr;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800858 for (Inst &Inst : Node->getInsts()) {
859 if (Inst.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700860 continue;
Jim Stichnothae953202014-12-20 06:17:49 -0800861 if (FirstInst == nullptr)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800862 FirstInst = &Inst;
863 InstNumberT InstNumber = Inst.getNumber();
864 if (Variable *Dest = Inst.getDest()) {
Jim Stichnoth47752552014-10-13 17:15:08 -0700865 if (!Dest->getIgnoreLiveness()) {
866 bool Invalid = false;
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700867 constexpr bool IsDest = true;
Jim Stichnoth47752552014-10-13 17:15:08 -0700868 if (!Dest->getLiveRange().containsValue(InstNumber, IsDest))
869 Invalid = true;
Andrew Scull57e12682015-09-16 11:30:19 -0700870 // Check that this instruction actually *begins* Dest's live range,
871 // by checking that Dest is not live in the previous instruction. As
872 // a special exception, we don't check this for the first instruction
873 // of the block, because a Phi temporary may be live at the end of
874 // the previous block, and if it is also assigned in the first
875 // instruction of this block, the adjacent live ranges get merged.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800876 if (static_cast<class Inst *>(&Inst) != FirstInst &&
Jim Stichnoth230d4102015-09-25 17:40:32 -0700877 !Inst.isDestRedefined() &&
Jim Stichnoth47752552014-10-13 17:15:08 -0700878 Dest->getLiveRange().containsValue(InstNumber - 1, IsDest))
879 Invalid = true;
880 if (Invalid) {
881 Valid = false;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800882 Str << "Liveness error: inst " << Inst.getNumber() << " dest ";
Jim Stichnoth47752552014-10-13 17:15:08 -0700883 Dest->dump(this);
884 Str << " live range " << Dest->getLiveRange() << "\n";
885 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700886 }
887 }
John Portoec3f5652015-08-31 15:07:09 -0700888 FOREACH_VAR_IN_INST(Var, Inst) {
889 static constexpr bool IsDest = false;
890 if (!Var->getIgnoreLiveness() &&
891 !Var->getLiveRange().containsValue(InstNumber, IsDest)) {
892 Valid = false;
893 Str << "Liveness error: inst " << Inst.getNumber() << " var ";
894 Var->dump(this);
895 Str << " live range " << Var->getLiveRange() << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700896 }
897 }
898 }
899 }
900 return Valid;
901}
902
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700903void Cfg::contractEmptyNodes() {
Andrew Scullaa6c1092015-09-03 17:50:30 -0700904 // If we're decorating the asm output with register liveness info, this
905 // information may become corrupted or incorrect after contracting nodes that
906 // contain only redundant assignments. As such, we disable this pass when
907 // DecorateAsm is specified. This may make the resulting code look more
908 // branchy, but it should have no effect on the register assignments.
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800909 if (Ctx->getFlags().getDecorateAsm())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700910 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700911 for (CfgNode *Node : Nodes) {
912 Node->contractIfEmpty();
913 }
914}
915
Jim Stichnothff9c7062014-09-18 04:50:49 -0700916void Cfg::doBranchOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700917 TimerMarker T(TimerStack::TT_doBranchOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700918 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
Andrew Scull713278a2015-07-22 17:17:02 -0700919 auto NextNode = I + 1;
Jim Stichnothae953202014-12-20 06:17:49 -0800920 (*I)->doBranchOpt(NextNode == E ? nullptr : *NextNode);
Jim Stichnothff9c7062014-09-18 04:50:49 -0700921 }
922}
923
Andrew Scull86df4e92015-07-30 13:54:44 -0700924void Cfg::markNodesForSandboxing() {
925 for (const InstJumpTable *JT : JumpTables)
926 for (SizeT I = 0; I < JT->getNumTargets(); ++I)
927 JT->getTarget(I)->setNeedsAlignment();
928}
929
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700930// ======================== Dump routines ======================== //
931
Andrew Scull57e12682015-09-16 11:30:19 -0700932// emitTextHeader() is not target-specific (apart from what is abstracted by
933// the Assembler), so it is defined here rather than in the target lowering
934// class.
Jim Stichnothbbca7542015-02-11 16:08:31 -0800935void Cfg::emitTextHeader(const IceString &MangledName, GlobalContext *Ctx,
936 const Assembler *Asm) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700937 if (!BuildDefs::dump())
Jim Stichnoth729dbd02015-02-25 14:48:43 -0800938 return;
Jan Voung0faec4c2014-11-05 17:29:56 -0800939 Ostream &Str = Ctx->getStrEmit();
940 Str << "\t.text\n";
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800941 if (Ctx->getFlags().getFunctionSections())
John Portoafc92af2015-10-16 10:34:04 -0700942 Str << "\t.section\t.text." << MangledName << ",\"ax\",%progbits\n";
Jim Stichnothbbca7542015-02-11 16:08:31 -0800943 if (!Asm->getInternal() || Ctx->getFlags().getDisableInternal()) {
Jan Voung0faec4c2014-11-05 17:29:56 -0800944 Str << "\t.globl\t" << MangledName << "\n";
Jan Voungb2d50842015-05-12 09:53:50 -0700945 Str << "\t.type\t" << MangledName << ",%function\n";
Jan Voung0faec4c2014-11-05 17:29:56 -0800946 }
Andrew Scull86df4e92015-07-30 13:54:44 -0700947 Str << "\t" << Asm->getAlignDirective() << " "
Jan Voungb2d50842015-05-12 09:53:50 -0700948 << Asm->getBundleAlignLog2Bytes() << ",0x";
Jan Voung08c3bcd2014-12-01 17:55:16 -0800949 for (uint8_t I : Asm->getNonExecBundlePadding())
Jan Voung0faec4c2014-11-05 17:29:56 -0800950 Str.write_hex(I);
951 Str << "\n";
952 Str << MangledName << ":\n";
953}
954
Andrew Scull86df4e92015-07-30 13:54:44 -0700955void Cfg::deleteJumpTableInsts() {
956 for (InstJumpTable *JumpTable : JumpTables)
957 JumpTable->setDeleted();
958}
959
960void Cfg::emitJumpTables() {
961 switch (Ctx->getFlags().getOutFileType()) {
962 case FT_Elf:
963 case FT_Iasm: {
Andrew Scull57e12682015-09-16 11:30:19 -0700964 // The emission needs to be delayed until the after the text section so
965 // save the offsets in the global context.
Andrew Scull86df4e92015-07-30 13:54:44 -0700966 IceString MangledName = Ctx->mangleName(getFunctionName());
967 for (const InstJumpTable *JumpTable : JumpTables) {
968 SizeT NumTargets = JumpTable->getNumTargets();
969 JumpTableData &JT =
970 Ctx->addJumpTable(MangledName, JumpTable->getId(), NumTargets);
971 for (SizeT I = 0; I < NumTargets; ++I) {
972 SizeT Index = JumpTable->getTarget(I)->getIndex();
Jan Voungc2ec5812015-08-05 09:35:18 -0700973 JT.pushTarget(getAssembler()->getCfgNodeLabel(Index)->getPosition());
Andrew Scull86df4e92015-07-30 13:54:44 -0700974 }
975 }
976 } break;
977 case FT_Asm: {
978 // Emit the assembly directly so we don't need to hang on to all the names
979 for (const InstJumpTable *JumpTable : JumpTables)
980 getTarget()->emitJumpTable(this, JumpTable);
981 } break;
Andrew Scull86df4e92015-07-30 13:54:44 -0700982 }
983}
984
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700985void Cfg::emit() {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700986 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800987 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700988 TimerMarker T(TimerStack::TT_emit, this);
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800989 if (Ctx->getFlags().getDecorateAsm()) {
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700990 renumberInstructions();
991 getVMetadata()->init(VMK_Uses);
992 liveness(Liveness_Basic);
993 dump("After recomputing liveness for -decorate-asm");
994 }
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800995 OstreamLocker L(Ctx);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700996 Ostream &Str = Ctx->getStrEmit();
Andrew Scull86df4e92015-07-30 13:54:44 -0700997 IceString MangledName = Ctx->mangleName(getFunctionName());
998 const Assembler *Asm = getAssembler<>();
999 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
1000
1001 emitTextHeader(MangledName, Ctx, Asm);
1002 deleteJumpTableInsts();
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001003 if (Ctx->getFlags().getDecorateAsm()) {
1004 for (Variable *Var : getVariables()) {
Jim Stichnoth3607b6c2015-11-13 14:28:23 -08001005 if (Var->getStackOffset() && !Var->isRematerializable()) {
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001006 Str << "\t" << Var->getSymbolicStackOffset(this) << " = "
1007 << Var->getStackOffset() << "\n";
1008 }
1009 }
1010 }
Andrew Scull86df4e92015-07-30 13:54:44 -07001011 for (CfgNode *Node : Nodes) {
1012 if (NeedSandboxing && Node->needsAlignment()) {
1013 Str << "\t" << Asm->getAlignDirective() << " "
1014 << Asm->getBundleAlignLog2Bytes() << "\n";
1015 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07001016 Node->emit(this);
Andrew Scull86df4e92015-07-30 13:54:44 -07001017 }
1018 emitJumpTables();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001019 Str << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001020}
1021
Jan Voung0faec4c2014-11-05 17:29:56 -08001022void Cfg::emitIAS() {
1023 TimerMarker T(TimerStack::TT_emit, this);
Andrew Scull57e12682015-09-16 11:30:19 -07001024 // The emitIAS() routines emit into the internal assembler buffer, so there's
1025 // no need to lock the streams.
Andrew Scull86df4e92015-07-30 13:54:44 -07001026 deleteJumpTableInsts();
1027 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
1028 for (CfgNode *Node : Nodes) {
1029 if (NeedSandboxing && Node->needsAlignment())
1030 getAssembler()->alignCfgNode();
Jan Voung0faec4c2014-11-05 17:29:56 -08001031 Node->emitIAS(this);
Andrew Scull86df4e92015-07-30 13:54:44 -07001032 }
1033 emitJumpTables();
Jan Voung0faec4c2014-11-05 17:29:56 -08001034}
1035
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001036// Dumps the IR with an optional introductory message.
1037void Cfg::dump(const IceString &Message) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001038 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001039 return;
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001040 if (!isVerbose())
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001041 return;
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001042 OstreamLocker L(Ctx);
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001043 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001044 if (!Message.empty())
1045 Str << "================ " << Message << " ================\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001046 setCurrentNode(getEntryNode());
1047 // Print function name+args
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001048 if (isVerbose(IceV_Instructions)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001049 Str << "define ";
Karl Schimpfdf80eb82015-02-09 14:20:22 -08001050 if (getInternal() && !Ctx->getFlags().getDisableInternal())
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001051 Str << "internal ";
Karl Schimpfdf6f9d12014-10-20 14:09:00 -07001052 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001053 for (SizeT i = 0; i < Args.size(); ++i) {
1054 if (i > 0)
1055 Str << ", ";
1056 Str << Args[i]->getType() << " ";
1057 Args[i]->dump(this);
1058 }
1059 Str << ") {\n";
1060 }
Jim Stichnoth800dab22014-09-20 12:25:02 -07001061 resetCurrentNode();
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001062 if (isVerbose(IceV_Liveness)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001063 // Print summary info about variables
Jim Stichnothf44f3712014-10-01 14:05:51 -07001064 for (Variable *Var : Variables) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001065 Str << "// multiblock=";
1066 if (getVMetadata()->isTracked(Var))
1067 Str << getVMetadata()->isMultiBlock(Var);
1068 else
1069 Str << "?";
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07001070 Str << " defs=";
1071 bool FirstPrint = true;
1072 if (VMetadata->getKind() != VMK_Uses) {
1073 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) {
1074 Str << FirstDef->getNumber();
1075 FirstPrint = false;
1076 }
1077 }
1078 if (VMetadata->getKind() == VMK_All) {
1079 for (const Inst *Instr : VMetadata->getLatterDefinitions(Var)) {
1080 if (!FirstPrint)
1081 Str << ",";
1082 Str << Instr->getNumber();
1083 FirstPrint = false;
1084 }
1085 }
Andrew Scull11c9a322015-08-28 14:24:14 -07001086 Str << " weight=" << Var->getWeight(this) << " ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001087 Var->dump(this);
1088 Str << " LIVE=" << Var->getLiveRange() << "\n";
1089 }
1090 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001091 // Print each basic block
Jim Stichnothf44f3712014-10-01 14:05:51 -07001092 for (CfgNode *Node : Nodes)
1093 Node->dump(this);
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001094 if (isVerbose(IceV_Instructions))
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001095 Str << "}\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001096}
1097
1098} // end of namespace Ice