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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 InstCall::create(this, NumArgs, Void, ProfileSummarySym, HasTailCall); | 136 InstCall::create(this, NumArgs, Void, ProfileSummarySym, HasTailCall); |
137 getEntryNode()->getInsts().push_front(Call); | 137 getEntryNode()->getInsts().push_front(Call); |
138 } | 138 } |
139 | 139 |
140 void Cfg::translate() { | 140 void Cfg::translate() { |
141 if (hasError()) | 141 if (hasError()) |
142 return; | 142 return; |
143 // FunctionTimer conditionally pushes/pops a TimerMarker if | 143 // FunctionTimer conditionally pushes/pops a TimerMarker if |
144 // TimeEachFunction is enabled. | 144 // TimeEachFunction is enabled. |
145 std::unique_ptr<TimerMarker> FunctionTimer; | 145 std::unique_ptr<TimerMarker> FunctionTimer; |
146 if (ALLOW_DUMP) { | 146 if (buildAllowsDump()) { |
147 const IceString &TimingFocusOn = | 147 const IceString &TimingFocusOn = |
148 getContext()->getFlags().getTimingFocusOn(); | 148 getContext()->getFlags().getTimingFocusOn(); |
149 const IceString &Name = getFunctionName(); | 149 const IceString &Name = getFunctionName(); |
150 if (TimingFocusOn == "*" || TimingFocusOn == Name) { | 150 if (TimingFocusOn == "*" || TimingFocusOn == Name) { |
151 setFocusedTiming(); | 151 setFocusedTiming(); |
152 getContext()->resetTimer(GlobalContext::TSK_Default); | 152 getContext()->resetTimer(GlobalContext::TSK_Default); |
153 getContext()->setTimerName(GlobalContext::TSK_Default, Name); | 153 getContext()->setTimerName(GlobalContext::TSK_Default, Name); |
154 } | 154 } |
155 if (getContext()->getFlags().getTimeEachFunction()) | 155 if (getContext()->getFlags().getTimeEachFunction()) |
156 FunctionTimer.reset(new TimerMarker( | 156 FunctionTimer.reset(new TimerMarker( |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 525 } |
526 } | 526 } |
527 | 527 |
528 // ======================== Dump routines ======================== // | 528 // ======================== Dump routines ======================== // |
529 | 529 |
530 // emitTextHeader() is not target-specific (apart from what is | 530 // emitTextHeader() is not target-specific (apart from what is |
531 // abstracted by the Assembler), so it is defined here rather than in | 531 // abstracted by the Assembler), so it is defined here rather than in |
532 // the target lowering class. | 532 // the target lowering class. |
533 void Cfg::emitTextHeader(const IceString &MangledName, GlobalContext *Ctx, | 533 void Cfg::emitTextHeader(const IceString &MangledName, GlobalContext *Ctx, |
534 const Assembler *Asm) { | 534 const Assembler *Asm) { |
535 if (!ALLOW_DUMP) | 535 if (!buildAllowsDump()) |
536 return; | 536 return; |
537 Ostream &Str = Ctx->getStrEmit(); | 537 Ostream &Str = Ctx->getStrEmit(); |
538 Str << "\t.text\n"; | 538 Str << "\t.text\n"; |
539 if (Ctx->getFlags().getFunctionSections()) | 539 if (Ctx->getFlags().getFunctionSections()) |
540 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n"; | 540 Str << "\t.section\t.text." << MangledName << ",\"ax\",@progbits\n"; |
541 if (!Asm->getInternal() || Ctx->getFlags().getDisableInternal()) { | 541 if (!Asm->getInternal() || Ctx->getFlags().getDisableInternal()) { |
542 Str << "\t.globl\t" << MangledName << "\n"; | 542 Str << "\t.globl\t" << MangledName << "\n"; |
543 Str << "\t.type\t" << MangledName << ",%function\n"; | 543 Str << "\t.type\t" << MangledName << ",%function\n"; |
544 } | 544 } |
545 Str << "\t" << Asm->getNonExecPadDirective() << " " | 545 Str << "\t" << Asm->getNonExecPadDirective() << " " |
546 << Asm->getBundleAlignLog2Bytes() << ",0x"; | 546 << Asm->getBundleAlignLog2Bytes() << ",0x"; |
547 for (uint8_t I : Asm->getNonExecBundlePadding()) | 547 for (uint8_t I : Asm->getNonExecBundlePadding()) |
548 Str.write_hex(I); | 548 Str.write_hex(I); |
549 Str << "\n"; | 549 Str << "\n"; |
550 Str << MangledName << ":\n"; | 550 Str << MangledName << ":\n"; |
551 } | 551 } |
552 | 552 |
553 void Cfg::emit() { | 553 void Cfg::emit() { |
554 if (!ALLOW_DUMP) | 554 if (!buildAllowsDump()) |
555 return; | 555 return; |
556 TimerMarker T(TimerStack::TT_emit, this); | 556 TimerMarker T(TimerStack::TT_emit, this); |
557 if (Ctx->getFlags().getDecorateAsm()) { | 557 if (Ctx->getFlags().getDecorateAsm()) { |
558 renumberInstructions(); | 558 renumberInstructions(); |
559 getVMetadata()->init(VMK_Uses); | 559 getVMetadata()->init(VMK_Uses); |
560 liveness(Liveness_Basic); | 560 liveness(Liveness_Basic); |
561 dump("After recomputing liveness for -decorate-asm"); | 561 dump("After recomputing liveness for -decorate-asm"); |
562 } | 562 } |
563 OstreamLocker L(Ctx); | 563 OstreamLocker L(Ctx); |
564 Ostream &Str = Ctx->getStrEmit(); | 564 Ostream &Str = Ctx->getStrEmit(); |
565 IceString MangledName = getContext()->mangleName(getFunctionName()); | 565 IceString MangledName = getContext()->mangleName(getFunctionName()); |
566 emitTextHeader(MangledName, Ctx, getAssembler<>()); | 566 emitTextHeader(MangledName, Ctx, getAssembler<>()); |
567 for (CfgNode *Node : Nodes) | 567 for (CfgNode *Node : Nodes) |
568 Node->emit(this); | 568 Node->emit(this); |
569 Str << "\n"; | 569 Str << "\n"; |
570 } | 570 } |
571 | 571 |
572 void Cfg::emitIAS() { | 572 void Cfg::emitIAS() { |
573 TimerMarker T(TimerStack::TT_emit, this); | 573 TimerMarker T(TimerStack::TT_emit, this); |
574 // The emitIAS() routines emit into the internal assembler buffer, | 574 // The emitIAS() routines emit into the internal assembler buffer, |
575 // so there's no need to lock the streams. | 575 // so there's no need to lock the streams. |
576 for (CfgNode *Node : Nodes) | 576 for (CfgNode *Node : Nodes) |
577 Node->emitIAS(this); | 577 Node->emitIAS(this); |
578 } | 578 } |
579 | 579 |
580 // Dumps the IR with an optional introductory message. | 580 // Dumps the IR with an optional introductory message. |
581 void Cfg::dump(const IceString &Message) { | 581 void Cfg::dump(const IceString &Message) { |
582 if (!ALLOW_DUMP) | 582 if (!buildAllowsDump()) |
583 return; | 583 return; |
584 if (!isVerbose()) | 584 if (!isVerbose()) |
585 return; | 585 return; |
586 OstreamLocker L(Ctx); | 586 OstreamLocker L(Ctx); |
587 Ostream &Str = Ctx->getStrDump(); | 587 Ostream &Str = Ctx->getStrDump(); |
588 if (!Message.empty()) | 588 if (!Message.empty()) |
589 Str << "================ " << Message << " ================\n"; | 589 Str << "================ " << Message << " ================\n"; |
590 setCurrentNode(getEntryNode()); | 590 setCurrentNode(getEntryNode()); |
591 // Print function name+args | 591 // Print function name+args |
592 if (isVerbose(IceV_Instructions)) { | 592 if (isVerbose(IceV_Instructions)) { |
(...skipping 24 matching lines...) Expand all Loading... |
617 } | 617 } |
618 } | 618 } |
619 // Print each basic block | 619 // Print each basic block |
620 for (CfgNode *Node : Nodes) | 620 for (CfgNode *Node : Nodes) |
621 Node->dump(this); | 621 Node->dump(this); |
622 if (isVerbose(IceV_Instructions)) | 622 if (isVerbose(IceV_Instructions)) |
623 Str << "}\n"; | 623 Str << "}\n"; |
624 } | 624 } |
625 | 625 |
626 } // end of namespace Ice | 626 } // end of namespace Ice |
OLD | NEW |