blob: 6bd9bf77fff8e9d6564feaa43f611e38d045217a [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"
17#include "IceDefs.h"
18#include "IceInst.h"
Jim Stichnothd97c7df2014-06-04 11:57:08 -070019#include "IceLiveness.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070020#include "IceOperand.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070021#include "IceTargetLowering.h"
Jim Stichnothf7c9a142014-04-29 10:52:43 -070022
23namespace Ice {
24
25Cfg::Cfg(GlobalContext *Ctx)
26 : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void),
27 IsInternalLinkage(false), HasError(false), ErrorMessage(""), Entry(NULL),
Jim Stichnothd97c7df2014-06-04 11:57:08 -070028 NextInstNumber(1), Live(NULL),
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070029 Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)),
30 CurrentNode(NULL) {}
Jim Stichnothf7c9a142014-04-29 10:52:43 -070031
32Cfg::~Cfg() {}
33
34void Cfg::setError(const IceString &Message) {
35 HasError = true;
36 ErrorMessage = Message;
37 Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n";
38}
39
40CfgNode *Cfg::makeNode(const IceString &Name) {
41 SizeT LabelIndex = Nodes.size();
42 CfgNode *Node = CfgNode::create(this, LabelIndex, Name);
43 Nodes.push_back(Node);
44 return Node;
45}
46
47// Create a new Variable with a particular type and an optional
48// name. The Node argument is the node where the variable is defined.
49Variable *Cfg::makeVariable(Type Ty, const CfgNode *Node,
50 const IceString &Name) {
51 SizeT Index = Variables.size();
52 Variables.push_back(Variable::create(this, Ty, Node, Index, Name));
53 return Variables[Index];
54}
55
56void Cfg::addArg(Variable *Arg) {
57 Arg->setIsArg(this);
58 Args.push_back(Arg);
59}
60
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070061// Returns whether the stack frame layout has been computed yet. This
62// is used for dumping the stack frame location of Variables.
63bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); }
64
65void Cfg::translate() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070066 if (hasError())
67 return;
68
Jim Stichnothd97c7df2014-06-04 11:57:08 -070069 dump("Initial CFG");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070070
71 Timer T_translate;
72 // The set of translation passes and their order are determined by
73 // the target.
74 getTarget()->translate();
75 T_translate.printElapsedUs(getContext(), "translate()");
76
Jim Stichnothd97c7df2014-06-04 11:57:08 -070077 dump("Final output");
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070078}
79
Jim Stichnothf7c9a142014-04-29 10:52:43 -070080void Cfg::computePredecessors() {
81 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
82 (*I)->computePredecessors();
83 }
84}
85
Jim Stichnothd97c7df2014-06-04 11:57:08 -070086void Cfg::renumberInstructions() {
87 NextInstNumber = 1;
88 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
89 (*I)->renumberInstructions();
90 }
91}
92
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070093// placePhiLoads() must be called before placePhiStores().
94void Cfg::placePhiLoads() {
95 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
96 (*I)->placePhiLoads();
97 }
98}
99
100// placePhiStores() must be called after placePhiLoads().
101void Cfg::placePhiStores() {
102 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
103 (*I)->placePhiStores();
104 }
105}
106
107void Cfg::deletePhis() {
108 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
109 (*I)->deletePhis();
110 }
111}
112
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700113void Cfg::doAddressOpt() {
114 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
115 (*I)->doAddressOpt();
116 }
117}
118
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700119void Cfg::genCode() {
120 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
121 (*I)->genCode();
122 }
123}
124
125// Compute the stack frame layout.
126void Cfg::genFrame() {
127 getTarget()->addProlog(Entry);
128 // TODO: Consider folding epilog generation into the final
129 // emission/assembly pass to avoid an extra iteration over the node
130 // list. Or keep a separate list of exit nodes.
131 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
132 CfgNode *Node = *I;
133 if (Node->getHasReturn())
134 getTarget()->addEpilog(Node);
135 }
136}
137
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700138// This is a lightweight version of live-range-end calculation. Marks
139// the last use of only those variables whose definition and uses are
140// completely with a single block. It is a quick single pass and
141// doesn't need to iterate until convergence.
142void Cfg::livenessLightweight() {
143 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
144 (*I)->livenessLightweight();
145 }
146}
147
148void Cfg::liveness(LivenessMode Mode) {
149 Live.reset(new Liveness(this, Mode));
150 Live->init();
151 // Initialize with all nodes needing to be processed.
152 llvm::BitVector NeedToProcess(Nodes.size(), true);
153 while (NeedToProcess.any()) {
154 // Iterate in reverse topological order to speed up convergence.
155 for (NodeList::reverse_iterator I = Nodes.rbegin(), E = Nodes.rend();
156 I != E; ++I) {
157 CfgNode *Node = *I;
158 if (NeedToProcess[Node->getIndex()]) {
159 NeedToProcess[Node->getIndex()] = false;
160 bool Changed = Node->liveness(getLiveness());
161 if (Changed) {
162 // If the beginning-of-block liveness changed since the last
163 // iteration, mark all in-edges as needing to be processed.
164 const NodeList &InEdges = Node->getInEdges();
165 for (NodeList::const_iterator I1 = InEdges.begin(),
166 E1 = InEdges.end();
167 I1 != E1; ++I1) {
168 CfgNode *Pred = *I1;
169 NeedToProcess[Pred->getIndex()] = true;
170 }
171 }
172 }
173 }
174 }
175 if (Mode == Liveness_Intervals) {
176 // Reset each variable's live range.
177 for (VarList::const_iterator I = Variables.begin(), E = Variables.end();
178 I != E; ++I) {
179 if (Variable *Var = *I)
180 Var->resetLiveRange();
181 }
182 }
183 // Collect timing for just the portion that constructs the live
184 // range intervals based on the end-of-live-range computation, for a
185 // finer breakdown of the cost.
186 Timer T_liveRange;
187 // Make a final pass over instructions to delete dead instructions
188 // and build each Variable's live range.
189 for (NodeList::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
190 (*I)->livenessPostprocess(Mode, getLiveness());
191 }
192 if (Mode == Liveness_Intervals) {
193 // Special treatment for live in-args. Their liveness needs to
194 // extend beyond the beginning of the function, otherwise an arg
195 // whose only use is in the first instruction will end up having
196 // the trivial live range [1,1) and will *not* interfere with
197 // other arguments. So if the first instruction of the method is
198 // "r=arg1+arg2", both args may be assigned the same register.
199 for (SizeT I = 0; I < Args.size(); ++I) {
200 Variable *Arg = Args[I];
201 if (!Live->getLiveRange(Arg).isEmpty()) {
202 // Add live range [-1,0) with weight 0. TODO: Here and below,
203 // use better symbolic constants along the lines of
204 // Inst::NumberDeleted and Inst::NumberSentinel instead of -1
205 // and 0.
206 Live->addLiveRange(Arg, -1, 0, 0);
207 }
208 // Do the same for i64 args that may have been lowered into i32
209 // Lo and Hi components.
210 Variable *Lo = Arg->getLo();
211 if (Lo && !Live->getLiveRange(Lo).isEmpty())
212 Live->addLiveRange(Lo, -1, 0, 0);
213 Variable *Hi = Arg->getHi();
214 if (Hi && !Live->getLiveRange(Hi).isEmpty())
215 Live->addLiveRange(Hi, -1, 0, 0);
216 }
217 // Copy Liveness::LiveRanges into individual variables. TODO:
218 // Remove Variable::LiveRange and redirect to
219 // Liveness::LiveRanges. TODO: make sure Variable weights
220 // are applied properly.
221 SizeT NumVars = Variables.size();
222 for (SizeT i = 0; i < NumVars; ++i) {
223 Variable *Var = Variables[i];
224 Var->setLiveRange(Live->getLiveRange(Var));
225 if (Var->getWeight().isInf())
226 Var->setLiveRangeInfiniteWeight();
227 }
228 T_liveRange.printElapsedUs(getContext(), "live range construction");
229 dump();
230 }
231}
232
233// Traverse every Variable of every Inst and verify that it
234// appears within the Variable's computed live range.
235bool Cfg::validateLiveness() const {
236 bool Valid = true;
237 Ostream &Str = Ctx->getStrDump();
238 for (NodeList::const_iterator I1 = Nodes.begin(), E1 = Nodes.end(); I1 != E1;
239 ++I1) {
240 CfgNode *Node = *I1;
241 InstList &Insts = Node->getInsts();
242 for (InstList::const_iterator I2 = Insts.begin(), E2 = Insts.end();
243 I2 != E2; ++I2) {
244 Inst *Inst = *I2;
245 if (Inst->isDeleted())
246 continue;
247 if (llvm::isa<InstFakeKill>(Inst))
248 continue;
249 InstNumberT InstNumber = Inst->getNumber();
250 Variable *Dest = Inst->getDest();
251 if (Dest) {
252 // TODO: This instruction should actually begin Dest's live
253 // range, so we could probably test that this instruction is
254 // the beginning of some segment of Dest's live range. But
255 // this wouldn't work with non-SSA temporaries during
256 // lowering.
257 if (!Dest->getLiveRange().containsValue(InstNumber)) {
258 Valid = false;
259 Str << "Liveness error: inst " << Inst->getNumber() << " dest ";
260 Dest->dump(this);
261 Str << " live range " << Dest->getLiveRange() << "\n";
262 }
263 }
264 for (SizeT I = 0; I < Inst->getSrcSize(); ++I) {
265 Operand *Src = Inst->getSrc(I);
266 SizeT NumVars = Src->getNumVars();
267 for (SizeT J = 0; J < NumVars; ++J) {
268 const Variable *Var = Src->getVar(J);
269 if (!Var->getLiveRange().containsValue(InstNumber)) {
270 Valid = false;
271 Str << "Liveness error: inst " << Inst->getNumber() << " var ";
272 Var->dump(this);
273 Str << " live range " << Var->getLiveRange() << "\n";
274 }
275 }
276 }
277 }
278 }
279 return Valid;
280}
281
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700282// ======================== Dump routines ======================== //
283
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700284void Cfg::emit() {
285 Ostream &Str = Ctx->getStrEmit();
286 Timer T_emit;
287 if (!Ctx->testAndSetHasEmittedFirstMethod()) {
288 // Print a helpful command for assembling the output.
289 // TODO: have the Target emit the header
290 // TODO: need a per-file emit in addition to per-CFG
291 Str << "# $LLVM_BIN_PATH/llvm-mc"
292 << " -arch=x86"
293 << " -x86-asm-syntax=intel"
294 << " -filetype=obj"
295 << " -o=MyObj.o"
296 << "\n\n";
297 }
298 Str << "\t.text\n";
299 if (!getInternal()) {
300 IceString MangledName = getContext()->mangleName(getFunctionName());
301 Str << "\t.globl\t" << MangledName << "\n";
302 Str << "\t.type\t" << MangledName << ",@function\n";
303 }
304 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E;
305 ++I) {
306 (*I)->emit(this);
307 }
308 Str << "\n";
309 T_emit.printElapsedUs(Ctx, "emit()");
310}
311
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700312// Dumps the IR with an optional introductory message.
313void Cfg::dump(const IceString &Message) {
314 if (!Ctx->isVerbose())
315 return;
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700316 Ostream &Str = Ctx->getStrDump();
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700317 if (!Message.empty())
318 Str << "================ " << Message << " ================\n";
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700319 setCurrentNode(getEntryNode());
320 // Print function name+args
321 if (getContext()->isVerbose(IceV_Instructions)) {
322 Str << "define ";
323 if (getInternal())
324 Str << "internal ";
325 Str << ReturnType << " @" << getFunctionName() << "(";
326 for (SizeT i = 0; i < Args.size(); ++i) {
327 if (i > 0)
328 Str << ", ";
329 Str << Args[i]->getType() << " ";
330 Args[i]->dump(this);
331 }
332 Str << ") {\n";
333 }
334 setCurrentNode(NULL);
Jim Stichnothd97c7df2014-06-04 11:57:08 -0700335 if (getContext()->isVerbose(IceV_Liveness)) {
336 // Print summary info about variables
337 for (VarList::const_iterator I = Variables.begin(), E = Variables.end();
338 I != E; ++I) {
339 Variable *Var = *I;
340 Str << "//"
341 << " multiblock=" << Var->isMultiblockLife() << " "
342 << " weight=" << Var->getWeight() << " ";
343 Var->dump(this);
344 Str << " LIVE=" << Var->getLiveRange() << "\n";
345 }
346 }
Jim Stichnothf7c9a142014-04-29 10:52:43 -0700347 // Print each basic block
348 for (NodeList::const_iterator I = Nodes.begin(), E = Nodes.end(); I != E;
349 ++I) {
350 (*I)->dump(this);
351 }
352 if (getContext()->isVerbose(IceV_Instructions)) {
353 Str << "}\n";
354 }
355}
356
357} // end of namespace Ice