OLD | NEW |
1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// | 1 //===- subzero/src/IceCfg.cpp - Control flow graph implementation ---------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the Cfg class, including constant pool | 10 // This file implements the Cfg class, including constant pool |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 ImplicitArgs.push_back(Arg); | 58 ImplicitArgs.push_back(Arg); |
59 } | 59 } |
60 | 60 |
61 // Returns whether the stack frame layout has been computed yet. This | 61 // Returns whether the stack frame layout has been computed yet. This |
62 // is used for dumping the stack frame location of Variables. | 62 // is used for dumping the stack frame location of Variables. |
63 bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); } | 63 bool Cfg::hasComputedFrame() const { return getTarget()->hasComputedFrame(); } |
64 | 64 |
65 void Cfg::translate() { | 65 void Cfg::translate() { |
66 if (hasError()) | 66 if (hasError()) |
67 return; | 67 return; |
68 VerboseMask OldVerboseMask = getContext()->getVerbose(); | |
69 const IceString &TimingFocusOn = getContext()->getFlags().TimingFocusOn; | 68 const IceString &TimingFocusOn = getContext()->getFlags().TimingFocusOn; |
70 if (TimingFocusOn == "*" || TimingFocusOn == getFunctionName()) { | 69 if (TimingFocusOn == "*" || TimingFocusOn == getFunctionName()) { |
71 setFocusedTiming(); | 70 setFocusedTiming(); |
72 getContext()->resetTimer(GlobalContext::TSK_Default); | 71 getContext()->resetTimer(GlobalContext::TSK_Default); |
73 getContext()->setTimerName(GlobalContext::TSK_Default, getFunctionName()); | 72 getContext()->setTimerName(GlobalContext::TSK_Default, getFunctionName()); |
74 } | 73 } |
75 bool VerboseFocus = | |
76 (getContext()->getFlags().VerboseFocusOn == getFunctionName()); | |
77 if (VerboseFocus) | |
78 getContext()->setVerbose(IceV_All); | |
79 TimerMarker T(TimerStack::TT_translate, this); | 74 TimerMarker T(TimerStack::TT_translate, this); |
80 | 75 |
81 dump("Initial CFG"); | 76 dump("Initial CFG"); |
82 | 77 |
83 // The set of translation passes and their order are determined by | 78 // The set of translation passes and their order are determined by |
84 // the target. | 79 // the target. |
85 getTarget()->translate(); | 80 getTarget()->translate(); |
86 | 81 |
87 dump("Final output"); | 82 dump("Final output"); |
88 if (getFocusedTiming()) | 83 if (getFocusedTiming()) |
89 getContext()->dumpTimers(); | 84 getContext()->dumpTimers(); |
90 if (VerboseFocus) | |
91 getContext()->setVerbose(OldVerboseMask); | |
92 } | 85 } |
93 | 86 |
94 void Cfg::computePredecessors() { | 87 void Cfg::computePredecessors() { |
95 for (CfgNode *Node : Nodes) | 88 for (CfgNode *Node : Nodes) |
96 Node->computePredecessors(); | 89 Node->computePredecessors(); |
97 } | 90 } |
98 | 91 |
99 void Cfg::renumberInstructions() { | 92 void Cfg::renumberInstructions() { |
100 TimerMarker T(TimerStack::TT_renumberInstructions, this); | 93 TimerMarker T(TimerStack::TT_renumberInstructions, this); |
101 NextInstNumber = 1; | 94 NextInstNumber = 1; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 void Cfg::genCode() { | 136 void Cfg::genCode() { |
144 TimerMarker T(TimerStack::TT_genCode, this); | 137 TimerMarker T(TimerStack::TT_genCode, this); |
145 for (CfgNode *Node : Nodes) | 138 for (CfgNode *Node : Nodes) |
146 Node->genCode(); | 139 Node->genCode(); |
147 } | 140 } |
148 | 141 |
149 // Compute the stack frame layout. | 142 // Compute the stack frame layout. |
150 void Cfg::genFrame() { | 143 void Cfg::genFrame() { |
151 TimerMarker T(TimerStack::TT_genFrame, this); | 144 TimerMarker T(TimerStack::TT_genFrame, this); |
152 getTarget()->addProlog(Entry); | 145 getTarget()->addProlog(Entry); |
153 // TODO: Consider folding epilog generation into the final | |
154 // emission/assembly pass to avoid an extra iteration over the node | |
155 // list. Or keep a separate list of exit nodes. | |
156 for (CfgNode *Node : Nodes) | 146 for (CfgNode *Node : Nodes) |
157 if (Node->getHasReturn()) | 147 if (Node->getHasReturn()) |
158 getTarget()->addEpilog(Node); | 148 getTarget()->addEpilog(Node); |
159 } | 149 } |
160 | 150 |
161 // This is a lightweight version of live-range-end calculation. Marks | 151 // This is a lightweight version of live-range-end calculation. Marks |
162 // the last use of only those variables whose definition and uses are | 152 // the last use of only those variables whose definition and uses are |
163 // completely with a single block. It is a quick single pass and | 153 // completely with a single block. It is a quick single pass and |
164 // doesn't need to iterate until convergence. | 154 // doesn't need to iterate until convergence. |
165 void Cfg::livenessLightweight() { | 155 void Cfg::livenessLightweight() { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 << " -arch=x86" | 306 << " -arch=x86" |
317 << " -x86-asm-syntax=intel" | 307 << " -x86-asm-syntax=intel" |
318 << " -filetype=obj" | 308 << " -filetype=obj" |
319 << " -o=MyObj.o" | 309 << " -o=MyObj.o" |
320 << "\n\n"; | 310 << "\n\n"; |
321 } | 311 } |
322 Str << "\t.text\n"; | 312 Str << "\t.text\n"; |
323 IceString MangledName = getContext()->mangleName(getFunctionName()); | 313 IceString MangledName = getContext()->mangleName(getFunctionName()); |
324 if (Ctx->getFlags().FunctionSections) | 314 if (Ctx->getFlags().FunctionSections) |
325 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n"; | 315 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n"; |
326 if (!getInternal()) { | 316 if (!getInternal() || Ctx->getFlags().DisableInternal) { |
327 Str << "\t.globl\t" << MangledName << "\n"; | 317 Str << "\t.globl\t" << MangledName << "\n"; |
328 Str << "\t.type\t" << MangledName << ",@function\n"; | 318 Str << "\t.type\t" << MangledName << ",@function\n"; |
329 } | 319 } |
330 Str << "\t.p2align " << getTarget()->getBundleAlignLog2Bytes() << ",0x"; | 320 Str << "\t.p2align " << getTarget()->getBundleAlignLog2Bytes() << ",0x"; |
331 for (AsmCodeByte I : getTarget()->getNonExecBundlePadding()) | 321 for (AsmCodeByte I : getTarget()->getNonExecBundlePadding()) |
332 Str.write_hex(I); | 322 Str.write_hex(I); |
333 Str << "\n"; | 323 Str << "\n"; |
334 for (CfgNode *Node : Nodes) | 324 for (CfgNode *Node : Nodes) |
335 Node->emit(this); | 325 Node->emit(this); |
336 Str << "\n"; | 326 Str << "\n"; |
337 } | 327 } |
338 | 328 |
339 // Dumps the IR with an optional introductory message. | 329 // Dumps the IR with an optional introductory message. |
340 void Cfg::dump(const IceString &Message) { | 330 void Cfg::dump(const IceString &Message) { |
341 if (!Ctx->isVerbose()) | 331 if (!Ctx->isVerbose()) |
342 return; | 332 return; |
343 Ostream &Str = Ctx->getStrDump(); | 333 Ostream &Str = Ctx->getStrDump(); |
344 if (!Message.empty()) | 334 if (!Message.empty()) |
345 Str << "================ " << Message << " ================\n"; | 335 Str << "================ " << Message << " ================\n"; |
346 setCurrentNode(getEntryNode()); | 336 setCurrentNode(getEntryNode()); |
347 // Print function name+args | 337 // Print function name+args |
348 if (getContext()->isVerbose(IceV_Instructions)) { | 338 if (getContext()->isVerbose(IceV_Instructions)) { |
349 Str << "define "; | 339 Str << "define "; |
350 if (getInternal()) | 340 if (getInternal() && !Ctx->getFlags().DisableInternal) |
351 Str << "internal "; | 341 Str << "internal "; |
352 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "("; | 342 Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "("; |
353 for (SizeT i = 0; i < Args.size(); ++i) { | 343 for (SizeT i = 0; i < Args.size(); ++i) { |
354 if (i > 0) | 344 if (i > 0) |
355 Str << ", "; | 345 Str << ", "; |
356 Str << Args[i]->getType() << " "; | 346 Str << Args[i]->getType() << " "; |
357 Args[i]->dump(this); | 347 Args[i]->dump(this); |
358 } | 348 } |
359 Str << ") {\n"; | 349 Str << ") {\n"; |
360 } | 350 } |
(...skipping 12 matching lines...) Expand all Loading... |
373 } | 363 } |
374 } | 364 } |
375 // Print each basic block | 365 // Print each basic block |
376 for (CfgNode *Node : Nodes) | 366 for (CfgNode *Node : Nodes) |
377 Node->dump(this); | 367 Node->dump(this); |
378 if (getContext()->isVerbose(IceV_Instructions)) | 368 if (getContext()->isVerbose(IceV_Instructions)) |
379 Str << "}\n"; | 369 Str << "}\n"; |
380 } | 370 } |
381 | 371 |
382 } // end of namespace Ice | 372 } // end of namespace Ice |
OLD | NEW |