blob: e40bd1609c0088d28d2ae4be7034c3da3b579218 [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//===----------------------------------------------------------------------===//
9//
10// This file implements the Cfg class, including constant pool
11// management.
12//
13//===----------------------------------------------------------------------===//
14
15#include "IceCfg.h"
16#include "IceCfgNode.h"
Jim Stichnoth989a7032014-08-08 10:13:44 -070017#include "IceClFlags.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070018#include "IceDefs.h"
19#include "IceInst.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070020#include "IceLiveness.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070021#include "IceOperand.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070022#include "IceTargetLowering.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070023
24namespace Ice {
25
26Cfg::Cfg(GlobalContext *Ctx)
27 : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void),
Jim Stichnoth8363a062014-10-07 10:02:38 -070028 IsInternalLinkage(false), HasError(false), FocusedTiming(false),
29 ErrorMessage(""), Entry(NULL), NextInstNumber(1), Live(nullptr),
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070030 Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)),
Jan Voung8acded02014-09-22 18:02:25 -070031 VMetadata(new VariablesMetadata(this)),
32 TargetAssembler(
33 TargetLowering::createAssembler(Ctx->getTargetArch(), this)),
Karl Schimpf6fcbddd2014-11-06 09:49:24 -080034 CurrentNode(NULL) {
35 assert(!Ctx->isIRGenerationDisabled() &&
36 "Attempt to build cfg when IR generation disabled");
37}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070038
39Cfg::~Cfg() {}
40
41void Cfg::setError(const IceString &Message) {
42 HasError = true;
43 ErrorMessage = Message;
44 Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n";
45}
46
47CfgNode *Cfg::makeNode(const IceString &Name) {
48 SizeT LabelIndex = Nodes.size();
49 CfgNode *Node = CfgNode::create(this, LabelIndex, Name);
50 Nodes.push_back(Node);
51 return Node;
52}
53
Jim Stichnothf7c9a142014-04-29 10:52:43 -070054void Cfg::addArg(Variable *Arg) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -070055 Arg->setIsArg();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070056 Args.push_back(Arg);
57}
58
Jim Stichnoth144cdce2014-09-22 16:02:59 -070059void Cfg::addImplicitArg(Variable *Arg) {
60 Arg->setIsImplicitArg();
61 ImplicitArgs.push_back(Arg);
62}
63
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070064// Returns whether the stack frame layout has been computed yet. This
65// is used for dumping the stack frame location of Variables.
66bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); }
67
68void Cfg::translate() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070069 if (hasError())
70 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -070071 const IceString &TimingFocusOn = getContext()->getFlags().TimingFocusOn;
Jim Stichnothd14b1a02014-10-08 08:28:36 -070072 if (TimingFocusOn == "*" || TimingFocusOn == getFunctionName()) {
Jim Stichnoth8363a062014-10-07 10:02:38 -070073 setFocusedTiming();
Jim Stichnothd14b1a02014-10-08 08:28:36 -070074 getContext()->resetTimer(GlobalContext::TSK_Default);
75 getContext()->setTimerName(GlobalContext::TSK_Default, getFunctionName());
76 }
Jim Stichnoth8363a062014-10-07 10:02:38 -070077 TimerMarker T(TimerStack::TT_translate, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070078
Jim Stichnothd97c7df2014-06-04 11:57:08 -070079 dump("Initial CFG");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070080
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070081 // The set of translation passes and their order are determined by
82 // the target.
83 getTarget()->translate();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070084
Jim Stichnothd97c7df2014-06-04 11:57:08 -070085 dump("Final output");
Jim Stichnoth8363a062014-10-07 10:02:38 -070086 if (getFocusedTiming())
87 getContext()->dumpTimers();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070088}
89
Jim Stichnothf7c9a142014-04-29 10:52:43 -070090void Cfg::computePredecessors() {
Jim Stichnothf44f3712014-10-01 14:05:51 -070091 for (CfgNode *Node : Nodes)
92 Node->computePredecessors();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070093}
94
Jim Stichnothd97c7df2014-06-04 11:57:08 -070095void Cfg::renumberInstructions() {
Jim Stichnoth8363a062014-10-07 10:02:38 -070096 TimerMarker T(TimerStack::TT_renumberInstructions, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -070097 NextInstNumber = 1;
Jim Stichnothf44f3712014-10-01 14:05:51 -070098 for (CfgNode *Node : Nodes)
99 Node->renumberInstructions();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700100}
101
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700102// placePhiLoads() must be called before placePhiStores().
103void Cfg::placePhiLoads() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700104 TimerMarker T(TimerStack::TT_placePhiLoads, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700105 for (CfgNode *Node : Nodes)
106 Node->placePhiLoads();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700107}
108
109// placePhiStores() must be called after placePhiLoads().
110void Cfg::placePhiStores() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700111 TimerMarker T(TimerStack::TT_placePhiStores, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700112 for (CfgNode *Node : Nodes)
113 Node->placePhiStores();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700114}
115
116void Cfg::deletePhis() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700117 TimerMarker T(TimerStack::TT_deletePhis, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700118 for (CfgNode *Node : Nodes)
119 Node->deletePhis();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700120}
121
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700122void Cfg::advancedPhiLowering() {
123 TimerMarker T(TimerStack::TT_advancedPhiLowering, this);
124 // This splits edges and appends new nodes to the end of the node
125 // list. This can invalidate iterators, so don't use an iterator.
126 SizeT NumNodes = getNumNodes();
127 for (SizeT I = 0; I < NumNodes; ++I)
128 Nodes[I]->advancedPhiLowering();
129}
130
131// Find a reasonable placement for nodes that have not yet been
132// placed, while maintaining the same relative ordering among already
133// placed nodes.
134void Cfg::reorderNodes() {
135 typedef std::list<CfgNode *> PlacedList;
136 PlacedList Placed; // Nodes with relative placement locked down
137 PlacedList Unreachable; // Unreachable nodes
138 PlacedList::iterator NoPlace = Placed.end();
139 // Keep track of where each node has been tentatively placed so that
140 // we can manage insertions into the middle.
141 std::vector<PlacedList::iterator> PlaceIndex(Nodes.size(), NoPlace);
142 for (CfgNode *Node : Nodes) {
143 // The "do ... while(0);" construct is to factor out the
144 // --PlaceIndex and assert() statements before moving to the next
145 // node.
146 do {
147 if (!Node->needsPlacement()) {
148 // Add to the end of the Placed list.
149 Placed.push_back(Node);
150 PlaceIndex[Node->getIndex()] = Placed.end();
151 continue;
152 }
153 Node->setNeedsPlacement(false);
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800154 if (Node != getEntryNode() && Node->getInEdges().empty()) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700155 // The node has essentially been deleted since it is not a
156 // successor of any other node.
157 Unreachable.push_back(Node);
158 PlaceIndex[Node->getIndex()] = Unreachable.end();
159 continue;
160 }
161 // Assume for now that the unplaced node is from edge-splitting
162 // and therefore has 1 in-edge and 1 out-edge (actually, possibly
163 // more than 1 in-edge if the predecessor node was contracted).
164 // If this changes in the future, rethink the strategy.
165 assert(Node->getInEdges().size() >= 1);
166 assert(Node->getOutEdges().size() == 1);
167
168 // If it's a (non-critical) edge where the successor has a single
169 // in-edge, then place it before the successor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800170 CfgNode *Succ = Node->getOutEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700171 if (Succ->getInEdges().size() == 1 &&
172 PlaceIndex[Succ->getIndex()] != NoPlace) {
173 Placed.insert(PlaceIndex[Succ->getIndex()], Node);
174 PlaceIndex[Node->getIndex()] = PlaceIndex[Succ->getIndex()];
175 continue;
176 }
177
178 // Otherwise, place it after the (first) predecessor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800179 CfgNode *Pred = Node->getInEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700180 auto PredPosition = PlaceIndex[Pred->getIndex()];
181 // It shouldn't be the case that PredPosition==NoPlace, but if
182 // that somehow turns out to be true, we just insert Node before
183 // PredPosition=NoPlace=Placed.end() .
184 if (PredPosition != NoPlace)
185 ++PredPosition;
186 Placed.insert(PredPosition, Node);
187 PlaceIndex[Node->getIndex()] = PredPosition;
188 } while (0);
189
190 --PlaceIndex[Node->getIndex()];
191 assert(*PlaceIndex[Node->getIndex()] == Node);
192 }
193
194 // Reorder Nodes according to the built-up lists.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800195 SizeT OldSize = Nodes.size();
196 (void)OldSize;
197 Nodes.clear();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700198 for (CfgNode *Node : Placed)
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800199 Nodes.push_back(Node);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700200 for (CfgNode *Node : Unreachable)
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800201 Nodes.push_back(Node);
202 assert(Nodes.size() == OldSize);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700203}
204
Matt Wala45a06232014-07-09 16:33:22 -0700205void Cfg::doArgLowering() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700206 TimerMarker T(TimerStack::TT_doArgLowering, this);
Matt Wala45a06232014-07-09 16:33:22 -0700207 getTarget()->lowerArguments();
208}
209
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700210void Cfg::doAddressOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700211 TimerMarker T(TimerStack::TT_doAddressOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700212 for (CfgNode *Node : Nodes)
213 Node->doAddressOpt();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700214}
215
Matt Walac3302742014-08-15 16:21:56 -0700216void Cfg::doNopInsertion() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700217 TimerMarker T(TimerStack::TT_doNopInsertion, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700218 for (CfgNode *Node : Nodes)
219 Node->doNopInsertion();
Matt Walac3302742014-08-15 16:21:56 -0700220}
221
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700222void Cfg::genCode() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700223 TimerMarker T(TimerStack::TT_genCode, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700224 for (CfgNode *Node : Nodes)
225 Node->genCode();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700226}
227
228// Compute the stack frame layout.
229void Cfg::genFrame() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700230 TimerMarker T(TimerStack::TT_genFrame, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700231 getTarget()->addProlog(Entry);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700232 for (CfgNode *Node : Nodes)
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700233 if (Node->getHasReturn())
234 getTarget()->addEpilog(Node);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700235}
236
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700237// This is a lightweight version of live-range-end calculation. Marks
238// the last use of only those variables whose definition and uses are
239// completely with a single block. It is a quick single pass and
240// doesn't need to iterate until convergence.
241void Cfg::livenessLightweight() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700242 TimerMarker T(TimerStack::TT_livenessLightweight, this);
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700243 getVMetadata()->init(VMK_Uses);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700244 for (CfgNode *Node : Nodes)
245 Node->livenessLightweight();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700246}
247
248void Cfg::liveness(LivenessMode Mode) {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700249 TimerMarker T(TimerStack::TT_liveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700250 Live.reset(new Liveness(this, Mode));
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700251 getVMetadata()->init(VMK_Uses);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700252 Live->init();
253 // Initialize with all nodes needing to be processed.
254 llvm::BitVector NeedToProcess(Nodes.size(), true);
255 while (NeedToProcess.any()) {
256 // Iterate in reverse topological order to speed up convergence.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700257 // TODO(stichnot): Use llvm::make_range with LLVM 3.5.
258 for (auto I = Nodes.rbegin(), E = Nodes.rend(); I != E; ++I) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700259 CfgNode *Node = *I;
260 if (NeedToProcess[Node->getIndex()]) {
261 NeedToProcess[Node->getIndex()] = false;
262 bool Changed = Node->liveness(getLiveness());
263 if (Changed) {
264 // If the beginning-of-block liveness changed since the last
265 // iteration, mark all in-edges as needing to be processed.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700266 for (CfgNode *Pred : Node->getInEdges())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700267 NeedToProcess[Pred->getIndex()] = true;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700268 }
269 }
270 }
271 }
272 if (Mode == Liveness_Intervals) {
273 // Reset each variable's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700274 for (Variable *Var : Variables)
275 Var->resetLiveRange();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700276 }
277 // Collect timing for just the portion that constructs the live
278 // range intervals based on the end-of-live-range computation, for a
279 // finer breakdown of the cost.
Jim Stichnoth47752552014-10-13 17:15:08 -0700280 TimerMarker T1(TimerStack::TT_liveRange, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700281 // Make a final pass over instructions to delete dead instructions
282 // and build each Variable's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700283 for (CfgNode *Node : Nodes)
284 Node->livenessPostprocess(Mode, getLiveness());
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700285 if (Mode == Liveness_Intervals) {
286 // Special treatment for live in-args. Their liveness needs to
287 // extend beyond the beginning of the function, otherwise an arg
288 // whose only use is in the first instruction will end up having
289 // the trivial live range [1,1) and will *not* interfere with
290 // other arguments. So if the first instruction of the method is
291 // "r=arg1+arg2", both args may be assigned the same register.
292 for (SizeT I = 0; I < Args.size(); ++I) {
293 Variable *Arg = Args[I];
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700294 if (!Arg->getLiveRange().isEmpty()) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700295 // Add live range [-1,0) with weight 0. TODO: Here and below,
296 // use better symbolic constants along the lines of
297 // Inst::NumberDeleted and Inst::NumberSentinel instead of -1
298 // and 0.
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700299 Arg->addLiveRange(-1, 0, 0);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700300 }
301 // Do the same for i64 args that may have been lowered into i32
302 // Lo and Hi components.
303 Variable *Lo = Arg->getLo();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700304 if (Lo && !Lo->getLiveRange().isEmpty())
305 Lo->addLiveRange(-1, 0, 0);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700306 Variable *Hi = Arg->getHi();
Jim Stichnoth5ce0abb2014-10-15 10:16:54 -0700307 if (Hi && !Hi->getLiveRange().isEmpty())
308 Hi->addLiveRange(-1, 0, 0);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700309 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700310 }
311}
312
313// Traverse every Variable of every Inst and verify that it
314// appears within the Variable's computed live range.
315bool Cfg::validateLiveness() const {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700316 TimerMarker T(TimerStack::TT_validateLiveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700317 bool Valid = true;
318 Ostream &Str = Ctx->getStrDump();
Jim Stichnothf44f3712014-10-01 14:05:51 -0700319 for (CfgNode *Node : Nodes) {
Jim Stichnoth47752552014-10-13 17:15:08 -0700320 Inst *FirstInst = NULL;
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800321 for (auto Inst = Node->getInsts().begin(), E = Node->getInsts().end();
322 Inst != E; ++Inst) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700323 if (Inst->isDeleted())
324 continue;
Jim Stichnoth47752552014-10-13 17:15:08 -0700325 if (FirstInst == NULL)
326 FirstInst = Inst;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700327 InstNumberT InstNumber = Inst->getNumber();
Jim Stichnoth47752552014-10-13 17:15:08 -0700328 if (Variable *Dest = Inst->getDest()) {
329 if (!Dest->getIgnoreLiveness()) {
330 bool Invalid = false;
331 const bool IsDest = true;
332 if (!Dest->getLiveRange().containsValue(InstNumber, IsDest))
333 Invalid = true;
334 // Check that this instruction actually *begins* Dest's live
335 // range, by checking that Dest is not live in the previous
336 // instruction. As a special exception, we don't check this
337 // for the first instruction of the block, because a Phi
338 // temporary may be live at the end of the previous block,
339 // and if it is also assigned in the first instruction of
340 // this block, the adjacent live ranges get merged.
Jim Stichnoth607e9f02014-11-06 13:32:05 -0800341 if (static_cast<class Inst *>(Inst) != FirstInst &&
342 !Inst->isDestNonKillable() &&
Jim Stichnoth47752552014-10-13 17:15:08 -0700343 Dest->getLiveRange().containsValue(InstNumber - 1, IsDest))
344 Invalid = true;
345 if (Invalid) {
346 Valid = false;
347 Str << "Liveness error: inst " << Inst->getNumber() << " dest ";
348 Dest->dump(this);
349 Str << " live range " << Dest->getLiveRange() << "\n";
350 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700351 }
352 }
353 for (SizeT I = 0; I < Inst->getSrcSize(); ++I) {
354 Operand *Src = Inst->getSrc(I);
355 SizeT NumVars = Src->getNumVars();
356 for (SizeT J = 0; J < NumVars; ++J) {
357 const Variable *Var = Src->getVar(J);
Jim Stichnoth47752552014-10-13 17:15:08 -0700358 const bool IsDest = false;
359 if (!Var->getIgnoreLiveness() &&
360 !Var->getLiveRange().containsValue(InstNumber, IsDest)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700361 Valid = false;
362 Str << "Liveness error: inst " << Inst->getNumber() << " var ";
363 Var->dump(this);
364 Str << " live range " << Var->getLiveRange() << "\n";
365 }
366 }
367 }
368 }
369 }
370 return Valid;
371}
372
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700373void Cfg::contractEmptyNodes() {
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700374 // If we're decorating the asm output with register liveness info,
375 // this information may become corrupted or incorrect after
376 // contracting nodes that contain only redundant assignments. As
377 // such, we disable this pass when DecorateAsm is specified. This
378 // may make the resulting code look more branchy, but it should have
379 // no effect on the register assignments.
380 if (Ctx->getFlags().DecorateAsm)
381 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700382 for (CfgNode *Node : Nodes) {
383 Node->contractIfEmpty();
384 }
385}
386
Jim Stichnothff9c7062014-09-18 04:50:49 -0700387void Cfg::doBranchOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700388 TimerMarker T(TimerStack::TT_doBranchOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700389 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
390 auto NextNode = I;
Jim Stichnothff9c7062014-09-18 04:50:49 -0700391 ++NextNode;
Jim Stichnothc4554d72014-09-30 16:49:38 -0700392 (*I)->doBranchOpt(NextNode == E ? NULL : *NextNode);
Jim Stichnothff9c7062014-09-18 04:50:49 -0700393 }
394}
395
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700396// ======================== Dump routines ======================== //
397
Jan Voung0faec4c2014-11-05 17:29:56 -0800398void Cfg::emitTextHeader(const IceString &MangledName) {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800399 // Note: Still used by emit IAS.
Jan Voung0faec4c2014-11-05 17:29:56 -0800400 Ostream &Str = Ctx->getStrEmit();
401 Str << "\t.text\n";
402 if (Ctx->getFlags().FunctionSections)
403 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n";
404 if (!getInternal() || Ctx->getFlags().DisableInternal) {
405 Str << "\t.globl\t" << MangledName << "\n";
406 Str << "\t.type\t" << MangledName << ",@function\n";
407 }
Jan Voung08c3bcd2014-12-01 17:55:16 -0800408 Assembler *Asm = getAssembler<Assembler>();
409 Str << "\t.p2align " << Asm->getBundleAlignLog2Bytes() << ",0x";
410 for (uint8_t I : Asm->getNonExecBundlePadding())
Jan Voung0faec4c2014-11-05 17:29:56 -0800411 Str.write_hex(I);
412 Str << "\n";
413 Str << MangledName << ":\n";
414}
415
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700416void Cfg::emit() {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800417 if (!ALLOW_DUMP)
418 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700419 TimerMarker T(TimerStack::TT_emit, this);
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700420 if (Ctx->getFlags().DecorateAsm) {
421 renumberInstructions();
422 getVMetadata()->init(VMK_Uses);
423 liveness(Liveness_Basic);
424 dump("After recomputing liveness for -decorate-asm");
425 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700426 Ostream &Str = Ctx->getStrEmit();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700427 if (!Ctx->testAndSetHasEmittedFirstMethod()) {
428 // Print a helpful command for assembling the output.
429 // TODO: have the Target emit the header
430 // TODO: need a per-file emit in addition to per-CFG
431 Str << "# $LLVM_BIN_PATH/llvm-mc"
432 << " -arch=x86"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700433 << " -filetype=obj"
434 << " -o=MyObj.o"
435 << "\n\n";
436 }
Jim Stichnoth989a7032014-08-08 10:13:44 -0700437 IceString MangledName = getContext()->mangleName(getFunctionName());
Jan Voung0faec4c2014-11-05 17:29:56 -0800438 emitTextHeader(MangledName);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700439 for (CfgNode *Node : Nodes)
440 Node->emit(this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700441 Str << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700442}
443
Jan Voung0faec4c2014-11-05 17:29:56 -0800444void Cfg::emitIAS() {
445 TimerMarker T(TimerStack::TT_emit, this);
446 assert(!Ctx->getFlags().DecorateAsm);
447 IceString MangledName = getContext()->mangleName(getFunctionName());
Jan Voung08c3bcd2014-12-01 17:55:16 -0800448 if (!Ctx->getFlags().UseELFWriter)
449 emitTextHeader(MangledName);
Jan Voung0faec4c2014-11-05 17:29:56 -0800450 for (CfgNode *Node : Nodes)
451 Node->emitIAS(this);
Jan Voung08c3bcd2014-12-01 17:55:16 -0800452 // Now write the function to the file and track.
453 if (Ctx->getFlags().UseELFWriter) {
454 getAssembler<Assembler>()->alignFunction();
455 // TODO(jvoung): Transfer remaining fixups too. They may need their
456 // offsets adjusted.
457 Ctx->getObjectWriter()->writeFunctionCode(
458 MangledName, getInternal(), getAssembler<Assembler>()->getBufferView());
459 } else {
460 getAssembler<Assembler>()->emitIASBytes(Ctx);
461 }
Jan Voung0faec4c2014-11-05 17:29:56 -0800462}
463
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700464// Dumps the IR with an optional introductory message.
465void Cfg::dump(const IceString &Message) {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800466 if (!ALLOW_DUMP)
467 return;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700468 if (!Ctx->isVerbose())
469 return;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700470 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700471 if (!Message.empty())
472 Str << "================ " << Message << " ================\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700473 setCurrentNode(getEntryNode());
474 // Print function name+args
475 if (getContext()->isVerbose(IceV_Instructions)) {
476 Str << "define ";
Jim Stichnoth088b2be2014-10-23 12:02:08 -0700477 if (getInternal() && !Ctx->getFlags().DisableInternal)
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700478 Str << "internal ";
Karl Schimpfdf6f9d12014-10-20 14:09:00 -0700479 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700480 for (SizeT i = 0; i < Args.size(); ++i) {
481 if (i > 0)
482 Str << ", ";
483 Str << Args[i]->getType() << " ";
484 Args[i]->dump(this);
485 }
486 Str << ") {\n";
487 }
Jim Stichnoth800dab22014-09-20 12:25:02 -0700488 resetCurrentNode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700489 if (getContext()->isVerbose(IceV_Liveness)) {
490 // Print summary info about variables
Jim Stichnothf44f3712014-10-01 14:05:51 -0700491 for (Variable *Var : Variables) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700492 Str << "// multiblock=";
493 if (getVMetadata()->isTracked(Var))
494 Str << getVMetadata()->isMultiBlock(Var);
495 else
496 Str << "?";
497 Str << " weight=" << Var->getWeight() << " ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700498 Var->dump(this);
499 Str << " LIVE=" << Var->getLiveRange() << "\n";
500 }
501 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700502 // Print each basic block
Jim Stichnothf44f3712014-10-01 14:05:51 -0700503 for (CfgNode *Node : Nodes)
504 Node->dump(this);
505 if (getContext()->isVerbose(IceV_Instructions))
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700506 Str << "}\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700507}
508
509} // end of namespace Ice