blob: a113b95d47948ddd03c1bbe7bd864c2aa3642bd5 [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
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Implements the Cfg class.
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"
John Porto36d6aa62016-02-26 07:19:59 -080018#include "IceBitVector.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070019#include "IceCfgNode.h"
Jim Stichnoth989a7032014-08-08 10:13:44 -070020#include "IceClFlags.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070021#include "IceDefs.h"
Jan Voungec270732015-01-12 17:00:22 -080022#include "IceELFObjectWriter.h"
John Portof8b4cc82015-06-09 18:06:19 -070023#include "IceGlobalInits.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070024#include "IceInst.h"
Thomas Livelyaab70992016-06-07 13:54:59 -070025#include "IceInstrumentation.h"
John Portoec3f5652015-08-31 15:07:09 -070026#include "IceInstVarIter.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070027#include "IceLiveness.h"
Andrew Scullaa6c1092015-09-03 17:50:30 -070028#include "IceLoopAnalyzer.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070029#include "IceOperand.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070030#include "IceTargetLowering.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070031
John Porto7bb9cab2016-04-01 05:43:09 -070032#include <memory>
33#include <utility>
34
Jim Stichnothf7c9a142014-04-29 10:52:43 -070035namespace Ice {
36
Jim Stichnothbbca7542015-02-11 16:08:31 -080037Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
Karl Schimpfd4699942016-04-02 09:55:31 -070038 : Ctx(Ctx), SequenceNumber(SequenceNumber), VMask(getFlags().getVerbose()),
39 FunctionName(), NextInstNumber(Inst::NumberInitial), Live(nullptr) {
John Porto44b3ce82016-02-26 13:10:55 -080040 Allocator.reset(new ArenaAllocator());
Jim Stichnoth467ffe52016-03-29 15:01:06 -070041 NodeStrings.reset(new StringPool);
42 VarStrings.reset(new StringPool);
John Porto44b3ce82016-02-26 13:10:55 -080043 CfgLocalAllocatorScope _(this);
Karl Schimpfd4699942016-04-02 09:55:31 -070044 Target = TargetLowering::createLowering(getFlags().getTargetArch(), this);
John Porto44b3ce82016-02-26 13:10:55 -080045 VMetadata.reset(new VariablesMetadata(this));
46 TargetAssembler = Target->createAssembler();
47
Karl Schimpfd4699942016-04-02 09:55:31 -070048 if (getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Randomize) {
Andrew Scull57e12682015-09-16 11:30:19 -070049 // If -randomize-pool-immediates=randomize, create a random number
50 // generator to generate a cookie for constant blinding.
Karl Schimpfd4699942016-04-02 09:55:31 -070051 RandomNumberGenerator RNG(getFlags().getRandomSeed(), RPE_ConstantBlinding,
52 this->SequenceNumber);
Qining Luaee5fa82015-08-20 14:59:03 -070053 ConstantBlindingCookie =
Qining Lu360e3192015-08-20 17:13:07 -070054 (uint32_t)RNG.next((uint64_t)std::numeric_limits<uint32_t>::max() + 1);
Qining Luaee5fa82015-08-20 14:59:03 -070055 }
Karl Schimpf6fcbddd2014-11-06 09:49:24 -080056}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070057
Jim Stichnoth467ffe52016-03-29 15:01:06 -070058Cfg::~Cfg() {
59 assert(CfgAllocatorTraits::current() == nullptr);
Karl Schimpfd4699942016-04-02 09:55:31 -070060 if (getFlags().getDumpStrings()) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -070061 OstreamLocker _(Ctx);
62 Ostream &Str = Ctx->getStrDump();
63 getNodeStrings()->dump(Str);
64 getVarStrings()->dump(Str);
65 }
66}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067
Jim Stichnothb40595a2016-01-29 06:14:31 -080068/// Create a string like "foo(i=123:b=9)" indicating the function name, number
69/// of high-level instructions, and number of basic blocks. This string is only
70/// used for dumping and other diagnostics, and the idea is that given a set of
71/// functions to debug a problem on, it's easy to find the smallest or simplest
72/// function to attack. Note that the counts may change somewhat depending on
73/// what point it is called during the translation passes.
Jim Stichnoth467ffe52016-03-29 15:01:06 -070074std::string Cfg::getFunctionNameAndSize() const {
Jim Stichnothb40595a2016-01-29 06:14:31 -080075 if (!BuildDefs::dump())
Jim Stichnoth467ffe52016-03-29 15:01:06 -070076 return getFunctionName().toString();
Jim Stichnothb40595a2016-01-29 06:14:31 -080077 SizeT NodeCount = 0;
78 SizeT InstCount = 0;
79 for (CfgNode *Node : getNodes()) {
80 ++NodeCount;
81 // Note: deleted instructions are *not* ignored.
82 InstCount += Node->getPhis().size();
83 for (Inst &I : Node->getInsts()) {
84 if (!llvm::isa<InstTarget>(&I))
85 ++InstCount;
86 }
87 }
88 return getFunctionName() + "(i=" + std::to_string(InstCount) + ":b=" +
89 std::to_string(NodeCount) + ")";
90}
91
Jim Stichnoth467ffe52016-03-29 15:01:06 -070092void Cfg::setError(const std::string &Message) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -070093 HasError = true;
94 ErrorMessage = Message;
Jim Stichnothf7c9a142014-04-29 10:52:43 -070095}
96
Jim Stichnoth668a7a32014-12-10 15:32:25 -080097CfgNode *Cfg::makeNode() {
Jim Stichnothf7c9a142014-04-29 10:52:43 -070098 SizeT LabelIndex = Nodes.size();
Jim Stichnoth54f3d512015-12-11 09:53:00 -080099 auto *Node = CfgNode::create(this, LabelIndex);
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700100 Nodes.push_back(Node);
101 return Node;
102}
103
Karl Schimpfac7d7342015-08-06 12:55:23 -0700104void Cfg::swapNodes(NodeList &NewNodes) {
Jim Stichnothe7dbc0b2015-09-15 10:09:24 -0700105 assert(Nodes.size() == NewNodes.size());
Karl Schimpfac7d7342015-08-06 12:55:23 -0700106 Nodes.swap(NewNodes);
107 for (SizeT I = 0, NumNodes = getNumNodes(); I < NumNodes; ++I)
108 Nodes[I]->resetIndex(I);
109}
110
John Portoa83bfde2015-09-18 08:43:02 -0700111template <> Variable *Cfg::makeVariable<Variable>(Type Ty) {
Andrew Scull6d47bcd2015-09-17 17:10:05 -0700112 SizeT Index = Variables.size();
113 Variable *Var = Target->shouldSplitToVariable64On32(Ty)
114 ? Variable64On32::create(this, Ty, Index)
115 : Variable::create(this, Ty, Index);
116 Variables.push_back(Var);
117 return Var;
118}
119
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700120void Cfg::addArg(Variable *Arg) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700121 Arg->setIsArg();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700122 Args.push_back(Arg);
123}
124
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700125void Cfg::addImplicitArg(Variable *Arg) {
126 Arg->setIsImplicitArg();
127 ImplicitArgs.push_back(Arg);
128}
129
Andrew Scull57e12682015-09-16 11:30:19 -0700130// Returns whether the stack frame layout has been computed yet. This is used
131// for dumping the stack frame location of Variables.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700132bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); }
133
John Portof8b4cc82015-06-09 18:06:19 -0700134namespace {
135constexpr char BlockNameGlobalPrefix[] = ".L$profiler$block_name$";
136constexpr char BlockStatsGlobalPrefix[] = ".L$profiler$block_info$";
John Portoa78e4ba2016-03-15 09:28:04 -0700137} // end of anonymous namespace
John Portof8b4cc82015-06-09 18:06:19 -0700138
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700139void Cfg::createNodeNameDeclaration(const std::string &NodeAsmName) {
John Portoa78e4ba2016-03-15 09:28:04 -0700140 auto *Var = VariableDeclaration::create(GlobalInits.get());
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700141 Var->setName(Ctx, BlockNameGlobalPrefix + NodeAsmName);
John Portof8b4cc82015-06-09 18:06:19 -0700142 Var->setIsConstant(true);
John Porto1bec8bc2015-06-22 10:51:13 -0700143 Var->addInitializer(VariableDeclaration::DataInitializer::create(
John Portoa78e4ba2016-03-15 09:28:04 -0700144 GlobalInits.get(), NodeAsmName.data(), NodeAsmName.size() + 1));
John Portof8b4cc82015-06-09 18:06:19 -0700145 const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
146 Var->setAlignment(Int64ByteSize); // Wasteful, 32-bit could use 4 bytes.
John Portoa78e4ba2016-03-15 09:28:04 -0700147 GlobalInits->push_back(Var);
John Portof8b4cc82015-06-09 18:06:19 -0700148}
149
John Portoa78e4ba2016-03-15 09:28:04 -0700150void Cfg::createBlockProfilingInfoDeclaration(
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700151 const std::string &NodeAsmName, VariableDeclaration *NodeNameDeclaration) {
John Portoa78e4ba2016-03-15 09:28:04 -0700152 auto *Var = VariableDeclaration::create(GlobalInits.get());
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700153 Var->setName(Ctx, BlockStatsGlobalPrefix + NodeAsmName);
John Portof8b4cc82015-06-09 18:06:19 -0700154 const SizeT Int64ByteSize = typeWidthInBytes(IceType_i64);
John Portoa78e4ba2016-03-15 09:28:04 -0700155 Var->addInitializer(VariableDeclaration::ZeroInitializer::create(
156 GlobalInits.get(), Int64ByteSize));
John Portof8b4cc82015-06-09 18:06:19 -0700157
158 const RelocOffsetT NodeNameDeclarationOffset = 0;
John Porto1bec8bc2015-06-22 10:51:13 -0700159 Var->addInitializer(VariableDeclaration::RelocInitializer::create(
John Portoa78e4ba2016-03-15 09:28:04 -0700160 GlobalInits.get(), NodeNameDeclaration,
John Porto844211e2016-02-04 08:42:48 -0800161 {RelocOffset::create(Ctx, NodeNameDeclarationOffset)}));
John Portof8b4cc82015-06-09 18:06:19 -0700162 Var->setAlignment(Int64ByteSize);
John Portoa78e4ba2016-03-15 09:28:04 -0700163 GlobalInits->push_back(Var);
John Portof8b4cc82015-06-09 18:06:19 -0700164}
John Portof8b4cc82015-06-09 18:06:19 -0700165
166void Cfg::profileBlocks() {
167 if (GlobalInits == nullptr)
168 GlobalInits.reset(new VariableDeclarationList());
169
170 for (CfgNode *Node : Nodes) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700171 const std::string NodeAsmName = Node->getAsmName();
John Portoa78e4ba2016-03-15 09:28:04 -0700172 createNodeNameDeclaration(NodeAsmName);
173 createBlockProfilingInfoDeclaration(NodeAsmName, GlobalInits->back());
John Portof8b4cc82015-06-09 18:06:19 -0700174 Node->profileExecutionCount(GlobalInits->back());
175 }
176}
177
178bool Cfg::isProfileGlobal(const VariableDeclaration &Var) {
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700179 if (!Var.getName().hasStdString())
180 return false;
181 return Var.getName().toString().find(BlockStatsGlobalPrefix) == 0;
John Portof8b4cc82015-06-09 18:06:19 -0700182}
183
184void Cfg::addCallToProfileSummary() {
185 // The call(s) to __Sz_profile_summary are added by the profiler in functions
186 // that cause the program to exit. This function is defined in
187 // runtime/szrt_profiler.c.
188 Constant *ProfileSummarySym =
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700189 Ctx->getConstantExternSym(Ctx->getGlobalString("__Sz_profile_summary"));
John Portof8b4cc82015-06-09 18:06:19 -0700190 constexpr SizeT NumArgs = 0;
191 constexpr Variable *Void = nullptr;
192 constexpr bool HasTailCall = false;
193 auto *Call =
194 InstCall::create(this, NumArgs, Void, ProfileSummarySym, HasTailCall);
195 getEntryNode()->getInsts().push_front(Call);
196}
197
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700198void Cfg::translate() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700199 if (hasError())
200 return;
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700201 // Cache the possibly-overridden optimization level once translation begins.
202 // It would be nicer to do this in the constructor, but we need to wait until
203 // after setFunctionName() has a chance to be called.
204 OptimizationLevel =
205 getFlags().matchForceO2(getFunctionName(), getSequenceNumber())
206 ? Opt_2
207 : getFlags().getOptLevel();
Jim Stichnoth318c01b2016-04-03 21:58:03 -0700208 if (BuildDefs::timers()) {
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700209 if (getFlags().matchTimingFocus(getFunctionName(), getSequenceNumber())) {
210 setFocusedTiming();
211 getContext()->resetTimer(GlobalContext::TSK_Default);
Jim Stichnoth1c44d812014-12-08 14:57:52 -0800212 }
Jim Stichnoth318c01b2016-04-03 21:58:03 -0700213 }
214 if (BuildDefs::dump()) {
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700215 if (isVerbose(IceV_Status) &&
216 getFlags().matchTestStatus(getFunctionName(), getSequenceNumber())) {
Jim Stichnoth3dd1bb82016-02-27 09:05:50 -0800217 getContext()->getStrDump() << ">>>Translating "
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700218 << getFunctionNameAndSize()
219 << " seq=" << getSequenceNumber() << "\n";
Jim Stichnoth3dd1bb82016-02-27 09:05:50 -0800220 }
Jim Stichnothd14b1a02014-10-08 08:28:36 -0700221 }
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700222 TimerMarker T_func(getContext(), getFunctionName().toStringOrEmpty());
Jim Stichnoth8363a062014-10-07 10:02:38 -0700223 TimerMarker T(TimerStack::TT_translate, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700224
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700225 dump("Initial CFG");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700226
Karl Schimpfd4699942016-04-02 09:55:31 -0700227 if (getFlags().getEnableBlockProfile()) {
John Portof8b4cc82015-06-09 18:06:19 -0700228 profileBlocks();
Andrew Scull57e12682015-09-16 11:30:19 -0700229 // TODO(jpp): this is fragile, at best. Figure out a better way of
230 // detecting exit functions.
Jim Stichnothdd6dcfa2016-04-18 12:52:09 -0700231 if (getFunctionName().toStringOrEmpty() == "exit") {
John Portof8b4cc82015-06-09 18:06:19 -0700232 addCallToProfileSummary();
233 }
234 dump("Profiled CFG");
235 }
236
Jim Stichnothbe87b2e2015-09-18 15:43:59 -0700237 // Create the Hi and Lo variables where a split was needed
238 for (Variable *Var : Variables)
Jim Stichnoth5bff61c2015-10-28 09:26:00 -0700239 if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Var))
Jim Stichnothbe87b2e2015-09-18 15:43:59 -0700240 Var64On32->initHiLo(this);
241
Thomas Livelyaab70992016-06-07 13:54:59 -0700242 // Instrument the Cfg, e.g. with AddressSanitizer
243 if (!BuildDefs::minimal() && getFlags().getSanitizeAddresses()) {
244 getContext()->instrumentFunc(this);
245 dump("Instrumented CFG");
246 }
247
Andrew Scull57e12682015-09-16 11:30:19 -0700248 // The set of translation passes and their order are determined by the
249 // target.
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700250 getTarget()->translate();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700251
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700252 dump("Final output");
Jim Stichnoth318c01b2016-04-03 21:58:03 -0700253 if (getFocusedTiming()) {
Jim Stichnoth2b000fd2016-04-06 06:37:15 -0700254 getContext()->dumpLocalTimers(getFunctionName().toString());
Jim Stichnoth318c01b2016-04-03 21:58:03 -0700255 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700256}
257
Eric Holk16f80612016-04-04 17:07:42 -0700258void Cfg::fixPhiNodes() {
259 for (auto *Node : Nodes) {
260 // Fix all the phi edges since WASM can't tell how to make them correctly at
261 // the beginning.
262 assert(Node);
263 const auto &InEdges = Node->getInEdges();
264 for (auto &Instr : Node->getPhis()) {
265 auto *Phi = llvm::cast<InstPhi>(&Instr);
266 assert(Phi);
267 for (SizeT i = 0; i < InEdges.size(); ++i) {
268 Phi->setLabel(i, InEdges[i]);
269 }
270 }
271 }
272}
273
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700274void Cfg::computeInOutEdges() {
275 // Compute the out-edges.
Eric Holk085bdae2016-04-18 15:08:19 -0700276 for (CfgNode *Node : Nodes) {
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700277 Node->computeSuccessors();
Eric Holk085bdae2016-04-18 15:08:19 -0700278 }
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700279
280 // Prune any unreachable nodes before computing in-edges.
281 SizeT NumNodes = getNumNodes();
John Porto36d6aa62016-02-26 07:19:59 -0800282 BitVector Reachable(NumNodes);
283 BitVector Pending(NumNodes);
Jim Stichnoth69d3f9c2015-03-23 10:33:38 -0700284 Pending.set(getEntryNode()->getIndex());
285 while (true) {
286 int Index = Pending.find_first();
287 if (Index == -1)
288 break;
289 Pending.reset(Index);
290 Reachable.set(Index);
291 CfgNode *Node = Nodes[Index];
292 assert(Node->getIndex() == (SizeT)Index);
293 for (CfgNode *Succ : Node->getOutEdges()) {
294 SizeT SuccIndex = Succ->getIndex();
295 if (!Reachable.test(SuccIndex))
296 Pending.set(SuccIndex);
297 }
298 }
299 SizeT Dest = 0;
300 for (SizeT Source = 0; Source < NumNodes; ++Source) {
301 if (Reachable.test(Source)) {
302 Nodes[Dest] = Nodes[Source];
303 Nodes[Dest]->resetIndex(Dest);
304 // Compute the in-edges.
305 Nodes[Dest]->computePredecessors();
306 ++Dest;
307 }
308 }
309 Nodes.resize(Dest);
Jim Stichnoth1aca2302015-09-16 11:25:22 -0700310
311 TimerMarker T(TimerStack::TT_phiValidation, this);
312 for (CfgNode *Node : Nodes)
David Sehr263ac522016-04-04 10:11:08 -0700313 Node->enforcePhiConsistency();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700314}
315
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700316void Cfg::renumberInstructions() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700317 TimerMarker T(TimerStack::TT_renumberInstructions, this);
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800318 NextInstNumber = Inst::NumberInitial;
Jim Stichnothf44f3712014-10-01 14:05:51 -0700319 for (CfgNode *Node : Nodes)
320 Node->renumberInstructions();
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -0800321 // Make sure the entry node is the first node and therefore got the lowest
322 // instruction numbers, to facilitate live range computation of function
323 // arguments. We want to model function arguments as being live on entry to
324 // the function, otherwise an argument whose only use is in the first
325 // instruction will be assigned a trivial live range and the register
326 // allocator will not recognize its live range as overlapping another
327 // variable's live range.
328 assert(Nodes.empty() || (*Nodes.begin() == getEntryNode()));
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700329}
330
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700331// placePhiLoads() must be called before placePhiStores().
332void Cfg::placePhiLoads() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700333 TimerMarker T(TimerStack::TT_placePhiLoads, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700334 for (CfgNode *Node : Nodes)
335 Node->placePhiLoads();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700336}
337
338// placePhiStores() must be called after placePhiLoads().
339void Cfg::placePhiStores() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700340 TimerMarker T(TimerStack::TT_placePhiStores, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700341 for (CfgNode *Node : Nodes)
342 Node->placePhiStores();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700343}
344
345void Cfg::deletePhis() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700346 TimerMarker T(TimerStack::TT_deletePhis, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700347 for (CfgNode *Node : Nodes)
348 Node->deletePhis();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700349}
350
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700351void Cfg::advancedPhiLowering() {
352 TimerMarker T(TimerStack::TT_advancedPhiLowering, this);
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700353 // Clear all previously computed live ranges (but not live-in/live-out bit
354 // vectors or last-use markers), because the follow-on register allocation is
355 // only concerned with live ranges across the newly created blocks.
356 for (Variable *Var : Variables) {
357 Var->getLiveRange().reset();
358 }
Andrew Scull57e12682015-09-16 11:30:19 -0700359 // This splits edges and appends new nodes to the end of the node list. This
360 // can invalidate iterators, so don't use an iterator.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700361 SizeT NumNodes = getNumNodes();
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700362 SizeT NumVars = getNumVariables();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700363 for (SizeT I = 0; I < NumNodes; ++I)
364 Nodes[I]->advancedPhiLowering();
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700365
366 TimerMarker TT(TimerStack::TT_lowerPhiAssignments, this);
367 if (true) {
Andrew Scull57e12682015-09-16 11:30:19 -0700368 // The following code does an in-place update of liveness and live ranges
369 // as a result of adding the new phi edge split nodes.
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700370 getLiveness()->initPhiEdgeSplits(Nodes.begin() + NumNodes,
371 Variables.begin() + NumVars);
372 TimerMarker TTT(TimerStack::TT_liveness, this);
373 // Iterate over the newly added nodes to add their liveness info.
374 for (auto I = Nodes.begin() + NumNodes, E = Nodes.end(); I != E; ++I) {
375 InstNumberT FirstInstNum = getNextInstNumber();
376 (*I)->renumberInstructions();
377 InstNumberT LastInstNum = getNextInstNumber() - 1;
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700378 (*I)->liveness(getLiveness());
379 (*I)->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
380 }
381 } else {
382 // The following code does a brute-force recalculation of live ranges as a
Andrew Scull57e12682015-09-16 11:30:19 -0700383 // result of adding the new phi edge split nodes. The liveness calculation
Jim Stichnotha3f57b92015-07-30 12:46:04 -0700384 // is particularly expensive because the new nodes are not yet in a proper
385 // topological order and so convergence is slower.
386 //
387 // This code is kept here for reference and can be temporarily enabled in
388 // case the incremental code is under suspicion.
389 renumberInstructions();
390 liveness(Liveness_Intervals);
391 getVMetadata()->init(VMK_All);
392 }
393 Target->regAlloc(RAK_Phi);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700394}
395
Andrew Scull57e12682015-09-16 11:30:19 -0700396// Find a reasonable placement for nodes that have not yet been placed, while
397// maintaining the same relative ordering among already placed nodes.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700398void Cfg::reorderNodes() {
Andrew Scull57e12682015-09-16 11:30:19 -0700399 // TODO(ascull): it would be nice if the switch tests were always followed by
400 // the default case to allow for fall through.
Andrew Scull00741a02015-09-16 19:04:09 -0700401 using PlacedList = CfgList<CfgNode *>;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700402 PlacedList Placed; // Nodes with relative placement locked down
403 PlacedList Unreachable; // Unreachable nodes
404 PlacedList::iterator NoPlace = Placed.end();
Andrew Scull57e12682015-09-16 11:30:19 -0700405 // Keep track of where each node has been tentatively placed so that we can
406 // manage insertions into the middle.
Andrew Scull00741a02015-09-16 19:04:09 -0700407 CfgVector<PlacedList::iterator> PlaceIndex(Nodes.size(), NoPlace);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700408 for (CfgNode *Node : Nodes) {
Andrew Scull57e12682015-09-16 11:30:19 -0700409 // The "do ... while(0);" construct is to factor out the --PlaceIndex and
410 // assert() statements before moving to the next node.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700411 do {
Andrew Scull713278a2015-07-22 17:17:02 -0700412 if (Node != getEntryNode() && Node->getInEdges().empty()) {
Andrew Scull57e12682015-09-16 11:30:19 -0700413 // The node has essentially been deleted since it is not a successor of
414 // any other node.
Andrew Scull713278a2015-07-22 17:17:02 -0700415 Unreachable.push_back(Node);
416 PlaceIndex[Node->getIndex()] = Unreachable.end();
417 Node->setNeedsPlacement(false);
418 continue;
419 }
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700420 if (!Node->needsPlacement()) {
421 // Add to the end of the Placed list.
422 Placed.push_back(Node);
423 PlaceIndex[Node->getIndex()] = Placed.end();
424 continue;
425 }
426 Node->setNeedsPlacement(false);
Andrew Scull57e12682015-09-16 11:30:19 -0700427 // Assume for now that the unplaced node is from edge-splitting and
428 // therefore has 1 in-edge and 1 out-edge (actually, possibly more than 1
429 // in-edge if the predecessor node was contracted). If this changes in
430 // the future, rethink the strategy.
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700431 assert(Node->getInEdges().size() >= 1);
Eric Holk16f80612016-04-04 17:07:42 -0700432 assert(Node->hasSingleOutEdge());
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700433
434 // If it's a (non-critical) edge where the successor has a single
435 // in-edge, then place it before the successor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800436 CfgNode *Succ = Node->getOutEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700437 if (Succ->getInEdges().size() == 1 &&
438 PlaceIndex[Succ->getIndex()] != NoPlace) {
439 Placed.insert(PlaceIndex[Succ->getIndex()], Node);
440 PlaceIndex[Node->getIndex()] = PlaceIndex[Succ->getIndex()];
441 continue;
442 }
443
444 // Otherwise, place it after the (first) predecessor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800445 CfgNode *Pred = Node->getInEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700446 auto PredPosition = PlaceIndex[Pred->getIndex()];
Andrew Scull57e12682015-09-16 11:30:19 -0700447 // It shouldn't be the case that PredPosition==NoPlace, but if that
448 // somehow turns out to be true, we just insert Node before
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700449 // PredPosition=NoPlace=Placed.end() .
450 if (PredPosition != NoPlace)
451 ++PredPosition;
452 Placed.insert(PredPosition, Node);
453 PlaceIndex[Node->getIndex()] = PredPosition;
454 } while (0);
455
456 --PlaceIndex[Node->getIndex()];
457 assert(*PlaceIndex[Node->getIndex()] == Node);
458 }
459
460 // Reorder Nodes according to the built-up lists.
Karl Schimpfac7d7342015-08-06 12:55:23 -0700461 NodeList Reordered;
462 Reordered.reserve(Placed.size() + Unreachable.size());
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700463 for (CfgNode *Node : Placed)
Karl Schimpfac7d7342015-08-06 12:55:23 -0700464 Reordered.push_back(Node);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700465 for (CfgNode *Node : Unreachable)
Karl Schimpfac7d7342015-08-06 12:55:23 -0700466 Reordered.push_back(Node);
467 assert(getNumNodes() == Reordered.size());
468 swapNodes(Reordered);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700469}
470
Qining Lu969f6a32015-07-31 09:58:34 -0700471namespace {
John Porto36d6aa62016-02-26 07:19:59 -0800472void getRandomPostOrder(CfgNode *Node, BitVector &ToVisit,
Qining Lu969f6a32015-07-31 09:58:34 -0700473 Ice::NodeList &PostOrder,
474 Ice::RandomNumberGenerator *RNG) {
475 assert(ToVisit[Node->getIndex()]);
476 ToVisit[Node->getIndex()] = false;
477 NodeList Outs = Node->getOutEdges();
478 Ice::RandomShuffle(Outs.begin(), Outs.end(),
479 [RNG](int N) { return RNG->next(N); });
480 for (CfgNode *Next : Outs) {
481 if (ToVisit[Next->getIndex()])
482 getRandomPostOrder(Next, ToVisit, PostOrder, RNG);
483 }
484 PostOrder.push_back(Node);
485}
486} // end of anonymous namespace
487
488void Cfg::shuffleNodes() {
Karl Schimpfd4699942016-04-02 09:55:31 -0700489 if (!getFlags().getReorderBasicBlocks())
Qining Lu969f6a32015-07-31 09:58:34 -0700490 return;
491
492 NodeList ReversedReachable;
493 NodeList Unreachable;
John Porto36d6aa62016-02-26 07:19:59 -0800494 BitVector ToVisit(Nodes.size(), true);
Qining Luaee5fa82015-08-20 14:59:03 -0700495 // Create Random number generator for function reordering
Karl Schimpfd4699942016-04-02 09:55:31 -0700496 RandomNumberGenerator RNG(getFlags().getRandomSeed(),
Qining Luaee5fa82015-08-20 14:59:03 -0700497 RPE_BasicBlockReordering, SequenceNumber);
Qining Lu969f6a32015-07-31 09:58:34 -0700498 // Traverse from entry node.
Qining Luaee5fa82015-08-20 14:59:03 -0700499 getRandomPostOrder(getEntryNode(), ToVisit, ReversedReachable, &RNG);
Qining Lu969f6a32015-07-31 09:58:34 -0700500 // Collect the unreachable nodes.
501 for (CfgNode *Node : Nodes)
502 if (ToVisit[Node->getIndex()])
503 Unreachable.push_back(Node);
504 // Copy the layout list to the Nodes.
Karl Schimpfac7d7342015-08-06 12:55:23 -0700505 NodeList Shuffled;
506 Shuffled.reserve(ReversedReachable.size() + Unreachable.size());
Qining Lu969f6a32015-07-31 09:58:34 -0700507 for (CfgNode *Node : reverse_range(ReversedReachable))
Karl Schimpfac7d7342015-08-06 12:55:23 -0700508 Shuffled.push_back(Node);
509 for (CfgNode *Node : Unreachable)
510 Shuffled.push_back(Node);
511 assert(Nodes.size() == Shuffled.size());
512 swapNodes(Shuffled);
Qining Lu969f6a32015-07-31 09:58:34 -0700513
514 dump("After basic block shuffling");
515}
516
Manasij Mukherjee032c3152016-05-24 14:25:04 -0700517void Cfg::localCSE() {
518 // Performs basic-block local common-subexpression elimination
519 // If we have
520 // t1 = op b c
521 // t2 = op b c
522 // This pass will replace future references to t2 in a basic block by t1
523 // Points to note:
524 // 1. Does not assume SSA, but not tested on non-SSA input yet as it is run
525 // at the beginning.
526 // 2. Leaves removal of instructions to DCE.
527 // 3. Only enabled on arithmetic instructions. pnacl-clang (-O2) is expected
528 // to take care of cases not arising from GEP simplification.
529 // 4. By default, two passes are made over each basic block. Control this
530 // with -lcse-max-iters=N
531
532 TimerMarker T(TimerStack::TT_localCse, this);
533 struct VariableHash {
534 size_t operator()(const Variable *Var) const { return Var->hashValue(); }
535 };
536
537 struct InstHash {
538 size_t operator()(const Inst *Instr) const {
539 auto Kind = Instr->getKind();
540 auto Result =
541 std::hash<typename std::underlying_type<Inst::InstKind>::type>()(
542 Kind);
543 for (SizeT i = 0; i < Instr->getSrcSize(); ++i) {
544 Result ^= Instr->getSrc(i)->hashValue();
545 }
546 return Result;
547 }
548 };
549 struct InstEq {
550 bool srcEq(const Operand *A, const Operand *B) const {
551 if (llvm::isa<Variable>(A) || llvm::isa<Constant>(A))
552 return (A == B);
553 return false;
554 }
555 bool operator()(const Inst *InstrA, const Inst *InstrB) const {
556 if ((InstrA->getKind() != InstrB->getKind()) ||
557 (InstrA->getSrcSize() != InstrB->getSrcSize()))
558 return false;
559
560 if (auto *A = llvm::dyn_cast<InstArithmetic>(InstrA)) {
561 auto *B = llvm::cast<InstArithmetic>(InstrB);
562 // A, B are guaranteed to be of the same 'kind' at this point
563 // So, dyn_cast is not needed
564 if (A->getOp() != B->getOp())
565 return false;
566 }
567 // Does not enter loop if different kind or number of operands
568 for (SizeT i = 0; i < InstrA->getSrcSize(); ++i) {
569 if (!srcEq(InstrA->getSrc(i), InstrB->getSrc(i)))
570 return false;
571 }
572 return true;
573 }
574 };
575
576 for (CfgNode *Node : getNodes()) {
577 CfgUnorderedSet<Inst *, InstHash, InstEq> Seen;
578
579 CfgUnorderedMap<Variable *, Variable *, VariableHash> Replacements;
580 // Combining the above two into a single data structure might consume less
581 // memory but will be slower i.e map of Instruction -> Set of Variables
582
583 CfgUnorderedMap<Variable *, std::vector<Inst *>, VariableHash> Dependency;
584 // Not necessary for SSA, still keeping it in case this pass is not run at
585 // the beginning. Remove to improve performace.
586
587 int IterCount = getFlags().getLocalCseMaxIterations();
588
589 while (IterCount--) {
590 // TODO : Stats on IterCount -> performance
591 for (Inst &Instr : Node->getInsts()) {
592 if (Instr.isDeleted() || !llvm::isa<InstArithmetic>(&Instr))
593 continue;
594
595 // Invalidate replacements
596 auto Iter = Replacements.find(Instr.getDest());
597 if (Iter != Replacements.end()) {
598 Replacements.erase(Iter);
599 }
600
601 // Invalidate 'seen' instructions whose operands were just updated.
602 auto DepIter = Dependency.find(Instr.getDest());
603 if (DepIter != Dependency.end()) {
604 for (auto DepInst : DepIter->second) {
605 Seen.erase(DepInst);
606 }
607 }
608 // The above two can be removed if SSA is assumed.
609
610 // Replace - doing this before checking for repetitions might enable
611 // more
612 // optimizations
613 for (SizeT i = 0; i < Instr.getSrcSize(); ++i) {
614 auto *Opnd = Instr.getSrc(i);
615 if (auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
616 if (Replacements.find(Var) != Replacements.end()) {
617 Instr.replaceSource(i, Replacements[Var]);
618 }
619 }
620 }
621
622 // Check for repetitions
623 auto SeenIter = Seen.find(&Instr);
624 if (SeenIter != Seen.end()) { // seen before
625 const Inst *Found = *SeenIter;
626 Replacements[Instr.getDest()] = Found->getDest();
627 } else { // new
628 Seen.insert(&Instr);
629
630 // Update dependencies
631 for (SizeT i = 0; i < Instr.getSrcSize(); ++i) {
632 auto *Opnd = Instr.getSrc(i);
633 if (auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
634 Dependency[Var].push_back(&Instr);
635 }
636 }
637 }
638 }
639 }
640 }
641}
642
Matt Wala45a06232014-07-09 16:33:22 -0700643void Cfg::doArgLowering() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700644 TimerMarker T(TimerStack::TT_doArgLowering, this);
Matt Wala45a06232014-07-09 16:33:22 -0700645 getTarget()->lowerArguments();
646}
647
David Sehr4318a412015-11-11 15:01:55 -0800648void Cfg::sortAndCombineAllocas(CfgVector<Inst *> &Allocas,
649 uint32_t CombinedAlignment, InstList &Insts,
650 AllocaBaseVariableType BaseVariableType) {
David Sehre39d0ca2015-11-06 11:25:41 -0800651 if (Allocas.empty())
652 return;
David Sehr4318a412015-11-11 15:01:55 -0800653 // Sort by decreasing alignment.
Jim Stichnothc59288b2015-11-09 11:38:40 -0800654 std::sort(Allocas.begin(), Allocas.end(), [](Inst *I1, Inst *I2) {
655 auto *A1 = llvm::dyn_cast<InstAlloca>(I1);
656 auto *A2 = llvm::dyn_cast<InstAlloca>(I2);
657 return A1->getAlignInBytes() > A2->getAlignInBytes();
658 });
David Sehr4318a412015-11-11 15:01:55 -0800659 // Process the allocas in order of decreasing stack alignment. This allows
660 // us to pack less-aligned pieces after more-aligned ones, resulting in less
661 // stack growth. It also allows there to be at most one stack alignment "and"
662 // instruction for a whole list of allocas.
663 uint32_t CurrentOffset = 0;
664 CfgVector<int32_t> Offsets;
Jim Stichnothc59288b2015-11-09 11:38:40 -0800665 for (Inst *Instr : Allocas) {
David Sehre39d0ca2015-11-06 11:25:41 -0800666 auto *Alloca = llvm::cast<InstAlloca>(Instr);
David Sehr4318a412015-11-11 15:01:55 -0800667 // Adjust the size of the allocation up to the next multiple of the
668 // object's alignment.
669 uint32_t Alignment = std::max(Alloca->getAlignInBytes(), 1u);
670 auto *ConstSize =
671 llvm::dyn_cast<ConstantInteger32>(Alloca->getSizeInBytes());
672 uint32_t Size = Utils::applyAlignment(ConstSize->getValue(), Alignment);
673 if (BaseVariableType == BVT_FramePointer) {
674 // Addressing is relative to the frame pointer. Subtract the offset after
675 // adding the size of the alloca, because it grows downwards from the
676 // frame pointer.
677 Offsets.push_back(-(CurrentOffset + Size));
678 } else {
679 // Addressing is relative to the stack pointer or to a user pointer. Add
680 // the offset before adding the size of the object, because it grows
John Porto614140e2015-11-23 11:43:13 -0800681 // upwards from the stack pointer. In addition, if the addressing is
682 // relative to the stack pointer, we need to add the pre-computed max out
683 // args size bytes.
684 const uint32_t OutArgsOffsetOrZero =
685 (BaseVariableType == BVT_StackPointer)
686 ? getTarget()->maxOutArgsSizeBytes()
687 : 0;
688 Offsets.push_back(CurrentOffset + OutArgsOffsetOrZero);
David Sehr4318a412015-11-11 15:01:55 -0800689 }
690 // Update the running offset of the fused alloca region.
691 CurrentOffset += Size;
692 }
693 // Round the offset up to the alignment granularity to use as the size.
694 uint32_t TotalSize = Utils::applyAlignment(CurrentOffset, CombinedAlignment);
695 // Ensure every alloca was assigned an offset.
696 assert(Allocas.size() == Offsets.size());
David Sehr2f3b8ec2015-11-16 16:51:39 -0800697
698 switch (BaseVariableType) {
699 case BVT_UserPointer: {
700 Variable *BaseVariable = makeVariable(IceType_i32);
701 for (SizeT i = 0; i < Allocas.size(); ++i) {
702 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
David Sehr4318a412015-11-11 15:01:55 -0800703 // Emit a new addition operation to replace the alloca.
704 Operand *AllocaOffset = Ctx->getConstantInt32(Offsets[i]);
705 InstArithmetic *Add =
706 InstArithmetic::create(this, InstArithmetic::Add, Alloca->getDest(),
707 BaseVariable, AllocaOffset);
708 Insts.push_front(Add);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800709 Alloca->setDeleted();
710 }
711 Operand *AllocaSize = Ctx->getConstantInt32(TotalSize);
712 InstAlloca *CombinedAlloca =
713 InstAlloca::create(this, BaseVariable, AllocaSize, CombinedAlignment);
714 CombinedAlloca->setKnownFrameOffset();
715 Insts.push_front(CombinedAlloca);
716 } break;
717 case BVT_StackPointer:
718 case BVT_FramePointer: {
719 for (SizeT i = 0; i < Allocas.size(); ++i) {
720 auto *Alloca = llvm::cast<InstAlloca>(Allocas[i]);
David Sehr4318a412015-11-11 15:01:55 -0800721 // Emit a fake definition of the rematerializable variable.
722 Variable *Dest = Alloca->getDest();
Jim Stichnoth54f3d512015-12-11 09:53:00 -0800723 auto *Def = InstFakeDef::create(this, Dest);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800724 if (BaseVariableType == BVT_StackPointer)
725 Dest->setRematerializable(getTarget()->getStackReg(), Offsets[i]);
726 else
727 Dest->setRematerializable(getTarget()->getFrameReg(), Offsets[i]);
David Sehr4318a412015-11-11 15:01:55 -0800728 Insts.push_front(Def);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800729 Alloca->setDeleted();
David Sehr4318a412015-11-11 15:01:55 -0800730 }
David Sehr2f3b8ec2015-11-16 16:51:39 -0800731 // Allocate the fixed area in the function prolog.
732 getTarget()->reserveFixedAllocaArea(TotalSize, CombinedAlignment);
David Sehr4318a412015-11-11 15:01:55 -0800733 } break;
David Sehr4318a412015-11-11 15:01:55 -0800734 }
David Sehre39d0ca2015-11-06 11:25:41 -0800735}
736
David Sehr4318a412015-11-11 15:01:55 -0800737void Cfg::processAllocas(bool SortAndCombine) {
Jim Stichnothb88d8c82016-03-11 15:33:00 -0800738 TimerMarker _(TimerStack::TT_alloca, this);
David Sehre39d0ca2015-11-06 11:25:41 -0800739 const uint32_t StackAlignment = getTarget()->getStackAlignment();
740 CfgNode *EntryNode = getEntryNode();
Eric Holk67c7c412016-04-15 13:05:37 -0700741 assert(EntryNode);
David Sehre39d0ca2015-11-06 11:25:41 -0800742 // LLVM enforces power of 2 alignment.
743 assert(llvm::isPowerOf2_32(StackAlignment));
David Sehr4318a412015-11-11 15:01:55 -0800744 // Determine if there are large alignment allocations in the entry block or
745 // dynamic allocations (variable size in the entry block).
746 bool HasLargeAlignment = false;
747 bool HasDynamicAllocation = false;
David Sehre39d0ca2015-11-06 11:25:41 -0800748 for (Inst &Instr : EntryNode->getInsts()) {
749 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
David Sehre39d0ca2015-11-06 11:25:41 -0800750 uint32_t AlignmentParam = Alloca->getAlignInBytes();
David Sehr4318a412015-11-11 15:01:55 -0800751 if (AlignmentParam > StackAlignment)
752 HasLargeAlignment = true;
753 if (llvm::isa<Constant>(Alloca->getSizeInBytes()))
754 Alloca->setKnownFrameOffset();
755 else {
756 HasDynamicAllocation = true;
757 // If Allocas are not sorted, the first dynamic allocation causes
758 // later Allocas to be at unknown offsets relative to the stack/frame.
759 if (!SortAndCombine)
760 break;
761 }
David Sehre39d0ca2015-11-06 11:25:41 -0800762 }
763 }
David Sehr4318a412015-11-11 15:01:55 -0800764 // Don't do the heavyweight sorting and layout for low optimization levels.
765 if (!SortAndCombine)
766 return;
767 // Any alloca outside the entry block is a dynamic allocation.
David Sehre39d0ca2015-11-06 11:25:41 -0800768 for (CfgNode *Node : Nodes) {
769 if (Node == EntryNode)
770 continue;
771 for (Inst &Instr : Node->getInsts()) {
772 if (llvm::isa<InstAlloca>(&Instr)) {
773 // Allocations outside the entry block require a frame pointer.
David Sehr4318a412015-11-11 15:01:55 -0800774 HasDynamicAllocation = true;
David Sehre39d0ca2015-11-06 11:25:41 -0800775 break;
776 }
777 }
David Sehr4318a412015-11-11 15:01:55 -0800778 if (HasDynamicAllocation)
David Sehre39d0ca2015-11-06 11:25:41 -0800779 break;
780 }
781 // Mark the target as requiring a frame pointer.
David Sehr4318a412015-11-11 15:01:55 -0800782 if (HasLargeAlignment || HasDynamicAllocation)
David Sehre39d0ca2015-11-06 11:25:41 -0800783 getTarget()->setHasFramePointer();
David Sehr4318a412015-11-11 15:01:55 -0800784 // Collect the Allocas into the two vectors.
785 // Allocas in the entry block that have constant size and alignment less
786 // than or equal to the function's stack alignment.
787 CfgVector<Inst *> FixedAllocas;
788 // Allocas in the entry block that have constant size and alignment greater
789 // than the function's stack alignment.
790 CfgVector<Inst *> AlignedAllocas;
David Sehr2f3b8ec2015-11-16 16:51:39 -0800791 // Maximum alignment used by any alloca.
David Sehr4318a412015-11-11 15:01:55 -0800792 uint32_t MaxAlignment = StackAlignment;
793 for (Inst &Instr : EntryNode->getInsts()) {
794 if (auto *Alloca = llvm::dyn_cast<InstAlloca>(&Instr)) {
795 if (!llvm::isa<Constant>(Alloca->getSizeInBytes()))
796 continue;
797 uint32_t AlignmentParam = Alloca->getAlignInBytes();
798 // For default align=0, set it to the real value 1, to avoid any
799 // bit-manipulation problems below.
800 AlignmentParam = std::max(AlignmentParam, 1u);
801 assert(llvm::isPowerOf2_32(AlignmentParam));
802 if (HasDynamicAllocation && AlignmentParam > StackAlignment) {
803 // If we have both dynamic allocations and large stack alignments,
804 // high-alignment allocations are pulled out with their own base.
805 AlignedAllocas.push_back(Alloca);
806 } else {
807 FixedAllocas.push_back(Alloca);
808 }
809 MaxAlignment = std::max(AlignmentParam, MaxAlignment);
810 }
811 }
David Sehre39d0ca2015-11-06 11:25:41 -0800812 // Add instructions to the head of the entry block in reverse order.
813 InstList &Insts = getEntryNode()->getInsts();
David Sehr4318a412015-11-11 15:01:55 -0800814 if (HasDynamicAllocation && HasLargeAlignment) {
815 // We are using a frame pointer, but fixed large-alignment alloca addresses,
816 // do not have a known offset from either the stack or frame pointer.
817 // They grow up from a user pointer from an alloca.
818 sortAndCombineAllocas(AlignedAllocas, MaxAlignment, Insts, BVT_UserPointer);
David Sehr2f3b8ec2015-11-16 16:51:39 -0800819 // Fixed size allocas are addressed relative to the frame pointer.
820 sortAndCombineAllocas(FixedAllocas, StackAlignment, Insts,
821 BVT_FramePointer);
822 } else {
823 // Otherwise, fixed size allocas are addressed relative to the stack unless
824 // there are dynamic allocas.
825 const AllocaBaseVariableType BasePointerType =
826 (HasDynamicAllocation ? BVT_FramePointer : BVT_StackPointer);
827 sortAndCombineAllocas(FixedAllocas, MaxAlignment, Insts, BasePointerType);
David Sehr4318a412015-11-11 15:01:55 -0800828 }
Jim Stichnoth3607b6c2015-11-13 14:28:23 -0800829 if (!FixedAllocas.empty() || !AlignedAllocas.empty())
830 // No use calling findRematerializable() unless there is some
831 // rematerializable alloca instruction to seed it.
832 findRematerializable();
833}
834
835namespace {
836
837// Helpers for findRematerializable(). For each of them, if a suitable
838// rematerialization is found, the instruction's Dest variable is set to be
839// rematerializable and it returns true, otherwise it returns false.
840
841bool rematerializeArithmetic(const Inst *Instr) {
842 // Check that it's an Arithmetic instruction with an Add operation.
843 auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr);
844 if (Arith == nullptr || Arith->getOp() != InstArithmetic::Add)
845 return false;
846 // Check that Src(0) is rematerializable.
847 auto *Src0Var = llvm::dyn_cast<Variable>(Arith->getSrc(0));
848 if (Src0Var == nullptr || !Src0Var->isRematerializable())
849 return false;
850 // Check that Src(1) is an immediate.
851 auto *Src1Imm = llvm::dyn_cast<ConstantInteger32>(Arith->getSrc(1));
852 if (Src1Imm == nullptr)
853 return false;
854 Arith->getDest()->setRematerializable(
855 Src0Var->getRegNum(), Src0Var->getStackOffset() + Src1Imm->getValue());
856 return true;
857}
858
859bool rematerializeAssign(const Inst *Instr) {
860 // An InstAssign only originates from an inttoptr or ptrtoint instruction,
861 // which never occurs in a MINIMAL build.
862 if (BuildDefs::minimal())
863 return false;
864 // Check that it's an Assign instruction.
865 if (!llvm::isa<InstAssign>(Instr))
866 return false;
867 // Check that Src(0) is rematerializable.
868 auto *Src0Var = llvm::dyn_cast<Variable>(Instr->getSrc(0));
869 if (Src0Var == nullptr || !Src0Var->isRematerializable())
870 return false;
871 Instr->getDest()->setRematerializable(Src0Var->getRegNum(),
872 Src0Var->getStackOffset());
873 return true;
874}
875
876bool rematerializeCast(const Inst *Instr) {
877 // An pointer-type bitcast never occurs in a MINIMAL build.
878 if (BuildDefs::minimal())
879 return false;
880 // Check that it's a Cast instruction with a Bitcast operation.
881 auto *Cast = llvm::dyn_cast<InstCast>(Instr);
882 if (Cast == nullptr || Cast->getCastKind() != InstCast::Bitcast)
883 return false;
884 // Check that Src(0) is rematerializable.
885 auto *Src0Var = llvm::dyn_cast<Variable>(Cast->getSrc(0));
886 if (Src0Var == nullptr || !Src0Var->isRematerializable())
887 return false;
888 // Check that Dest and Src(0) have the same type.
889 Variable *Dest = Cast->getDest();
890 if (Dest->getType() != Src0Var->getType())
891 return false;
892 Dest->setRematerializable(Src0Var->getRegNum(), Src0Var->getStackOffset());
893 return true;
894}
895
896} // end of anonymous namespace
897
898/// Scan the function to find additional rematerializable variables. This is
899/// possible when the source operand of an InstAssignment is a rematerializable
900/// variable, or the same for a pointer-type InstCast::Bitcast, or when an
901/// InstArithmetic is an add of a rematerializable variable and an immediate.
902/// Note that InstAssignment instructions and pointer-type InstCast::Bitcast
903/// instructions generally only come about from the IceConverter's treatment of
904/// inttoptr, ptrtoint, and bitcast instructions. TODO(stichnot): Consider
905/// other possibilities, however unlikely, such as InstArithmetic::Sub, or
906/// commutativity.
907void Cfg::findRematerializable() {
908 // Scan the instructions in order, and repeat until no new opportunities are
909 // found. It may take more than one iteration because a variable's defining
910 // block may happen to come after a block where it is used, depending on the
911 // CfgNode linearization order.
912 bool FoundNewAssignment;
913 do {
914 FoundNewAssignment = false;
915 for (CfgNode *Node : getNodes()) {
916 // No need to process Phi instructions.
917 for (Inst &Instr : Node->getInsts()) {
918 if (Instr.isDeleted())
919 continue;
920 Variable *Dest = Instr.getDest();
921 if (Dest == nullptr || Dest->isRematerializable())
922 continue;
923 if (rematerializeArithmetic(&Instr) || rematerializeAssign(&Instr) ||
924 rematerializeCast(&Instr)) {
925 FoundNewAssignment = true;
926 }
927 }
928 }
929 } while (FoundNewAssignment);
David Sehre39d0ca2015-11-06 11:25:41 -0800930}
931
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700932void Cfg::doAddressOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700933 TimerMarker T(TimerStack::TT_doAddressOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700934 for (CfgNode *Node : Nodes)
935 Node->doAddressOpt();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700936}
937
John Portoa47c11c2016-04-21 05:53:42 -0700938namespace {
939// ShuffleVectorUtils implements helper functions for rematerializing
940// shufflevector instructions from a sequence of extractelement/insertelement
941// instructions. It looks for the following pattern:
942//
943// %t0 = extractelement A, %n0
944// %t1 = extractelement B, %n1
945// %t2 = extractelement C, %n2
946// ...
947// %tN = extractelement N, %nN
948// %d0 = insertelement undef, %t0, 0
949// %d1 = insertelement %d0, %t1, 1
950// %d2 = insertelement %d1, %t2, 2
951// ...
952// %dest = insertelement %d_N-1, %tN, N
953//
954// where N is num_element(typeof(%dest)), and A, B, C, ... N are at most two
955// distinct variables.
956namespace ShuffleVectorUtils {
957// findAllInserts is used when searching for all the insertelements that are
958// used in a shufflevector operation. This function works recursively, when
959// invoked with I = i, the function assumes Insts[i] is the last found
960// insertelement in the chain. The next insertelement insertruction is saved in
961// Insts[i+1].
962bool findAllInserts(Cfg *Func, GlobalContext *Ctx, VariablesMetadata *VM,
963 CfgVector<const Inst *> *Insts, SizeT I = 0) {
964 const bool Verbose = BuildDefs::dump() && Func->isVerbose(IceV_ShufMat);
965
966 if (I > Insts->size()) {
967 if (Verbose) {
968 Ctx->getStrDump() << "\tToo many inserts.\n";
969 }
970 return false;
971 }
972
973 const auto *LastInsert = Insts->at(I);
974 assert(llvm::isa<InstInsertElement>(LastInsert));
975
976 if (I == Insts->size() - 1) {
977 // Matching against undef is not really needed because the value in Src(0)
978 // will be totally overwritten. We still enforce it anyways because the
979 // PNaCl toolchain generates the bitcode with it.
980 if (!llvm::isa<ConstantUndef>(LastInsert->getSrc(0))) {
981 if (Verbose) {
982 Ctx->getStrDump() << "\tSrc0 is not undef: " << I << " "
983 << Insts->size();
984 LastInsert->dump(Func);
985 Ctx->getStrDump() << "\n";
986 }
987 return false;
988 }
989
990 // The following loop ensures that the insertelements are sorted. In theory,
991 // we could relax this restriction and allow any order. As long as each
992 // index appears exactly once, this chain is still a candidate for becoming
993 // a shufflevector. The Insts vector is traversed backwards because the
994 // instructions are "enqueued" in reverse order.
995 int32_t ExpectedElement = 0;
996 for (const auto *I : reverse_range(*Insts)) {
997 if (llvm::cast<ConstantInteger32>(I->getSrc(2))->getValue() !=
998 ExpectedElement) {
999 return false;
1000 }
1001 ++ExpectedElement;
1002 }
1003 return true;
1004 }
1005
1006 const auto *Src0V = llvm::cast<Variable>(LastInsert->getSrc(0));
1007 const auto *Def = VM->getSingleDefinition(Src0V);
1008
1009 // Only optimize if the first operand in
1010 //
1011 // Dest = insertelement A, B, 10
1012 //
1013 // is singly-def'ed.
1014 if (Def == nullptr) {
1015 if (Verbose) {
1016 Ctx->getStrDump() << "\tmulti-def: ";
1017 (*Insts)[I]->dump(Func);
1018 Ctx->getStrDump() << "\n";
1019 }
1020 return false;
1021 }
1022
1023 // We also require the (single) definition to come from an insertelement
1024 // instruction.
1025 if (!llvm::isa<InstInsertElement>(Def)) {
1026 if (Verbose) {
1027 Ctx->getStrDump() << "\tnot insert element: ";
1028 Def->dump(Func);
1029 Ctx->getStrDump() << "\n";
1030 }
1031 return false;
1032 }
1033
1034 // Everything seems fine, so we save Def in Insts, and delegate the decision
1035 // to findAllInserts.
1036 (*Insts)[I + 1] = Def;
1037
1038 return findAllInserts(Func, Ctx, VM, Insts, I + 1);
1039}
1040
1041// insertsLastElement returns true if Insert is inserting an element in the last
1042// position of a vector.
1043bool insertsLastElement(const Inst &Insert) {
1044 const Type DestTy = Insert.getDest()->getType();
1045 assert(isVectorType(DestTy));
1046 const SizeT Elem =
1047 llvm::cast<ConstantInteger32>(Insert.getSrc(2))->getValue();
1048 return Elem == typeNumElements(DestTy) - 1;
1049}
1050
1051// findAllExtracts goes over all the insertelement instructions that are
1052// candidates to be replaced by a shufflevector, and searches for all the
1053// definitions of the elements being inserted. If all of the elements are the
1054// result of an extractelement instruction, and all of the extractelements
1055// operate on at most two different sources, than the instructions can be
1056// replaced by a shufflevector.
1057bool findAllExtracts(Cfg *Func, GlobalContext *Ctx, VariablesMetadata *VM,
1058 const CfgVector<const Inst *> &Insts, Variable **Src0,
1059 Variable **Src1, CfgVector<const Inst *> *Extracts) {
1060 const bool Verbose = BuildDefs::dump() && Func->isVerbose(IceV_ShufMat);
1061
1062 *Src0 = nullptr;
1063 *Src1 = nullptr;
1064 assert(Insts.size() > 0);
1065 for (SizeT I = 0; I < Insts.size(); ++I) {
1066 const auto *Insert = Insts.at(I);
1067 const auto *Src1V = llvm::dyn_cast<Variable>(Insert->getSrc(1));
1068 if (Src1V == nullptr) {
1069 if (Verbose) {
1070 Ctx->getStrDump() << "src(1) is not a variable: ";
1071 Insert->dump(Func);
1072 Ctx->getStrDump() << "\n";
1073 }
1074 return false;
1075 }
1076
1077 const auto *Def = VM->getSingleDefinition(Src1V);
1078 if (Def == nullptr) {
1079 if (Verbose) {
1080 Ctx->getStrDump() << "multi-def src(1): ";
1081 Insert->dump(Func);
1082 Ctx->getStrDump() << "\n";
1083 }
1084 return false;
1085 }
1086
1087 if (!llvm::isa<InstExtractElement>(Def)) {
1088 if (Verbose) {
1089 Ctx->getStrDump() << "not extractelement: ";
1090 Def->dump(Func);
1091 Ctx->getStrDump() << "\n";
1092 }
1093 return false;
1094 }
1095
1096 auto *Src = llvm::cast<Variable>(Def->getSrc(0));
1097 if (*Src0 == nullptr) {
1098 // No sources yet. Save Src to Src0.
1099 *Src0 = Src;
1100 } else if (*Src1 == nullptr) {
1101 // We already have a source, so we might save Src in Src1 -- but only if
1102 // Src0 is not Src.
1103 if (*Src0 != Src) {
1104 *Src1 = Src;
1105 }
1106 } else if (Src != *Src0 && Src != *Src1) {
1107 // More than two sources, so we can't rematerialize the shufflevector
1108 // instruction.
1109 if (Verbose) {
1110 Ctx->getStrDump() << "Can't shuffle more than two sources.\n";
1111 }
1112 return false;
1113 }
1114
1115 (*Extracts)[I] = Def;
1116 }
1117
1118 // We should have seen at least one source operand.
1119 assert(*Src0 != nullptr);
1120
1121 // If a second source was not seen, then we just make Src1 = Src0 to simplify
1122 // things down stream. This should not matter, as all of the indexes in the
1123 // shufflevector instruction will point to Src0.
1124 if (*Src1 == nullptr) {
1125 *Src1 = *Src0;
1126 }
1127
1128 return true;
1129}
1130
1131} // end of namespace ShuffleVectorUtils
1132} // end of anonymous namespace
1133
1134void Cfg::materializeVectorShuffles() {
1135 const bool Verbose = BuildDefs::dump() && isVerbose(IceV_ShufMat);
1136
1137 std::unique_ptr<OstreamLocker> L;
1138 if (Verbose) {
1139 L.reset(new OstreamLocker(getContext()));
1140 getContext()->getStrDump() << "\nShuffle materialization:\n";
1141 }
1142
1143 // MaxVectorElements is the maximum number of elements in the vector types
1144 // handled by Subzero. We use it to create the Inserts and Extracts vectors
1145 // with the appropriate size, thus avoiding resize() calls.
1146 const SizeT MaxVectorElements = typeNumElements(IceType_v16i8);
1147 CfgVector<const Inst *> Inserts(MaxVectorElements);
1148 CfgVector<const Inst *> Extracts(MaxVectorElements);
1149
1150 TimerMarker T(TimerStack::TT_materializeVectorShuffles, this);
1151 for (CfgNode *Node : Nodes) {
1152 for (auto &Instr : Node->getInsts()) {
1153 if (!llvm::isa<InstInsertElement>(Instr)) {
1154 continue;
1155 }
1156 if (!ShuffleVectorUtils::insertsLastElement(Instr)) {
1157 // To avoid wasting time, we only start the pattern match at the last
1158 // insertelement instruction -- and go backwards from there.
1159 continue;
1160 }
1161 if (Verbose) {
1162 getContext()->getStrDump() << "\tCandidate: ";
1163 Instr.dump(this);
1164 getContext()->getStrDump() << "\n";
1165 }
1166 Inserts.resize(typeNumElements(Instr.getDest()->getType()));
1167 Inserts[0] = &Instr;
1168 if (!ShuffleVectorUtils::findAllInserts(this, getContext(),
1169 VMetadata.get(), &Inserts)) {
1170 // If we fail to find a sequence of insertelements, we stop the
1171 // optimization.
1172 if (Verbose) {
1173 getContext()->getStrDump() << "\tFalse alarm.\n";
1174 }
1175 continue;
1176 }
1177 if (Verbose) {
1178 getContext()->getStrDump() << "\tFound the following insertelement: \n";
1179 for (auto *I : reverse_range(Inserts)) {
1180 getContext()->getStrDump() << "\t\t";
1181 I->dump(this);
1182 getContext()->getStrDump() << "\n";
1183 }
1184 }
1185 Extracts.resize(Inserts.size());
1186 Variable *Src0;
1187 Variable *Src1;
1188 if (!ShuffleVectorUtils::findAllExtracts(this, getContext(),
1189 VMetadata.get(), Inserts, &Src0,
1190 &Src1, &Extracts)) {
1191 // If we fail to match the definitions of the insertelements' sources
1192 // with extractelement instructions -- or if those instructions operate
1193 // on more than two different variables -- we stop the optimization.
1194 if (Verbose) {
1195 getContext()->getStrDump() << "\tFailed to match extractelements.\n";
1196 }
1197 continue;
1198 }
1199 if (Verbose) {
1200 getContext()->getStrDump()
1201 << "\tFound the following insert/extract element pairs: \n";
1202 for (SizeT I = 0; I < Inserts.size(); ++I) {
1203 const SizeT Pos = Inserts.size() - I - 1;
1204 getContext()->getStrDump() << "\t\tInsert : ";
1205 Inserts[Pos]->dump(this);
1206 getContext()->getStrDump() << "\n\t\tExtract: ";
1207 Extracts[Pos]->dump(this);
1208 getContext()->getStrDump() << "\n";
1209 }
1210 }
1211
1212 assert(Src0 != nullptr);
1213 assert(Src1 != nullptr);
1214
1215 auto *ShuffleVector =
1216 InstShuffleVector::create(this, Instr.getDest(), Src0, Src1);
1217 assert(ShuffleVector->getSrc(0) == Src0);
1218 assert(ShuffleVector->getSrc(1) == Src1);
1219 for (SizeT I = 0; I < Extracts.size(); ++I) {
1220 const SizeT Pos = Extracts.size() - I - 1;
1221 auto *Index = llvm::cast<ConstantInteger32>(Extracts[Pos]->getSrc(1));
1222 if (Src0 == Extracts[Pos]->getSrc(0)) {
1223 ShuffleVector->addIndex(Index);
1224 } else {
1225 ShuffleVector->addIndex(llvm::cast<ConstantInteger32>(
1226 Ctx->getConstantInt32(Index->getValue() + Extracts.size())));
1227 }
1228 }
1229
1230 if (Verbose) {
1231 getContext()->getStrDump() << "Created: ";
1232 ShuffleVector->dump(this);
1233 getContext()->getStrDump() << "\n";
1234 }
1235
1236 Instr.setDeleted();
1237 auto &LoweringContext = getTarget()->getContext();
Jim Stichnothf5fdd232016-05-09 12:24:36 -07001238 LoweringContext.setInsertPoint(instToIterator(&Instr));
John Portoa47c11c2016-04-21 05:53:42 -07001239 LoweringContext.insert(ShuffleVector);
1240 }
1241 }
1242}
1243
Matt Walac3302742014-08-15 16:21:56 -07001244void Cfg::doNopInsertion() {
Karl Schimpfd4699942016-04-02 09:55:31 -07001245 if (!getFlags().getShouldDoNopInsertion())
Qining Lu969f6a32015-07-31 09:58:34 -07001246 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -07001247 TimerMarker T(TimerStack::TT_doNopInsertion, this);
Karl Schimpfd4699942016-04-02 09:55:31 -07001248 RandomNumberGenerator RNG(getFlags().getRandomSeed(), RPE_NopInsertion,
Qining Luaee5fa82015-08-20 14:59:03 -07001249 SequenceNumber);
Jim Stichnothf44f3712014-10-01 14:05:51 -07001250 for (CfgNode *Node : Nodes)
Qining Luaee5fa82015-08-20 14:59:03 -07001251 Node->doNopInsertion(RNG);
Matt Walac3302742014-08-15 16:21:56 -07001252}
1253
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001254void Cfg::genCode() {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001255 TimerMarker T(TimerStack::TT_genCode, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -07001256 for (CfgNode *Node : Nodes)
1257 Node->genCode();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001258}
1259
1260// Compute the stack frame layout.
1261void Cfg::genFrame() {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001262 TimerMarker T(TimerStack::TT_genFrame, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001263 getTarget()->addProlog(Entry);
Jim Stichnothf44f3712014-10-01 14:05:51 -07001264 for (CfgNode *Node : Nodes)
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001265 if (Node->getHasReturn())
1266 getTarget()->addEpilog(Node);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001267}
1268
Andrew Scullaa6c1092015-09-03 17:50:30 -07001269void Cfg::computeLoopNestDepth() {
1270 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this);
1271 LoopAnalyzer LA(this);
1272 LA.computeLoopNestDepth();
1273}
1274
Andrew Scull57e12682015-09-16 11:30:19 -07001275// This is a lightweight version of live-range-end calculation. Marks the last
Andrew Scullaa6c1092015-09-03 17:50:30 -07001276// use of only those variables whose definition and uses are completely with a
Andrew Scull57e12682015-09-16 11:30:19 -07001277// single block. It is a quick single pass and doesn't need to iterate until
Andrew Scullaa6c1092015-09-03 17:50:30 -07001278// convergence.
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001279void Cfg::livenessLightweight() {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001280 TimerMarker T(TimerStack::TT_livenessLightweight, this);
Jim Stichnoth877b04e2014-10-15 15:13:06 -07001281 getVMetadata()->init(VMK_Uses);
Jim Stichnothf44f3712014-10-01 14:05:51 -07001282 for (CfgNode *Node : Nodes)
1283 Node->livenessLightweight();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001284}
1285
1286void Cfg::liveness(LivenessMode Mode) {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001287 TimerMarker T(TimerStack::TT_liveness, this);
John Porto7bb9cab2016-04-01 05:43:09 -07001288 // Destroying the previous (if any) Liveness information clears the Liveness
1289 // allocator TLS pointer.
1290 Live = nullptr;
1291 Live = Liveness::create(this, Mode);
1292
Jim Stichnoth877b04e2014-10-15 15:13:06 -07001293 getVMetadata()->init(VMK_Uses);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001294 Live->init();
John Porto7bb9cab2016-04-01 05:43:09 -07001295
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001296 // Initialize with all nodes needing to be processed.
John Porto36d6aa62016-02-26 07:19:59 -08001297 BitVector NeedToProcess(Nodes.size(), true);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001298 while (NeedToProcess.any()) {
1299 // Iterate in reverse topological order to speed up convergence.
Jim Stichnoth7e571362015-01-09 11:43:26 -08001300 for (CfgNode *Node : reverse_range(Nodes)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001301 if (NeedToProcess[Node->getIndex()]) {
1302 NeedToProcess[Node->getIndex()] = false;
1303 bool Changed = Node->liveness(getLiveness());
1304 if (Changed) {
1305 // If the beginning-of-block liveness changed since the last
1306 // iteration, mark all in-edges as needing to be processed.
Jim Stichnothf44f3712014-10-01 14:05:51 -07001307 for (CfgNode *Pred : Node->getInEdges())
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001308 NeedToProcess[Pred->getIndex()] = true;
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001309 }
1310 }
1311 }
1312 }
1313 if (Mode == Liveness_Intervals) {
1314 // Reset each variable's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -07001315 for (Variable *Var : Variables)
1316 Var->resetLiveRange();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001317 }
Andrew Scull57e12682015-09-16 11:30:19 -07001318 // Make a final pass over each node to delete dead instructions, collect the
1319 // first and last instruction numbers, and add live range segments for that
1320 // node.
Jim Stichnothe5b73e62014-12-15 09:58:51 -08001321 for (CfgNode *Node : Nodes) {
1322 InstNumberT FirstInstNum = Inst::NumberSentinel;
1323 InstNumberT LastInstNum = Inst::NumberSentinel;
Jim Stichnoth29841e82014-12-23 12:26:24 -08001324 for (Inst &I : Node->getPhis()) {
1325 I.deleteIfDead();
1326 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -08001327 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -08001328 FirstInstNum = I.getNumber();
1329 assert(I.getNumber() > LastInstNum);
1330 LastInstNum = I.getNumber();
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001331 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -08001332 }
Jim Stichnoth29841e82014-12-23 12:26:24 -08001333 for (Inst &I : Node->getInsts()) {
1334 I.deleteIfDead();
1335 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -08001336 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -08001337 FirstInstNum = I.getNumber();
1338 assert(I.getNumber() > LastInstNum);
1339 LastInstNum = I.getNumber();
Jim Stichnothe5b73e62014-12-15 09:58:51 -08001340 }
1341 }
1342 if (Mode == Liveness_Intervals) {
Andrew Scull57e12682015-09-16 11:30:19 -07001343 // Special treatment for live in-args. Their liveness needs to extend
1344 // beyond the beginning of the function, otherwise an arg whose only use
1345 // is in the first instruction will end up having the trivial live range
1346 // [2,2) and will *not* interfere with other arguments. So if the first
1347 // instruction of the method is "r=arg1+arg2", both args may be assigned
1348 // the same register. This is accomplished by extending the entry block's
1349 // instruction range from [2,n) to [1,n) which will transform the
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -08001350 // problematic [2,2) live ranges into [1,2). This extension works because
1351 // the entry node is guaranteed to have the lowest instruction numbers.
Jim Stichnothe4f65d82015-06-17 22:16:02 -07001352 if (Node == getEntryNode()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -08001353 FirstInstNum = Inst::NumberExtended;
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -08001354 // Just in case the entry node somehow contains no instructions...
1355 if (LastInstNum == Inst::NumberSentinel)
1356 LastInstNum = FirstInstNum;
Jim Stichnothe4f65d82015-06-17 22:16:02 -07001357 }
Jim Stichnoth6f7ad6c2016-01-15 09:52:54 -08001358 // If this node somehow contains no instructions, don't bother trying to
1359 // add liveness intervals for it, because variables that are live-in and
1360 // live-out will have a bogus interval added.
1361 if (FirstInstNum != Inst::NumberSentinel)
1362 Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001363 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001364 }
1365}
1366
Andrew Scull57e12682015-09-16 11:30:19 -07001367// Traverse every Variable of every Inst and verify that it appears within the
1368// Variable's computed live range.
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001369bool Cfg::validateLiveness() const {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001370 TimerMarker T(TimerStack::TT_validateLiveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001371 bool Valid = true;
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001372 OstreamLocker L(Ctx);
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001373 Ostream &Str = Ctx->getStrDump();
Jim Stichnothf44f3712014-10-01 14:05:51 -07001374 for (CfgNode *Node : Nodes) {
Jim Stichnothae953202014-12-20 06:17:49 -08001375 Inst *FirstInst = nullptr;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001376 for (Inst &Instr : Node->getInsts()) {
1377 if (Instr.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001378 continue;
Jim Stichnothae953202014-12-20 06:17:49 -08001379 if (FirstInst == nullptr)
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001380 FirstInst = &Instr;
1381 InstNumberT InstNumber = Instr.getNumber();
1382 if (Variable *Dest = Instr.getDest()) {
Jim Stichnoth47752552014-10-13 17:15:08 -07001383 if (!Dest->getIgnoreLiveness()) {
1384 bool Invalid = false;
Jim Stichnoth5bff61c2015-10-28 09:26:00 -07001385 constexpr bool IsDest = true;
Jim Stichnoth47752552014-10-13 17:15:08 -07001386 if (!Dest->getLiveRange().containsValue(InstNumber, IsDest))
1387 Invalid = true;
Andrew Scull57e12682015-09-16 11:30:19 -07001388 // Check that this instruction actually *begins* Dest's live range,
1389 // by checking that Dest is not live in the previous instruction. As
1390 // a special exception, we don't check this for the first instruction
1391 // of the block, because a Phi temporary may be live at the end of
1392 // the previous block, and if it is also assigned in the first
1393 // instruction of this block, the adjacent live ranges get merged.
Jim Stichnoth2d6c8262016-02-07 09:50:27 -08001394 if (&Instr != FirstInst && !Instr.isDestRedefined() &&
Jim Stichnoth47752552014-10-13 17:15:08 -07001395 Dest->getLiveRange().containsValue(InstNumber - 1, IsDest))
1396 Invalid = true;
1397 if (Invalid) {
1398 Valid = false;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001399 Str << "Liveness error: inst " << Instr.getNumber() << " dest ";
Jim Stichnoth47752552014-10-13 17:15:08 -07001400 Dest->dump(this);
1401 Str << " live range " << Dest->getLiveRange() << "\n";
1402 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001403 }
1404 }
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001405 FOREACH_VAR_IN_INST(Var, Instr) {
John Portoec3f5652015-08-31 15:07:09 -07001406 static constexpr bool IsDest = false;
1407 if (!Var->getIgnoreLiveness() &&
1408 !Var->getLiveRange().containsValue(InstNumber, IsDest)) {
1409 Valid = false;
Jim Stichnoth8cfeb692016-02-05 09:50:02 -08001410 Str << "Liveness error: inst " << Instr.getNumber() << " var ";
John Portoec3f5652015-08-31 15:07:09 -07001411 Var->dump(this);
1412 Str << " live range " << Var->getLiveRange() << "\n";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001413 }
1414 }
1415 }
1416 }
1417 return Valid;
1418}
1419
Jim Stichnoth336f6c42014-10-30 15:01:31 -07001420void Cfg::contractEmptyNodes() {
Andrew Scullaa6c1092015-09-03 17:50:30 -07001421 // If we're decorating the asm output with register liveness info, this
1422 // information may become corrupted or incorrect after contracting nodes that
1423 // contain only redundant assignments. As such, we disable this pass when
1424 // DecorateAsm is specified. This may make the resulting code look more
1425 // branchy, but it should have no effect on the register assignments.
Karl Schimpfd4699942016-04-02 09:55:31 -07001426 if (getFlags().getDecorateAsm())
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001427 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -07001428 for (CfgNode *Node : Nodes) {
1429 Node->contractIfEmpty();
1430 }
1431}
1432
Jim Stichnothff9c7062014-09-18 04:50:49 -07001433void Cfg::doBranchOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -07001434 TimerMarker T(TimerStack::TT_doBranchOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -07001435 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
Andrew Scull713278a2015-07-22 17:17:02 -07001436 auto NextNode = I + 1;
Jim Stichnothae953202014-12-20 06:17:49 -08001437 (*I)->doBranchOpt(NextNode == E ? nullptr : *NextNode);
Jim Stichnothff9c7062014-09-18 04:50:49 -07001438 }
1439}
1440
Andrew Scull86df4e92015-07-30 13:54:44 -07001441void Cfg::markNodesForSandboxing() {
1442 for (const InstJumpTable *JT : JumpTables)
1443 for (SizeT I = 0; I < JT->getNumTargets(); ++I)
1444 JT->getTarget(I)->setNeedsAlignment();
1445}
1446
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001447// ======================== Dump routines ======================== //
1448
Andrew Scull57e12682015-09-16 11:30:19 -07001449// emitTextHeader() is not target-specific (apart from what is abstracted by
1450// the Assembler), so it is defined here rather than in the target lowering
1451// class.
Jim Stichnoth467ffe52016-03-29 15:01:06 -07001452void Cfg::emitTextHeader(GlobalString Name, GlobalContext *Ctx,
Jim Stichnothbbca7542015-02-11 16:08:31 -08001453 const Assembler *Asm) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001454 if (!BuildDefs::dump())
Jim Stichnoth729dbd02015-02-25 14:48:43 -08001455 return;
Jan Voung0faec4c2014-11-05 17:29:56 -08001456 Ostream &Str = Ctx->getStrEmit();
1457 Str << "\t.text\n";
Karl Schimpfd4699942016-04-02 09:55:31 -07001458 if (getFlags().getFunctionSections())
Jim Stichnoth98ba0062016-03-07 09:26:22 -08001459 Str << "\t.section\t.text." << Name << ",\"ax\",%progbits\n";
Karl Schimpfd4699942016-04-02 09:55:31 -07001460 if (!Asm->getInternal() || getFlags().getDisableInternal()) {
Jim Stichnoth98ba0062016-03-07 09:26:22 -08001461 Str << "\t.globl\t" << Name << "\n";
1462 Str << "\t.type\t" << Name << ",%function\n";
Jan Voung0faec4c2014-11-05 17:29:56 -08001463 }
Andrew Scull86df4e92015-07-30 13:54:44 -07001464 Str << "\t" << Asm->getAlignDirective() << " "
Jan Voungb2d50842015-05-12 09:53:50 -07001465 << Asm->getBundleAlignLog2Bytes() << ",0x";
Jan Voung08c3bcd2014-12-01 17:55:16 -08001466 for (uint8_t I : Asm->getNonExecBundlePadding())
Jan Voung0faec4c2014-11-05 17:29:56 -08001467 Str.write_hex(I);
1468 Str << "\n";
Jim Stichnoth98ba0062016-03-07 09:26:22 -08001469 Str << Name << ":\n";
Jan Voung0faec4c2014-11-05 17:29:56 -08001470}
1471
Andrew Scull86df4e92015-07-30 13:54:44 -07001472void Cfg::emitJumpTables() {
Karl Schimpfd4699942016-04-02 09:55:31 -07001473 switch (getFlags().getOutFileType()) {
Andrew Scull86df4e92015-07-30 13:54:44 -07001474 case FT_Elf:
1475 case FT_Iasm: {
Andrew Scull57e12682015-09-16 11:30:19 -07001476 // The emission needs to be delayed until the after the text section so
1477 // save the offsets in the global context.
Andrew Scull86df4e92015-07-30 13:54:44 -07001478 for (const InstJumpTable *JumpTable : JumpTables) {
John Porto03077212016-04-05 06:30:21 -07001479 Ctx->addJumpTableData(JumpTable->toJumpTableData(getAssembler()));
Andrew Scull86df4e92015-07-30 13:54:44 -07001480 }
1481 } break;
1482 case FT_Asm: {
1483 // Emit the assembly directly so we don't need to hang on to all the names
1484 for (const InstJumpTable *JumpTable : JumpTables)
1485 getTarget()->emitJumpTable(this, JumpTable);
1486 } break;
Andrew Scull86df4e92015-07-30 13:54:44 -07001487 }
1488}
1489
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001490void Cfg::emit() {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001491 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001492 return;
Karl Schimpfb6e9b892016-03-08 12:27:12 -08001493 TimerMarker T(TimerStack::TT_emitAsm, this);
Karl Schimpfd4699942016-04-02 09:55:31 -07001494 if (getFlags().getDecorateAsm()) {
Jim Stichnoth3d44fe82014-11-01 10:10:18 -07001495 renumberInstructions();
1496 getVMetadata()->init(VMK_Uses);
1497 liveness(Liveness_Basic);
1498 dump("After recomputing liveness for -decorate-asm");
1499 }
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001500 OstreamLocker L(Ctx);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001501 Ostream &Str = Ctx->getStrEmit();
Andrew Scull86df4e92015-07-30 13:54:44 -07001502 const Assembler *Asm = getAssembler<>();
Karl Schimpfd4699942016-04-02 09:55:31 -07001503 const bool NeedSandboxing = getFlags().getUseSandboxing();
Andrew Scull86df4e92015-07-30 13:54:44 -07001504
Jim Stichnoth98ba0062016-03-07 09:26:22 -08001505 emitTextHeader(FunctionName, Ctx, Asm);
Karl Schimpfd4699942016-04-02 09:55:31 -07001506 if (getFlags().getDecorateAsm()) {
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001507 for (Variable *Var : getVariables()) {
Jim Stichnoth3607b6c2015-11-13 14:28:23 -08001508 if (Var->getStackOffset() && !Var->isRematerializable()) {
Jim Stichnotha91c3412016-04-05 15:31:43 -07001509 Str << "\t" << Var->getSymbolicStackOffset() << " = "
Jim Stichnoth238b4c12015-10-01 07:46:38 -07001510 << Var->getStackOffset() << "\n";
1511 }
1512 }
1513 }
Andrew Scull86df4e92015-07-30 13:54:44 -07001514 for (CfgNode *Node : Nodes) {
1515 if (NeedSandboxing && Node->needsAlignment()) {
1516 Str << "\t" << Asm->getAlignDirective() << " "
1517 << Asm->getBundleAlignLog2Bytes() << "\n";
1518 }
Jim Stichnothf44f3712014-10-01 14:05:51 -07001519 Node->emit(this);
Andrew Scull86df4e92015-07-30 13:54:44 -07001520 }
1521 emitJumpTables();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001522 Str << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -07001523}
1524
Jan Voung0faec4c2014-11-05 17:29:56 -08001525void Cfg::emitIAS() {
Karl Schimpfb6e9b892016-03-08 12:27:12 -08001526 TimerMarker T(TimerStack::TT_emitAsm, this);
Andrew Scull57e12682015-09-16 11:30:19 -07001527 // The emitIAS() routines emit into the internal assembler buffer, so there's
1528 // no need to lock the streams.
Karl Schimpfd4699942016-04-02 09:55:31 -07001529 const bool NeedSandboxing = getFlags().getUseSandboxing();
Andrew Scull86df4e92015-07-30 13:54:44 -07001530 for (CfgNode *Node : Nodes) {
1531 if (NeedSandboxing && Node->needsAlignment())
1532 getAssembler()->alignCfgNode();
Jan Voung0faec4c2014-11-05 17:29:56 -08001533 Node->emitIAS(this);
Andrew Scull86df4e92015-07-30 13:54:44 -07001534 }
1535 emitJumpTables();
Jan Voung0faec4c2014-11-05 17:29:56 -08001536}
1537
John Portoa3984a12016-04-01 11:14:30 -07001538size_t Cfg::getTotalMemoryMB() const {
1539 constexpr size_t _1MB = 1024 * 1024;
1540 assert(Allocator != nullptr);
1541 assert(CfgAllocatorTraits::current() == Allocator.get());
1542 return Allocator->getTotalMemory() / _1MB;
1543}
1544
1545size_t Cfg::getLivenessMemoryMB() const {
1546 constexpr size_t _1MB = 1024 * 1024;
1547 if (Live == nullptr) {
1548 return 0;
1549 }
1550 return Live->getAllocator()->getTotalMemory() / _1MB;
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001551}
1552
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001553// Dumps the IR with an optional introductory message.
Jim Stichnothb88d8c82016-03-11 15:33:00 -08001554void Cfg::dump(const char *Message) {
Jim Stichnoth20b71f52015-06-24 15:52:24 -07001555 if (!BuildDefs::dump())
Karl Schimpfb6c96af2014-11-17 10:58:39 -08001556 return;
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001557 if (!isVerbose())
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001558 return;
Jim Stichnothe4a8f402015-01-20 12:52:51 -08001559 OstreamLocker L(Ctx);
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001560 Ostream &Str = Ctx->getStrDump();
Jim Stichnothb88d8c82016-03-11 15:33:00 -08001561 if (Message[0])
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001562 Str << "================ " << Message << " ================\n";
Jim Stichnoth3dd1bb82016-02-27 09:05:50 -08001563 if (isVerbose(IceV_Mem)) {
Jim Stichnoth1bdb7352016-02-29 16:58:15 -08001564 Str << "Memory size = " << getTotalMemoryMB() << " MB\n";
Jim Stichnoth3dd1bb82016-02-27 09:05:50 -08001565 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001566 setCurrentNode(getEntryNode());
1567 // Print function name+args
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001568 if (isVerbose(IceV_Instructions)) {
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001569 Str << "define ";
Karl Schimpfd4699942016-04-02 09:55:31 -07001570 if (getInternal() && !getFlags().getDisableInternal())
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001571 Str << "internal ";
Jim Stichnoth98ba0062016-03-07 09:26:22 -08001572 Str << ReturnType << " @" << getFunctionName() << "(";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001573 for (SizeT i = 0; i < Args.size(); ++i) {
1574 if (i > 0)
1575 Str << ", ";
1576 Str << Args[i]->getType() << " ";
1577 Args[i]->dump(this);
1578 }
Jim Stichnothb40595a2016-01-29 06:14:31 -08001579 // Append an extra copy of the function name here, in order to print its
1580 // size stats but not mess up lit tests.
1581 Str << ") { # " << getFunctionNameAndSize() << "\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001582 }
Jim Stichnoth800dab22014-09-20 12:25:02 -07001583 resetCurrentNode();
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001584 if (isVerbose(IceV_Liveness)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001585 // Print summary info about variables
Jim Stichnothf44f3712014-10-01 14:05:51 -07001586 for (Variable *Var : Variables) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -07001587 Str << "// multiblock=";
1588 if (getVMetadata()->isTracked(Var))
1589 Str << getVMetadata()->isMultiBlock(Var);
1590 else
1591 Str << "?";
Jim Stichnoth48e3ae52015-10-01 13:33:35 -07001592 Str << " defs=";
1593 bool FirstPrint = true;
1594 if (VMetadata->getKind() != VMK_Uses) {
1595 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) {
1596 Str << FirstDef->getNumber();
1597 FirstPrint = false;
1598 }
1599 }
1600 if (VMetadata->getKind() == VMK_All) {
1601 for (const Inst *Instr : VMetadata->getLatterDefinitions(Var)) {
1602 if (!FirstPrint)
1603 Str << ",";
1604 Str << Instr->getNumber();
1605 FirstPrint = false;
1606 }
1607 }
Andrew Scull11c9a322015-08-28 14:24:14 -07001608 Str << " weight=" << Var->getWeight(this) << " ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -07001609 Var->dump(this);
1610 Str << " LIVE=" << Var->getLiveRange() << "\n";
1611 }
1612 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001613 // Print each basic block
Jim Stichnothf44f3712014-10-01 14:05:51 -07001614 for (CfgNode *Node : Nodes)
1615 Node->dump(this);
Jim Stichnothfa4efea2015-01-27 05:06:03 -08001616 if (isVerbose(IceV_Instructions))
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001617 Str << "}\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -07001618}
1619
1620} // end of namespace Ice