blob: f8d40a5bf25cff1013f48050b0d30392ec0480df [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
John Porto614140e2015-11-23 11:43:13 -0800487 // upwards from the stack pointer. In addition, if the addressing is
488 // relative to the stack pointer, we need to add the pre-computed max out
489 // args size bytes.
490 const uint32_t OutArgsOffsetOrZero =
491 (BaseVariableType == BVT_StackPointer)
492 ? getTarget()->maxOutArgsSizeBytes()
493 : 0;
494 Offsets.push_back(CurrentOffset + OutArgsOffsetOrZero);
David Sehr4318a412015-11-11 15:01:55 -0800495 }
496 // Update the running offset of the fused alloca region.
497 CurrentOffset += Size;
498 }
499 // Round the offset up to the alignment granularity to use as the size.
500 uint32_t TotalSize = Utils::applyAlignment(CurrentOffset, CombinedAlignment);
501 // Ensure every alloca was assigned an offset.
502 assert(Allocas.size() == Offsets.size());
David Sehr2f3b8ec2015-11-16 16:51:39 -0800503
504 switch (BaseVariableType) {
505 case BVT_UserPointer: {
506 Variable *BaseVariable = makeVariable(IceType_i32);
507 for (SizeT i = 0; i < Allocas.size(); ++i) {
508 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
David Sehr4318a412015-11-11 15:01:55 -0800509 // Emit a new addition operation to replace the alloca.
510 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]);
511 InstArithmetic *Add =
512 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(),
513 BaseVariable, AllocaOffset);
514 Insts.push_front(Add);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800515 Alloca->setDeleted();
516 }
517 Operand *AllocaSize = Ctx->getConstantInt32(TotalSize);
518 InstAlloca *CombinedAlloca =
519 InstAlloca::create(this, BaseVariable, AllocaSize, CombinedAlignment);
520 CombinedAlloca->setKnownFrameOffset();
521 Insts.push_front(CombinedAlloca);
522 } break;
523 case BVT_StackPointer:
524 case BVT_FramePointer: {
525 for (SizeT i = 0; i < Allocas.size(); ++i) {
526 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
David Sehr4318a412015-11-11 15:01:55 -0800527 // Emit a fake definition of the rematerializable variable.
528 Variable *Dest = Alloca->getDest();
529 InstFakeDef *Def = InstFakeDef::create(this, Dest);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800530 if (BaseVariableType == BVT_StackPointer)
531 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]);
532 else
533 Dest->setRematerializable(getTarget()->getFrameReg(), Offsets[i]);
David Sehr4318a412015-11-11 15:01:55 -0800534 Insts.push_front(Def);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800535 Alloca->setDeleted();
David Sehr4318a412015-11-11 15:01:55 -0800536 }
David Sehr2f3b8ec2015-11-16 16:51:39 -0800537 // Allocate the fixed area in the function prolog.
538 getTarget()->reserveFixedAllocaArea(TotalSize, CombinedAlignment);
David Sehr4318a412015-11-11 15:01:55 -0800539 } break;
David Sehr4318a412015-11-11 15:01:55 -0800540 }
David Sehre39d0ca2015-11-06 11:25:41 -0800541}
542
David Sehr4318a412015-11-11 15:01:55 -0800543void Cfg::processAllocas(bool SortAndCombine) {
David Sehre39d0ca2015-11-06 11:25:41 -0800544 const uint32_t StackAlignment = getTarget()->getStackAlignment();
545 CfgNode *EntryNode = getEntryNode();
David Sehre39d0ca2015-11-06 11:25:41 -0800546 // LLVM enforces power of 2 alignment.
547 assert(llvm::isPowerOf2_32(StackAlignment));
David Sehr4318a412015-11-11 15:01:55 -0800548 // Determine if there are large alignment allocations in the entry block or
549 // dynamic allocations (variable size in the entry block).
550 bool HasLargeAlignment = false;
551 bool HasDynamicAllocation = false;
David Sehre39d0ca2015-11-06 11:25:41 -0800552 for (Inst &Instr : EntryNode->getInsts()) {
553 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
David Sehre39d0ca2015-11-06 11:25:41 -0800554 uint32_t AlignmentParam = Alloca->getAlignInBytes();
David Sehr4318a412015-11-11 15:01:55 -0800555 if (AlignmentParam > StackAlignment)
556 HasLargeAlignment = true;
557 if (llvm::isa<Constant>(Alloca->getSizeInBytes()))
558 Alloca->setKnownFrameOffset();
559 else {
560 HasDynamicAllocation = true;
561 // If Allocas are not sorted, the first dynamic allocation causes
562 // later Allocas to be at unknown offsets relative to the stack/frame.
563 if (!SortAndCombine)
564 break;
565 }
David Sehre39d0ca2015-11-06 11:25:41 -0800566 }
567 }
David Sehr4318a412015-11-11 15:01:55 -0800568 // Don't do the heavyweight sorting and layout for low optimization levels.
569 if (!SortAndCombine)
570 return;
571 // Any alloca outside the entry block is a dynamic allocation.
David Sehre39d0ca2015-11-06 11:25:41 -0800572 for (CfgNode *Node : Nodes) {
573 if (Node == EntryNode)
574 continue;
575 for (Inst &Instr : Node->getInsts()) {
576 if (llvm::isa<InstAlloca>(&Instr)) {
577 // Allocations outside the entry block require a frame pointer.
David Sehr4318a412015-11-11 15:01:55 -0800578 HasDynamicAllocation = true;
David Sehre39d0ca2015-11-06 11:25:41 -0800579 break;
580 }
581 }
David Sehr4318a412015-11-11 15:01:55 -0800582 if (HasDynamicAllocation)
David Sehre39d0ca2015-11-06 11:25:41 -0800583 break;
584 }
585 // Mark the target as requiring a frame pointer.
David Sehr4318a412015-11-11 15:01:55 -0800586 if (HasLargeAlignment || HasDynamicAllocation)
David Sehre39d0ca2015-11-06 11:25:41 -0800587 getTarget()->setHasFramePointer();
David Sehr4318a412015-11-11 15:01:55 -0800588 // Collect the Allocas into the two vectors.
589 // Allocas in the entry block that have constant size and alignment less
590 // than or equal to the function's stack alignment.
591 CfgVector<Inst *> FixedAllocas;
592 // Allocas in the entry block that have constant size and alignment greater
593 // than the function's stack alignment.
594 CfgVector<Inst *> AlignedAllocas;
David Sehr2f3b8ec2015-11-16 16:51:39 -0800595 // Maximum alignment used by any alloca.
David Sehr4318a412015-11-11 15:01:55 -0800596 uint32_t MaxAlignment = StackAlignment;
597 for (Inst &Instr : EntryNode->getInsts()) {
598 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
599 if (!llvm::isa<Constant>(Alloca->getSizeInBytes()))
600 continue;
601 uint32_t AlignmentParam = Alloca->getAlignInBytes();
602 // For default align=0, set it to the real value 1, to avoid any
603 // bit-manipulation problems below.
604 AlignmentParam = std::max(AlignmentParam, 1u);
605 assert(llvm::isPowerOf2_32(AlignmentParam));
606 if (HasDynamicAllocation && AlignmentParam > StackAlignment) {
607 // If we have both dynamic allocations and large stack alignments,
608 // high-alignment allocations are pulled out with their own base.
609 AlignedAllocas.push_back(Alloca);
610 } else {
611 FixedAllocas.push_back(Alloca);
612 }
613 MaxAlignment = std::max(AlignmentParam, MaxAlignment);
614 }
615 }
David Sehre39d0ca2015-11-06 11:25:41 -0800616 // Add instructions to the head of the entry block in reverse order.
617 InstList &Insts = getEntryNode()->getInsts();
David Sehr4318a412015-11-11 15:01:55 -0800618 if (HasDynamicAllocation && HasLargeAlignment) {
619 // We are using a frame pointer, but fixed large-alignment alloca addresses,
620 // do not have a known offset from either the stack or frame pointer.
621 // They grow up from a user pointer from an alloca.
622 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800623 // Fixed size allocas are addressed relative to the frame pointer.
624 sortAndCombineAllocas(FixedAllocas, StackAlignment, Insts,
625 BVT_FramePointer);
626 } else {
627 // Otherwise, fixed size allocas are addressed relative to the stack unless
628 // there are dynamic allocas.
629 const AllocaBaseVariableType BasePointerType =
630 (HasDynamicAllocation ? BVT_FramePointer : BVT_StackPointer);
631 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType);
David Sehr4318a412015-11-11 15:01:55 -0800632 }
Jim Stichnoth3607b6c2015-11-13 14:28:23 -0800633 if (!FixedAllocas.empty() || !AlignedAllocas.empty())
634 // No use calling findRematerializable() unless there is some
635 // rematerializable alloca instruction to seed it.
636 findRematerializable();
637}
638
639namespace {
640
641// Helpers for findRematerializable(). For each of them, if a suitable
642// rematerialization is found, the instruction's Dest variable is set to be
643// rematerializable and it returns true, otherwise it returns false.
644
645bool rematerializeArithmetic(const Inst *Instr) {
646 // Check that it's an Arithmetic instruction with an Add operation.
647 auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr);
648 if (Arith == nullptr || Arith->getOp() != InstArithmetic::Add)
649 return false;
650 // Check that Src(0) is rematerializable.
651 auto *Src0Var = llvm::dyn_cast<Variable>(Arith->getSrc(0));
652 if (Src0Var == nullptr || !Src0Var->isRematerializable())
653 return false;
654 // Check that Src(1) is an immediate.
655 auto *Src1Imm = llvm::dyn_cast<ConstantInteger32>(Arith->getSrc(1));
656 if (Src1Imm == nullptr)
657 return false;
658 Arith->getDest()->setRematerializable(
659 Src0Var->getRegNum(), Src0Var->getStackOffset() + Src1Imm->getValue());
660 return true;
661}
662
663bool rematerializeAssign(const Inst *Instr) {
664 // An InstAssign only originates from an inttoptr or ptrtoint instruction,
665 // which never occurs in a MINIMAL build.
666 if (BuildDefs::minimal())
667 return false;
668 // Check that it's an Assign instruction.
669 if (!llvm::isa<InstAssign>(Instr))
670 return false;
671 // Check that Src(0) is rematerializable.
672 auto *Src0Var = llvm::dyn_cast<Variable>(Instr->getSrc(0));
673 if (Src0Var == nullptr || !Src0Var->isRematerializable())
674 return false;
675 Instr->getDest()->setRematerializable(Src0Var->getRegNum(),
676 Src0Var->getStackOffset());
677 return true;
678}
679
680bool rematerializeCast(const Inst *Instr) {
681 // An pointer-type bitcast never occurs in a MINIMAL build.
682 if (BuildDefs::minimal())
683 return false;
684 // Check that it's a Cast instruction with a Bitcast operation.
685 auto *Cast = llvm::dyn_cast<InstCast>(Instr);
686 if (Cast == nullptr || Cast->getCastKind() != InstCast::Bitcast)
687 return false;
688 // Check that Src(0) is rematerializable.
689 auto *Src0Var = llvm::dyn_cast<Variable>(Cast->getSrc(0));
690 if (Src0Var == nullptr || !Src0Var->isRematerializable())
691 return false;
692 // Check that Dest and Src(0) have the same type.
693 Variable *Dest = Cast->getDest();
694 if (Dest->getType() != Src0Var->getType())
695 return false;
696 Dest->setRematerializable(Src0Var->getRegNum(), Src0Var->getStackOffset());
697 return true;
698}
699
700} // end of anonymous namespace
701
702/// Scan the function to find additional rematerializable variables. This is
703/// possible when the source operand of an InstAssignment is a rematerializable
704/// variable, or the same for a pointer-type InstCast::Bitcast, or when an
705/// InstArithmetic is an add of a rematerializable variable and an immediate.
706/// Note that InstAssignment instructions and pointer-type InstCast::Bitcast
707/// instructions generally only come about from the IceConverter's treatment of
708/// inttoptr, ptrtoint, and bitcast instructions. TODO(stichnot): Consider
709/// other possibilities, however unlikely, such as InstArithmetic::Sub, or
710/// commutativity.
711void Cfg::findRematerializable() {
712 // Scan the instructions in order, and repeat until no new opportunities are
713 // found. It may take more than one iteration because a variable's defining
714 // block may happen to come after a block where it is used, depending on the
715 // CfgNode linearization order.
716 bool FoundNewAssignment;
717 do {
718 FoundNewAssignment = false;
719 for (CfgNode *Node : getNodes()) {
720 // No need to process Phi instructions.
721 for (Inst &Instr : Node->getInsts()) {
722 if (Instr.isDeleted())
723 continue;
724 Variable *Dest = Instr.getDest();
725 if (Dest == nullptr || Dest->isRematerializable())
726 continue;
727 if (rematerializeArithmetic(&Instr) || rematerializeAssign(&Instr) ||
728 rematerializeCast(&Instr)) {
729 FoundNewAssignment = true;
730 }
731 }
732 }
733 } while (FoundNewAssignment);
David Sehre39d0ca2015-11-06 11:25:41 -0800734}
735
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700736void Cfg::doAddressOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700737 TimerMarker T(TimerStack::TT_doAddressOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700738 for (CfgNode *Node : Nodes)
739 Node->doAddressOpt();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700740}
741
Matt Walac3302742014-08-15 16:21:56 -0700742void Cfg::doNopInsertion() {
Qining Lu969f6a32015-07-31 09:58:34 -0700743 if (!Ctx->getFlags().shouldDoNopInsertion())
744 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700745 TimerMarker T(TimerStack::TT_doNopInsertion, this);
Qining Luaee5fa82015-08-20 14:59:03 -0700746 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(), RPE_NopInsertion,
747 SequenceNumber);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700748 for (CfgNode *Node : Nodes)
Qining Luaee5fa82015-08-20 14:59:03 -0700749 Node->doNopInsertion(RNG);
Matt Walac3302742014-08-15 16:21:56 -0700750}
751
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700752void Cfg::genCode() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700753 TimerMarker T(TimerStack::TT_genCode, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700754 for (CfgNode *Node : Nodes)
755 Node->genCode();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700756}
757
758// Compute the stack frame layout.
759void Cfg::genFrame() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700760 TimerMarker T(TimerStack::TT_genFrame, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700761 getTarget()->addProlog(Entry);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700762 for (CfgNode *Node : Nodes)
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700763 if (Node->getHasReturn())
764 getTarget()->addEpilog(Node);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700765}
766
Andrew Scullaa6c1092015-09-03 17:50:30 -0700767void Cfg::computeLoopNestDepth() {
768 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this);
769 LoopAnalyzer LA(this);
770 LA.computeLoopNestDepth();
771}
772
Andrew Scull57e12682015-09-16 11:30:19 -0700773// This is a lightweight version of live-range-end calculation. Marks the last
Andrew Scullaa6c1092015-09-03 17:50:30 -0700774// use of only those variables whose definition and uses are completely with a
Andrew Scull57e12682015-09-16 11:30:19 -0700775// single block. It is a quick single pass and doesn't need to iterate until
Andrew Scullaa6c1092015-09-03 17:50:30 -0700776// convergence.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700777void Cfg::livenessLightweight() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700778 TimerMarker T(TimerStack::TT_livenessLightweight, this);
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700779 getVMetadata()->init(VMK_Uses);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700780 for (CfgNode *Node : Nodes)
781 Node->livenessLightweight();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700782}
783
784void Cfg::liveness(LivenessMode Mode) {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700785 TimerMarker T(TimerStack::TT_liveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700786 Live.reset(new Liveness(this, Mode));
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700787 getVMetadata()->init(VMK_Uses);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700788 Live->init();
789 // Initialize with all nodes needing to be processed.
790 llvm::BitVector NeedToProcess(Nodes.size(), true);
791 while (NeedToProcess.any()) {
792 // Iterate in reverse topological order to speed up convergence.
Jim Stichnoth7e571362015-01-09 11:43:26 -0800793 for (CfgNode *Node : reverse_range(Nodes)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700794 if (NeedToProcess[Node->getIndex()]) {
795 NeedToProcess[Node->getIndex()] = false;
796 bool Changed = Node->liveness(getLiveness());
797 if (Changed) {
798 // If the beginning-of-block liveness changed since the last
799 // iteration, mark all in-edges as needing to be processed.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700800 for (CfgNode *Pred : Node->getInEdges())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700801 NeedToProcess[Pred->getIndex()] = true;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700802 }
803 }
804 }
805 }
806 if (Mode == Liveness_Intervals) {
807 // Reset each variable's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700808 for (Variable *Var : Variables)
809 Var->resetLiveRange();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700810 }
Andrew Scull57e12682015-09-16 11:30:19 -0700811 // Make a final pass over each node to delete dead instructions, collect the
812 // first and last instruction numbers, and add live range segments for that
813 // node.
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800814 for (CfgNode *Node : Nodes) {
815 InstNumberT FirstInstNum = Inst::NumberSentinel;
816 InstNumberT LastInstNum = Inst::NumberSentinel;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800817 for (Inst &I : Node->getPhis()) {
818 I.deleteIfDead();
819 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800820 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800821 FirstInstNum = I.getNumber();
822 assert(I.getNumber() > LastInstNum);
823 LastInstNum = I.getNumber();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700824 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800825 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800826 for (Inst &I : Node->getInsts()) {
827 I.deleteIfDead();
828 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800829 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800830 FirstInstNum = I.getNumber();
831 assert(I.getNumber() > LastInstNum);
832 LastInstNum = I.getNumber();
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800833 }
834 }
835 if (Mode == Liveness_Intervals) {
Andrew Scull57e12682015-09-16 11:30:19 -0700836 // Special treatment for live in-args. Their liveness needs to extend
837 // beyond the beginning of the function, otherwise an arg whose only use
838 // is in the first instruction will end up having the trivial live range
839 // [2,2) and will *not* interfere with other arguments. So if the first
840 // instruction of the method is "r=arg1+arg2", both args may be assigned
841 // the same register. This is accomplished by extending the entry block's
842 // instruction range from [2,n) to [1,n) which will transform the
843 // problematic [2,2) live ranges into [1,2).
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700844 if (Node == getEntryNode()) {
Andrew Scull57e12682015-09-16 11:30:19 -0700845 // TODO(stichnot): Make it a strict requirement that the entry node
846 // gets the lowest instruction numbers, so that extending the live
847 // range for in-args is guaranteed to work.
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800848 FirstInstNum = Inst::NumberExtended;
Jim Stichnothe4f65d82015-06-17 22:16:02 -0700849 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800850 Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700851 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700852 }
853}
854
Andrew Scull57e12682015-09-16 11:30:19 -0700855// Traverse every Variable of every Inst and verify that it appears within the
856// Variable's computed live range.
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700857bool Cfg::validateLiveness() const {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700858 TimerMarker T(TimerStack::TT_validateLiveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700859 bool Valid = true;
Jim Stichnothe4a8f402015-01-20 12:52:51 -0800860 OstreamLocker L(Ctx);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700861 Ostream &Str = Ctx->getStrDump();
Jim Stichnothf44f3712014-10-01 14:05:51 -0700862 for (CfgNode *Node : Nodes) {
Jim Stichnothae953202014-12-20 06:17:49 -0800863 Inst *FirstInst = nullptr;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800864 for (Inst &Inst : Node->getInsts()) {
865 if (Inst.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700866 continue;
Jim Stichnothae953202014-12-20 06:17:49 -0800867 if (FirstInst == nullptr)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800868 FirstInst = &Inst;
869 InstNumberT InstNumber = Inst.getNumber();
870 if (Variable *Dest = Inst.getDest()) {
Jim Stichnoth47752552014-10-13 17:15:08 -0700871 if (!Dest->getIgnoreLiveness()) {
872 bool Invalid = false;
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700873 constexpr bool IsDest = true;
Jim Stichnoth47752552014-10-13 17:15:08 -0700874 if (!Dest->getLiveRange().containsValue(InstNumber, IsDest))
875 Invalid = true;
Andrew Scull57e12682015-09-16 11:30:19 -0700876 // Check that this instruction actually *begins* Dest's live range,
877 // by checking that Dest is not live in the previous instruction. As
878 // a special exception, we don't check this for the first instruction
879 // of the block, because a Phi temporary may be live at the end of
880 // the previous block, and if it is also assigned in the first
881 // instruction of this block, the adjacent live ranges get merged.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800882 if (static_cast<class Inst *>(&Inst) != FirstInst &&
Jim Stichnoth230d41012015-09-25 17:40:32 -0700883 !Inst.isDestRedefined() &&
Jim Stichnoth47752552014-10-13 17:15:08 -0700884 Dest->getLiveRange().containsValue(InstNumber - 1, IsDest))
885 Invalid = true;
886 if (Invalid) {
887 Valid = false;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800888 Str << "Liveness error: inst " << Inst.getNumber() << " dest ";
Jim Stichnoth47752552014-10-13 17:15:08 -0700889 Dest->dump(this);
890 Str << " live range " << Dest->getLiveRange() << "\n";
891 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700892 }
893 }
John Portoec3f5652015-08-31 15:07:09 -0700894 FOREACH_VAR_IN_INST(Var, Inst) {
895 static constexpr bool IsDest = false;
896 if (!Var->getIgnoreLiveness() &&
897 !Var->getLiveRange().containsValue(InstNumber, IsDest)) {
898 Valid = false;
899 Str << "Liveness error: inst " << Inst.getNumber() << " var ";
900 Var->dump(this);
901 Str << " live range " << Var->getLiveRange() << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700902 }
903 }
904 }
905 }
906 return Valid;
907}
908
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700909void Cfg::contractEmptyNodes() {
Andrew Scullaa6c1092015-09-03 17:50:30 -0700910 // If we're decorating the asm output with register liveness info, this
911 // information may become corrupted or incorrect after contracting nodes that
912 // contain only redundant assignments. As such, we disable this pass when
913 // DecorateAsm is specified. This may make the resulting code look more
914 // branchy, but it should have no effect on the register assignments.
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800915 if (Ctx->getFlags().getDecorateAsm())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700916 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700917 for (CfgNode *Node : Nodes) {
918 Node->contractIfEmpty();
919 }
920}
921
Jim Stichnothff9c7062014-09-18 04:50:49 -0700922void Cfg::doBranchOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700923 TimerMarker T(TimerStack::TT_doBranchOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700924 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
Andrew Scull713278a2015-07-22 17:17:02 -0700925 auto NextNode = I + 1;
Jim Stichnothae953202014-12-20 06:17:49 -0800926 (*I)->doBranchOpt(NextNode == E ? nullptr : *NextNode);
Jim Stichnothff9c7062014-09-18 04:50:49 -0700927 }
928}
929
Andrew Scull86df4e92015-07-30 13:54:44 -0700930void Cfg::markNodesForSandboxing() {
931 for (const InstJumpTable *JT : JumpTables)
932 for (SizeT I = 0; I < JT->getNumTargets(); ++I)
933 JT->getTarget(I)->setNeedsAlignment();
934}
935
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700936// ======================== Dump routines ======================== //
937
Andrew Scull57e12682015-09-16 11:30:19 -0700938// emitTextHeader() is not target-specific (apart from what is abstracted by
939// the Assembler), so it is defined here rather than in the target lowering
940// class.
Jim Stichnothbbca7542015-02-11 16:08:31 -0800941void Cfg::emitTextHeader(const IceString &MangledName, GlobalContext *Ctx,
942 const Assembler *Asm) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700943 if (!BuildDefs::dump())
Jim Stichnoth729dbd02015-02-25 14:48:43 -0800944 return;
Jan Voung0faec4c2014-11-05 17:29:56 -0800945 Ostream &Str = Ctx->getStrEmit();
946 Str << "\t.text\n";
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800947 if (Ctx->getFlags().getFunctionSections())
John Portoafc92af2015-10-16 10:34:04 -0700948 Str << "\t.section\t.text." << MangledName << ",\"ax\",%progbits\n";
Jim Stichnothbbca7542015-02-11 16:08:31 -0800949 if (!Asm->getInternal() || Ctx->getFlags().getDisableInternal()) {
Jan Voung0faec4c2014-11-05 17:29:56 -0800950 Str << "\t.globl\t" << MangledName << "\n";
Jan Voungb2d50842015-05-12 09:53:50 -0700951 Str << "\t.type\t" << MangledName << ",%function\n";
Jan Voung0faec4c2014-11-05 17:29:56 -0800952 }
Andrew Scull86df4e92015-07-30 13:54:44 -0700953 Str << "\t" << Asm->getAlignDirective() << " "
Jan Voungb2d50842015-05-12 09:53:50 -0700954 << Asm->getBundleAlignLog2Bytes() << ",0x";
Jan Voung08c3bcd2014-12-01 17:55:16 -0800955 for (uint8_t I : Asm->getNonExecBundlePadding())
Jan Voung0faec4c2014-11-05 17:29:56 -0800956 Str.write_hex(I);
957 Str << "\n";
958 Str << MangledName << ":\n";
959}
960
Andrew Scull86df4e92015-07-30 13:54:44 -0700961void Cfg::deleteJumpTableInsts() {
962 for (InstJumpTable *JumpTable : JumpTables)
963 JumpTable->setDeleted();
964}
965
966void Cfg::emitJumpTables() {
967 switch (Ctx->getFlags().getOutFileType()) {
968 case FT_Elf:
969 case FT_Iasm: {
Andrew Scull57e12682015-09-16 11:30:19 -0700970 // The emission needs to be delayed until the after the text section so
971 // save the offsets in the global context.
Andrew Scull86df4e92015-07-30 13:54:44 -0700972 IceString MangledName = Ctx->mangleName(getFunctionName());
973 for (const InstJumpTable *JumpTable : JumpTables) {
974 SizeT NumTargets = JumpTable->getNumTargets();
David Sehr0fe6b542015-11-19 21:47:15 -0800975 JumpTableData::TargetList TargetList;
Andrew Scull86df4e92015-07-30 13:54:44 -0700976 for (SizeT I = 0; I < NumTargets; ++I) {
977 SizeT Index = JumpTable->getTarget(I)->getIndex();
David Sehr0fe6b542015-11-19 21:47:15 -0800978 TargetList.emplace_back(
979 getAssembler()->getCfgNodeLabel(Index)->getPosition());
Andrew Scull86df4e92015-07-30 13:54:44 -0700980 }
David Sehr0fe6b542015-11-19 21:47:15 -0800981 Ctx->addJumpTable(MangledName, JumpTable->getId(), TargetList);
Andrew Scull86df4e92015-07-30 13:54:44 -0700982 }
983 } break;
984 case FT_Asm: {
985 // Emit the assembly directly so we don't need to hang on to all the names
986 for (const InstJumpTable *JumpTable : JumpTables)
987 getTarget()->emitJumpTable(this, JumpTable);
988 } break;
Andrew Scull86df4e92015-07-30 13:54:44 -0700989 }
990}
991
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700992void Cfg::emit() {
Jim Stichnoth20b71f52015-06-24 15:52:24 -0700993 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800994 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700995 TimerMarker T(TimerStack::TT_emit, this);
Karl Schimpfdf80eb82015-02-09 14:20:22 -0800996 if (Ctx->getFlags().getDecorateAsm()) {
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700997 renumberInstructions();
998 getVMetadata()->init(VMK_Uses);
999 liveness(Liveness_Basic);
1000 dump("After recomputing liveness for -decorate-asm");
1001 }
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001002 OstreamLocker L(Ctx);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001003 Ostream &Str = Ctx->getStrEmit();
Andrew Scull86df4e92015-07-30 13:54:44 -07001004 IceString MangledName = Ctx->mangleName(getFunctionName());
1005 const Assembler *Asm = getAssembler<>();
1006 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
1007
1008 emitTextHeader(MangledName, Ctx, Asm);
1009 deleteJumpTableInsts();
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001010 if (Ctx->getFlags().getDecorateAsm()) {
1011 for (Variable *Var : getVariables()) {
Jim Stichnoth3607b6c2015-11-13 14:28:23 -08001012 if (Var->getStackOffset() && !Var->isRematerializable()) {
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001013 Str << "\t" << Var->getSymbolicStackOffset(this) << " = "
1014 << Var->getStackOffset() << "\n";
1015 }
1016 }
1017 }
Andrew Scull86df4e92015-07-30 13:54:44 -07001018 for (CfgNode *Node : Nodes) {
1019 if (NeedSandboxing && Node->needsAlignment()) {
1020 Str << "\t" << Asm->getAlignDirective() << " "
1021 << Asm->getBundleAlignLog2Bytes() << "\n";
1022 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07001023 Node->emit(this);
Andrew Scull86df4e92015-07-30 13:54:44 -07001024 }
1025 emitJumpTables();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001026 Str << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001027}
1028
Jan Voung0faec4c2014-11-05 17:29:56 -08001029void Cfg::emitIAS() {
1030 TimerMarker T(TimerStack::TT_emit, this);
Andrew Scull57e12682015-09-16 11:30:19 -07001031 // The emitIAS() routines emit into the internal assembler buffer, so there's
1032 // no need to lock the streams.
Andrew Scull86df4e92015-07-30 13:54:44 -07001033 deleteJumpTableInsts();
1034 const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing();
1035 for (CfgNode *Node : Nodes) {
1036 if (NeedSandboxing && Node->needsAlignment())
1037 getAssembler()->alignCfgNode();
Jan Voung0faec4c2014-11-05 17:29:56 -08001038 Node->emitIAS(this);
Andrew Scull86df4e92015-07-30 13:54:44 -07001039 }
1040 emitJumpTables();
Jan Voung0faec4c2014-11-05 17:29:56 -08001041}
1042
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001043// Dumps the IR with an optional introductory message.
1044void Cfg::dump(const IceString &Message) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001045 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001046 return;
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001047 if (!isVerbose())
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001048 return;
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001049 OstreamLocker L(Ctx);
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001050 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001051 if (!Message.empty())
1052 Str << "================ " << Message << " ================\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001053 setCurrentNode(getEntryNode());
1054 // Print function name+args
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001055 if (isVerbose(IceV_Instructions)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001056 Str << "define ";
Karl Schimpfdf80eb82015-02-09 14:20:22 -08001057 if (getInternal() && !Ctx->getFlags().getDisableInternal())
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001058 Str << "internal ";
Karl Schimpfdf6f9d12014-10-20 14:09:00 -07001059 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001060 for (SizeT i = 0; i < Args.size(); ++i) {
1061 if (i > 0)
1062 Str << ", ";
1063 Str << Args[i]->getType() << " ";
1064 Args[i]->dump(this);
1065 }
1066 Str << ") {\n";
1067 }
Jim Stichnoth800dab22014-09-20 12:25:02 -07001068 resetCurrentNode();
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001069 if (isVerbose(IceV_Liveness)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001070 // Print summary info about variables
Jim Stichnothf44f3712014-10-01 14:05:51 -07001071 for (Variable *Var : Variables) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001072 Str << "// multiblock=";
1073 if (getVMetadata()->isTracked(Var))
1074 Str << getVMetadata()->isMultiBlock(Var);
1075 else
1076 Str << "?";
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07001077 Str << " defs=";
1078 bool FirstPrint = true;
1079 if (VMetadata->getKind() != VMK_Uses) {
1080 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) {
1081 Str << FirstDef->getNumber();
1082 FirstPrint = false;
1083 }
1084 }
1085 if (VMetadata->getKind() == VMK_All) {
1086 for (const Inst *Instr : VMetadata->getLatterDefinitions(Var)) {
1087 if (!FirstPrint)
1088 Str << ",";
1089 Str << Instr->getNumber();
1090 FirstPrint = false;
1091 }
1092 }
Andrew Scull11c9a322015-08-28 14:24:14 -07001093 Str << " weight=" << Var->getWeight(this) << " ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001094 Var->dump(this);
1095 Str << " LIVE=" << Var->getLiveRange() << "\n";
1096 }
1097 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001098 // Print each basic block
Jim Stichnothf44f3712014-10-01 14:05:51 -07001099 for (CfgNode *Node : Nodes)
1100 Node->dump(this);
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001101 if (isVerbose(IceV_Instructions))
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001102 Str << "}\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001103}
1104
1105} // end of namespace Ice