blob: 9726ff92f876099bbb4a7b807185541eaba4fa4c [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
Jim Stichnothae953202014-12-20 06:17:49 -080026thread_local const Cfg *Cfg::CurrentCfg = nullptr;
Jim Stichnoth31c95592014-12-19 12:51:35 -080027
28ArenaAllocator *getCurrentCfgAllocator() {
29 return Cfg::getCurrentCfgAllocator();
30}
31
Jim Stichnothf7c9a142014-04-29 10:52:43 -070032Cfg::Cfg(GlobalContext *Ctx)
33 : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void),
Jim Stichnoth8363a062014-10-07 10:02:38 -070034 IsInternalLinkage(false), HasError(false), FocusedTiming(false),
Jim Stichnothae953202014-12-20 06:17:49 -080035 ErrorMessage(""), Entry(nullptr), NextInstNumber(Inst::NumberInitial),
Jim Stichnoth31c95592014-12-19 12:51:35 -080036 Allocator(new ArenaAllocator()), Live(nullptr),
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070037 Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)),
Jan Voung8acded02014-09-22 18:02:25 -070038 VMetadata(new VariablesMetadata(this)),
39 TargetAssembler(
40 TargetLowering::createAssembler(Ctx->getTargetArch(), this)),
Jim Stichnothae953202014-12-20 06:17:49 -080041 CurrentNode(nullptr) {
Karl Schimpf6fcbddd2014-11-06 09:49:24 -080042 assert(!Ctx->isIRGenerationDisabled() &&
43 "Attempt to build cfg when IR generation disabled");
44}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070045
Jim Stichnoth31c95592014-12-19 12:51:35 -080046Cfg::~Cfg() {
Jim Stichnothae953202014-12-20 06:17:49 -080047 // TODO(stichnot,kschimpf): Set CurrentCfg=nullptr in the dtor for
Jim Stichnoth31c95592014-12-19 12:51:35 -080048 // safety. This can't be done currently because the translator
49 // manages the Cfg by creating a new Cfg (which sets CurrentCfg to
50 // the new value), then deleting the old Cfg (which would then reset
Jim Stichnothae953202014-12-20 06:17:49 -080051 // CurrentCfg to nullptr).
Jim Stichnoth31c95592014-12-19 12:51:35 -080052}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070053
54void Cfg::setError(const IceString &Message) {
55 HasError = true;
56 ErrorMessage = Message;
57 Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n";
58}
59
Jim Stichnoth668a7a32014-12-10 15:32:25 -080060CfgNode *Cfg::makeNode() {
Jim Stichnothf7c9a142014-04-29 10:52:43 -070061 SizeT LabelIndex = Nodes.size();
Jim Stichnoth668a7a32014-12-10 15:32:25 -080062 CfgNode *Node = CfgNode::create(this, LabelIndex);
Jim Stichnothf7c9a142014-04-29 10:52:43 -070063 Nodes.push_back(Node);
64 return Node;
65}
66
Jim Stichnothf7c9a142014-04-29 10:52:43 -070067void Cfg::addArg(Variable *Arg) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -070068 Arg->setIsArg();
Jim Stichnothf7c9a142014-04-29 10:52:43 -070069 Args.push_back(Arg);
70}
71
Jim Stichnoth144cdce2014-09-22 16:02:59 -070072void Cfg::addImplicitArg(Variable *Arg) {
73 Arg->setIsImplicitArg();
74 ImplicitArgs.push_back(Arg);
75}
76
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070077// Returns whether the stack frame layout has been computed yet. This
78// is used for dumping the stack frame location of Variables.
79bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); }
80
81void Cfg::translate() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070082 if (hasError())
83 return;
Jim Stichnoth1c44d812014-12-08 14:57:52 -080084 if (ALLOW_DUMP) {
85 const IceString &TimingFocusOn = getContext()->getFlags().TimingFocusOn;
86 if (TimingFocusOn == "*" || TimingFocusOn == getFunctionName()) {
87 setFocusedTiming();
88 getContext()->resetTimer(GlobalContext::TSK_Default);
89 getContext()->setTimerName(GlobalContext::TSK_Default, getFunctionName());
90 }
Jim Stichnothd14b1a02014-10-08 08:28:36 -070091 }
Jim Stichnoth8363a062014-10-07 10:02:38 -070092 TimerMarker T(TimerStack::TT_translate, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070093
Jim Stichnothd97c7df2014-06-04 11:57:08 -070094 dump("Initial CFG");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070095
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070096 // The set of translation passes and their order are determined by
97 // the target.
98 getTarget()->translate();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070099
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700100 dump("Final output");
Jim Stichnoth8363a062014-10-07 10:02:38 -0700101 if (getFocusedTiming())
102 getContext()->dumpTimers();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700103}
104
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700105void Cfg::computePredecessors() {
Jim Stichnothf44f3712014-10-01 14:05:51 -0700106 for (CfgNode *Node : Nodes)
107 Node->computePredecessors();
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700108}
109
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700110void Cfg::renumberInstructions() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700111 TimerMarker T(TimerStack::TT_renumberInstructions, this);
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800112 NextInstNumber = Inst::NumberInitial;
Jim Stichnothf44f3712014-10-01 14:05:51 -0700113 for (CfgNode *Node : Nodes)
114 Node->renumberInstructions();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700115}
116
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700117// placePhiLoads() must be called before placePhiStores().
118void Cfg::placePhiLoads() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700119 TimerMarker T(TimerStack::TT_placePhiLoads, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700120 for (CfgNode *Node : Nodes)
121 Node->placePhiLoads();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700122}
123
124// placePhiStores() must be called after placePhiLoads().
125void Cfg::placePhiStores() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700126 TimerMarker T(TimerStack::TT_placePhiStores, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700127 for (CfgNode *Node : Nodes)
128 Node->placePhiStores();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700129}
130
131void Cfg::deletePhis() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700132 TimerMarker T(TimerStack::TT_deletePhis, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700133 for (CfgNode *Node : Nodes)
134 Node->deletePhis();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700135}
136
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700137void Cfg::advancedPhiLowering() {
138 TimerMarker T(TimerStack::TT_advancedPhiLowering, this);
139 // This splits edges and appends new nodes to the end of the node
140 // list. This can invalidate iterators, so don't use an iterator.
141 SizeT NumNodes = getNumNodes();
142 for (SizeT I = 0; I < NumNodes; ++I)
143 Nodes[I]->advancedPhiLowering();
144}
145
146// Find a reasonable placement for nodes that have not yet been
147// placed, while maintaining the same relative ordering among already
148// placed nodes.
149void Cfg::reorderNodes() {
150 typedef std::list<CfgNode *> PlacedList;
151 PlacedList Placed; // Nodes with relative placement locked down
152 PlacedList Unreachable; // Unreachable nodes
153 PlacedList::iterator NoPlace = Placed.end();
154 // Keep track of where each node has been tentatively placed so that
155 // we can manage insertions into the middle.
156 std::vector<PlacedList::iterator> PlaceIndex(Nodes.size(), NoPlace);
157 for (CfgNode *Node : Nodes) {
158 // The "do ... while(0);" construct is to factor out the
159 // --PlaceIndex and assert() statements before moving to the next
160 // node.
161 do {
162 if (!Node->needsPlacement()) {
163 // Add to the end of the Placed list.
164 Placed.push_back(Node);
165 PlaceIndex[Node->getIndex()] = Placed.end();
166 continue;
167 }
168 Node->setNeedsPlacement(false);
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800169 if (Node != getEntryNode() && Node->getInEdges().empty()) {
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700170 // The node has essentially been deleted since it is not a
171 // successor of any other node.
172 Unreachable.push_back(Node);
173 PlaceIndex[Node->getIndex()] = Unreachable.end();
174 continue;
175 }
176 // Assume for now that the unplaced node is from edge-splitting
177 // and therefore has 1 in-edge and 1 out-edge (actually, possibly
178 // more than 1 in-edge if the predecessor node was contracted).
179 // If this changes in the future, rethink the strategy.
180 assert(Node->getInEdges().size() >= 1);
181 assert(Node->getOutEdges().size() == 1);
182
183 // If it's a (non-critical) edge where the successor has a single
184 // in-edge, then place it before the successor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800185 CfgNode *Succ = Node->getOutEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700186 if (Succ->getInEdges().size() == 1 &&
187 PlaceIndex[Succ->getIndex()] != NoPlace) {
188 Placed.insert(PlaceIndex[Succ->getIndex()], Node);
189 PlaceIndex[Node->getIndex()] = PlaceIndex[Succ->getIndex()];
190 continue;
191 }
192
193 // Otherwise, place it after the (first) predecessor.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800194 CfgNode *Pred = Node->getInEdges().front();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700195 auto PredPosition = PlaceIndex[Pred->getIndex()];
196 // It shouldn't be the case that PredPosition==NoPlace, but if
197 // that somehow turns out to be true, we just insert Node before
198 // PredPosition=NoPlace=Placed.end() .
199 if (PredPosition != NoPlace)
200 ++PredPosition;
201 Placed.insert(PredPosition, Node);
202 PlaceIndex[Node->getIndex()] = PredPosition;
203 } while (0);
204
205 --PlaceIndex[Node->getIndex()];
206 assert(*PlaceIndex[Node->getIndex()] == Node);
207 }
208
209 // Reorder Nodes according to the built-up lists.
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800210 SizeT OldSize = Nodes.size();
211 (void)OldSize;
212 Nodes.clear();
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700213 for (CfgNode *Node : Placed)
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800214 Nodes.push_back(Node);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700215 for (CfgNode *Node : Unreachable)
Jim Stichnothbfb410d2014-11-05 16:04:05 -0800216 Nodes.push_back(Node);
217 assert(Nodes.size() == OldSize);
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700218}
219
Matt Wala45a06232014-07-09 16:33:22 -0700220void Cfg::doArgLowering() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700221 TimerMarker T(TimerStack::TT_doArgLowering, this);
Matt Wala45a06232014-07-09 16:33:22 -0700222 getTarget()->lowerArguments();
223}
224
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700225void Cfg::doAddressOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700226 TimerMarker T(TimerStack::TT_doAddressOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700227 for (CfgNode *Node : Nodes)
228 Node->doAddressOpt();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700229}
230
Matt Walac3302742014-08-15 16:21:56 -0700231void Cfg::doNopInsertion() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700232 TimerMarker T(TimerStack::TT_doNopInsertion, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700233 for (CfgNode *Node : Nodes)
234 Node->doNopInsertion();
Matt Walac3302742014-08-15 16:21:56 -0700235}
236
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700237void Cfg::genCode() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700238 TimerMarker T(TimerStack::TT_genCode, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700239 for (CfgNode *Node : Nodes)
240 Node->genCode();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700241}
242
243// Compute the stack frame layout.
244void Cfg::genFrame() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700245 TimerMarker T(TimerStack::TT_genFrame, this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700246 getTarget()->addProlog(Entry);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700247 for (CfgNode *Node : Nodes)
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700248 if (Node->getHasReturn())
249 getTarget()->addEpilog(Node);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700250}
251
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700252// This is a lightweight version of live-range-end calculation. Marks
253// the last use of only those variables whose definition and uses are
254// completely with a single block. It is a quick single pass and
255// doesn't need to iterate until convergence.
256void Cfg::livenessLightweight() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700257 TimerMarker T(TimerStack::TT_livenessLightweight, this);
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700258 getVMetadata()->init(VMK_Uses);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700259 for (CfgNode *Node : Nodes)
260 Node->livenessLightweight();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700261}
262
263void Cfg::liveness(LivenessMode Mode) {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700264 TimerMarker T(TimerStack::TT_liveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700265 Live.reset(new Liveness(this, Mode));
Jim Stichnoth877b04e2014-10-15 15:13:06 -0700266 getVMetadata()->init(VMK_Uses);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700267 Live->init();
268 // Initialize with all nodes needing to be processed.
269 llvm::BitVector NeedToProcess(Nodes.size(), true);
270 while (NeedToProcess.any()) {
271 // Iterate in reverse topological order to speed up convergence.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700272 for (auto I = Nodes.rbegin(), E = Nodes.rend(); I != E; ++I) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700273 CfgNode *Node = *I;
274 if (NeedToProcess[Node->getIndex()]) {
275 NeedToProcess[Node->getIndex()] = false;
276 bool Changed = Node->liveness(getLiveness());
277 if (Changed) {
278 // If the beginning-of-block liveness changed since the last
279 // iteration, mark all in-edges as needing to be processed.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700280 for (CfgNode *Pred : Node->getInEdges())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700281 NeedToProcess[Pred->getIndex()] = true;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700282 }
283 }
284 }
285 }
286 if (Mode == Liveness_Intervals) {
287 // Reset each variable's live range.
Jim Stichnothf44f3712014-10-01 14:05:51 -0700288 for (Variable *Var : Variables)
289 Var->resetLiveRange();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700290 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800291 // Make a final pass over each node to delete dead instructions,
292 // collect the first and last instruction numbers, and add live
293 // range segments for that node.
294 for (CfgNode *Node : Nodes) {
295 InstNumberT FirstInstNum = Inst::NumberSentinel;
296 InstNumberT LastInstNum = Inst::NumberSentinel;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800297 for (Inst &I : Node->getPhis()) {
298 I.deleteIfDead();
299 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800300 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800301 FirstInstNum = I.getNumber();
302 assert(I.getNumber() > LastInstNum);
303 LastInstNum = I.getNumber();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700304 }
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800305 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800306 for (Inst &I : Node->getInsts()) {
307 I.deleteIfDead();
308 if (Mode == Liveness_Intervals && !I.isDeleted()) {
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800309 if (FirstInstNum == Inst::NumberSentinel)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800310 FirstInstNum = I.getNumber();
311 assert(I.getNumber() > LastInstNum);
312 LastInstNum = I.getNumber();
Jim Stichnothe5b73e62014-12-15 09:58:51 -0800313 }
314 }
315 if (Mode == Liveness_Intervals) {
316 // Special treatment for live in-args. Their liveness needs to
317 // extend beyond the beginning of the function, otherwise an arg
318 // whose only use is in the first instruction will end up having
319 // the trivial live range [2,2) and will *not* interfere with
320 // other arguments. So if the first instruction of the method
321 // is "r=arg1+arg2", both args may be assigned the same
322 // register. This is accomplished by extending the entry
323 // block's instruction range from [2,n) to [1,n) which will
324 // transform the problematic [2,2) live ranges into [1,2).
325 if (FirstInstNum == Inst::NumberInitial)
326 FirstInstNum = Inst::NumberExtended;
327 Node->livenessAddIntervals(getLiveness(), FirstInstNum, LastInstNum);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700328 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700329 }
330}
331
332// Traverse every Variable of every Inst and verify that it
333// appears within the Variable's computed live range.
334bool Cfg::validateLiveness() const {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700335 TimerMarker T(TimerStack::TT_validateLiveness, this);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700336 bool Valid = true;
337 Ostream &Str = Ctx->getStrDump();
Jim Stichnothf44f3712014-10-01 14:05:51 -0700338 for (CfgNode *Node : Nodes) {
Jim Stichnothae953202014-12-20 06:17:49 -0800339 Inst *FirstInst = nullptr;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800340 for (Inst &Inst : Node->getInsts()) {
341 if (Inst.isDeleted())
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700342 continue;
Jim Stichnothae953202014-12-20 06:17:49 -0800343 if (FirstInst == nullptr)
Jim Stichnoth29841e82014-12-23 12:26:24 -0800344 FirstInst = &Inst;
345 InstNumberT InstNumber = Inst.getNumber();
346 if (Variable *Dest = Inst.getDest()) {
Jim Stichnoth47752552014-10-13 17:15:08 -0700347 if (!Dest->getIgnoreLiveness()) {
348 bool Invalid = false;
349 const bool IsDest = true;
350 if (!Dest->getLiveRange().containsValue(InstNumber, IsDest))
351 Invalid = true;
352 // Check that this instruction actually *begins* Dest's live
353 // range, by checking that Dest is not live in the previous
354 // instruction. As a special exception, we don't check this
355 // for the first instruction of the block, because a Phi
356 // temporary may be live at the end of the previous block,
357 // and if it is also assigned in the first instruction of
358 // this block, the adjacent live ranges get merged.
Jim Stichnoth29841e82014-12-23 12:26:24 -0800359 if (static_cast<class Inst *>(&Inst) != FirstInst &&
360 !Inst.isDestNonKillable() &&
Jim Stichnoth47752552014-10-13 17:15:08 -0700361 Dest->getLiveRange().containsValue(InstNumber - 1, IsDest))
362 Invalid = true;
363 if (Invalid) {
364 Valid = false;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800365 Str << "Liveness error: inst " << Inst.getNumber() << " dest ";
Jim Stichnoth47752552014-10-13 17:15:08 -0700366 Dest->dump(this);
367 Str << " live range " << Dest->getLiveRange() << "\n";
368 }
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700369 }
370 }
Jim Stichnoth29841e82014-12-23 12:26:24 -0800371 for (SizeT I = 0; I < Inst.getSrcSize(); ++I) {
372 Operand *Src = Inst.getSrc(I);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700373 SizeT NumVars = Src->getNumVars();
374 for (SizeT J = 0; J < NumVars; ++J) {
375 const Variable *Var = Src->getVar(J);
Jim Stichnoth47752552014-10-13 17:15:08 -0700376 const bool IsDest = false;
377 if (!Var->getIgnoreLiveness() &&
378 !Var->getLiveRange().containsValue(InstNumber, IsDest)) {
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700379 Valid = false;
Jim Stichnoth29841e82014-12-23 12:26:24 -0800380 Str << "Liveness error: inst " << Inst.getNumber() << " var ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700381 Var->dump(this);
382 Str << " live range " << Var->getLiveRange() << "\n";
383 }
384 }
385 }
386 }
387 }
388 return Valid;
389}
390
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700391void Cfg::contractEmptyNodes() {
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700392 // If we're decorating the asm output with register liveness info,
393 // this information may become corrupted or incorrect after
394 // contracting nodes that contain only redundant assignments. As
395 // such, we disable this pass when DecorateAsm is specified. This
396 // may make the resulting code look more branchy, but it should have
397 // no effect on the register assignments.
398 if (Ctx->getFlags().DecorateAsm)
399 return;
Jim Stichnoth336f6c42014-10-30 15:01:31 -0700400 for (CfgNode *Node : Nodes) {
401 Node->contractIfEmpty();
402 }
403}
404
Jim Stichnothff9c7062014-09-18 04:50:49 -0700405void Cfg::doBranchOpt() {
Jim Stichnoth8363a062014-10-07 10:02:38 -0700406 TimerMarker T(TimerStack::TT_doBranchOpt, this);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700407 for (auto I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
408 auto NextNode = I;
Jim Stichnothff9c7062014-09-18 04:50:49 -0700409 ++NextNode;
Jim Stichnothae953202014-12-20 06:17:49 -0800410 (*I)->doBranchOpt(NextNode == E ? nullptr : *NextNode);
Jim Stichnothff9c7062014-09-18 04:50:49 -0700411 }
412}
413
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700414// ======================== Dump routines ======================== //
415
Jan Voung0faec4c2014-11-05 17:29:56 -0800416void Cfg::emitTextHeader(const IceString &MangledName) {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800417 // Note: Still used by emit IAS.
Jan Voung0faec4c2014-11-05 17:29:56 -0800418 Ostream &Str = Ctx->getStrEmit();
419 Str << "\t.text\n";
420 if (Ctx->getFlags().FunctionSections)
421 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n";
422 if (!getInternal() || Ctx->getFlags().DisableInternal) {
423 Str << "\t.globl\t" << MangledName << "\n";
424 Str << "\t.type\t" << MangledName << ",@function\n";
425 }
Jan Voung08c3bcd2014-12-01 17:55:16 -0800426 Assembler *Asm = getAssembler<Assembler>();
427 Str << "\t.p2align " << Asm->getBundleAlignLog2Bytes() << ",0x";
428 for (uint8_t I : Asm->getNonExecBundlePadding())
Jan Voung0faec4c2014-11-05 17:29:56 -0800429 Str.write_hex(I);
430 Str << "\n";
431 Str << MangledName << ":\n";
432}
433
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700434void Cfg::emit() {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800435 if (!ALLOW_DUMP)
436 return;
Jim Stichnoth8363a062014-10-07 10:02:38 -0700437 TimerMarker T(TimerStack::TT_emit, this);
Jim Stichnoth3d44fe82014-11-01 10:10:18 -0700438 if (Ctx->getFlags().DecorateAsm) {
439 renumberInstructions();
440 getVMetadata()->init(VMK_Uses);
441 liveness(Liveness_Basic);
442 dump("After recomputing liveness for -decorate-asm");
443 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700444 Ostream &Str = Ctx->getStrEmit();
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700445 if (!Ctx->testAndSetHasEmittedFirstMethod()) {
446 // Print a helpful command for assembling the output.
447 // TODO: have the Target emit the header
448 // TODO: need a per-file emit in addition to per-CFG
449 Str << "# $LLVM_BIN_PATH/llvm-mc"
450 << " -arch=x86"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700451 << " -filetype=obj"
452 << " -o=MyObj.o"
453 << "\n\n";
454 }
Jim Stichnoth989a7032014-08-08 10:13:44 -0700455 IceString MangledName = getContext()->mangleName(getFunctionName());
Jan Voung0faec4c2014-11-05 17:29:56 -0800456 emitTextHeader(MangledName);
Jim Stichnothf44f3712014-10-01 14:05:51 -0700457 for (CfgNode *Node : Nodes)
458 Node->emit(this);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700459 Str << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700460}
461
Jan Voung0faec4c2014-11-05 17:29:56 -0800462void Cfg::emitIAS() {
463 TimerMarker T(TimerStack::TT_emit, this);
464 assert(!Ctx->getFlags().DecorateAsm);
465 IceString MangledName = getContext()->mangleName(getFunctionName());
Jan Voung08c3bcd2014-12-01 17:55:16 -0800466 if (!Ctx->getFlags().UseELFWriter)
467 emitTextHeader(MangledName);
Jan Voung0faec4c2014-11-05 17:29:56 -0800468 for (CfgNode *Node : Nodes)
469 Node->emitIAS(this);
Jan Voung08c3bcd2014-12-01 17:55:16 -0800470 // Now write the function to the file and track.
471 if (Ctx->getFlags().UseELFWriter) {
472 getAssembler<Assembler>()->alignFunction();
473 // TODO(jvoung): Transfer remaining fixups too. They may need their
474 // offsets adjusted.
475 Ctx->getObjectWriter()->writeFunctionCode(
476 MangledName, getInternal(), getAssembler<Assembler>()->getBufferView());
477 } else {
478 getAssembler<Assembler>()->emitIASBytes(Ctx);
479 }
Jan Voung0faec4c2014-11-05 17:29:56 -0800480}
481
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700482// Dumps the IR with an optional introductory message.
483void Cfg::dump(const IceString &Message) {
Karl Schimpfb6c96af2014-11-17 10:58:39 -0800484 if (!ALLOW_DUMP)
485 return;
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700486 if (!Ctx->isVerbose())
487 return;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700488 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700489 if (!Message.empty())
490 Str << "================ " << Message << " ================\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700491 setCurrentNode(getEntryNode());
492 // Print function name+args
493 if (getContext()->isVerbose(IceV_Instructions)) {
494 Str << "define ";
Jim Stichnoth088b2be2014-10-23 12:02:08 -0700495 if (getInternal() && !Ctx->getFlags().DisableInternal)
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700496 Str << "internal ";
Karl Schimpfdf6f9d12014-10-20 14:09:00 -0700497 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700498 for (SizeT i = 0; i < Args.size(); ++i) {
499 if (i > 0)
500 Str << ", ";
501 Str << Args[i]->getType() << " ";
502 Args[i]->dump(this);
503 }
504 Str << ") {\n";
505 }
Jim Stichnoth800dab22014-09-20 12:25:02 -0700506 resetCurrentNode();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700507 if (getContext()->isVerbose(IceV_Liveness)) {
508 // Print summary info about variables
Jim Stichnothf44f3712014-10-01 14:05:51 -0700509 for (Variable *Var : Variables) {
Jim Stichnoth144cdce2014-09-22 16:02:59 -0700510 Str << "// multiblock=";
511 if (getVMetadata()->isTracked(Var))
512 Str << getVMetadata()->isMultiBlock(Var);
513 else
514 Str << "?";
515 Str << " weight=" << Var->getWeight() << " ";
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700516 Var->dump(this);
517 Str << " LIVE=" << Var->getLiveRange() << "\n";
518 }
519 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700520 // Print each basic block
Jim Stichnothf44f3712014-10-01 14:05:51 -0700521 for (CfgNode *Node : Nodes)
522 Node->dump(this);
523 if (getContext()->isVerbose(IceV_Instructions))
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700524 Str << "}\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700525}
526
527} // end of namespace Ice