| 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 |