| 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 /// \file | 10 /// \file |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 } | 636 } |
| 637 } | 637 } |
| 638 } | 638 } |
| 639 } | 639 } |
| 640 } | 640 } |
| 641 } | 641 } |
| 642 | 642 |
| 643 void Cfg::loopInvariantCodeMotion() { | 643 void Cfg::loopInvariantCodeMotion() { |
| 644 TimerMarker T(TimerStack::TT_loopInvariantCodeMotion, this); | 644 TimerMarker T(TimerStack::TT_loopInvariantCodeMotion, this); |
| 645 // Does not introduce new nodes as of now. | 645 // Does not introduce new nodes as of now. |
| 646 for (auto &Pair : LoopInfo) { | 646 for (auto &Loop : LoopInfo) { |
| 647 CfgNode *Header = Nodes[Pair.first]; | 647 CfgNode *Header = Loop.Header; |
| 648 assert(Header); | 648 assert(Header); |
| 649 if (Header->getLoopNestDepth() < 1) | 649 if (Header->getLoopNestDepth() < 1) |
| 650 continue; | 650 return; |
| 651 CfgNode *PreHeader = nullptr; | 651 CfgNode *PreHeader = Loop.PreHeader; |
| 652 for (auto *Pred : Header->getInEdges()) { | |
| 653 if (Pred->getLoopNestDepth() == Header->getLoopNestDepth() - 1) { | |
| 654 if (PreHeader == nullptr) { | |
| 655 PreHeader = Pred; | |
| 656 } else { | |
| 657 PreHeader = nullptr; | |
| 658 break; | |
| 659 // Do not consider cases with two incoming edges. | |
| 660 // Will require insertion of nodes. | |
| 661 } | |
| 662 } | |
| 663 } | |
| 664 if (PreHeader == nullptr || PreHeader->getInsts().size() == 0) { | 652 if (PreHeader == nullptr || PreHeader->getInsts().size() == 0) { |
| 665 continue; // to next loop | 653 return; // try next loop |
| 666 } | 654 } |
| 667 | 655 |
| 668 auto &Insts = PreHeader->getInsts(); | 656 auto &Insts = PreHeader->getInsts(); |
| 669 auto &LastInst = Insts.back(); | 657 auto &LastInst = Insts.back(); |
| 670 Insts.pop_back(); | 658 Insts.pop_back(); |
| 671 | 659 |
| 672 for (auto *Inst : findLoopInvariantInstructions(Pair.first)) { | 660 for (auto *Inst : findLoopInvariantInstructions(Loop.Body)) { |
| 673 PreHeader->appendInst(Inst); | 661 PreHeader->appendInst(Inst); |
| 674 } | 662 } |
| 675 PreHeader->appendInst(&LastInst); | 663 PreHeader->appendInst(&LastInst); |
| 676 } | 664 } |
| 677 } | 665 } |
| 678 | 666 |
| 679 Ice::CfgVector<Inst *> | 667 CfgVector<Inst *> |
| 680 Cfg::findLoopInvariantInstructions(Ice::SizeT LoopHeaderIndex) { | 668 Cfg::findLoopInvariantInstructions(const CfgUnorderedSet<SizeT> &Body) { |
| 681 CfgUnorderedSet<Inst *> InvariantInsts; | 669 CfgUnorderedSet<Inst *> InvariantInsts; |
| 682 CfgUnorderedSet<Variable *> InvariantVars; | 670 CfgUnorderedSet<Variable *> InvariantVars; |
| 683 for (auto *Var : getArgs()) { | 671 for (auto *Var : getArgs()) { |
| 684 InvariantVars.insert(Var); | 672 InvariantVars.insert(Var); |
| 685 } | 673 } |
| 686 bool Changed = false; | 674 bool Changed = false; |
| 687 do { | 675 do { |
| 688 Changed = false; | 676 Changed = false; |
| 689 for (auto NodeIndex : LoopInfo[LoopHeaderIndex]) { | 677 for (auto NodeIndex : Body) { |
| 690 auto *Node = Nodes[NodeIndex]; | 678 auto *Node = Nodes[NodeIndex]; |
| 691 CfgVector<std::reference_wrapper<Inst>> Insts(Node->getInsts().begin(), | 679 CfgVector<std::reference_wrapper<Inst>> Insts(Node->getInsts().begin(), |
| 692 Node->getInsts().end()); | 680 Node->getInsts().end()); |
| 693 | 681 |
| 694 for (auto &InstRef : Insts) { | 682 for (auto &InstRef : Insts) { |
| 695 auto &Inst = InstRef.get(); | 683 auto &Inst = InstRef.get(); |
| 696 if (Inst.isDeleted() || | 684 if (Inst.isDeleted() || |
| 697 InvariantInsts.find(&Inst) != InvariantInsts.end()) | 685 InvariantInsts.find(&Inst) != InvariantInsts.end()) |
| 698 continue; | 686 continue; |
| 699 switch (Inst.getKind()) { | 687 switch (Inst.getKind()) { |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 void Cfg::genFrame() { | 1418 void Cfg::genFrame() { |
| 1431 TimerMarker T(TimerStack::TT_genFrame, this); | 1419 TimerMarker T(TimerStack::TT_genFrame, this); |
| 1432 getTarget()->addProlog(Entry); | 1420 getTarget()->addProlog(Entry); |
| 1433 for (CfgNode *Node : Nodes) | 1421 for (CfgNode *Node : Nodes) |
| 1434 if (Node->getHasReturn()) | 1422 if (Node->getHasReturn()) |
| 1435 getTarget()->addEpilog(Node); | 1423 getTarget()->addEpilog(Node); |
| 1436 } | 1424 } |
| 1437 | 1425 |
| 1438 void Cfg::generateLoopInfo() { | 1426 void Cfg::generateLoopInfo() { |
| 1439 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this); | 1427 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this); |
| 1440 LoopInfo = LoopAnalyzer(this).getLoopInfo(); | 1428 LoopInfo = ComputeLoopInfo(this); |
| 1441 } | 1429 } |
| 1442 | 1430 |
| 1443 // This is a lightweight version of live-range-end calculation. Marks the last | 1431 // This is a lightweight version of live-range-end calculation. Marks the last |
| 1444 // use of only those variables whose definition and uses are completely with a | 1432 // use of only those variables whose definition and uses are completely with a |
| 1445 // single block. It is a quick single pass and doesn't need to iterate until | 1433 // single block. It is a quick single pass and doesn't need to iterate until |
| 1446 // convergence. | 1434 // convergence. |
| 1447 void Cfg::livenessLightweight() { | 1435 void Cfg::livenessLightweight() { |
| 1448 TimerMarker T(TimerStack::TT_livenessLightweight, this); | 1436 TimerMarker T(TimerStack::TT_livenessLightweight, this); |
| 1449 getVMetadata()->init(VMK_Uses); | 1437 getVMetadata()->init(VMK_Uses); |
| 1450 for (CfgNode *Node : Nodes) | 1438 for (CfgNode *Node : Nodes) |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 } | 1767 } |
| 1780 } | 1768 } |
| 1781 // Print each basic block | 1769 // Print each basic block |
| 1782 for (CfgNode *Node : Nodes) | 1770 for (CfgNode *Node : Nodes) |
| 1783 Node->dump(this); | 1771 Node->dump(this); |
| 1784 if (isVerbose(IceV_Instructions)) | 1772 if (isVerbose(IceV_Instructions)) |
| 1785 Str << "}\n"; | 1773 Str << "}\n"; |
| 1786 } | 1774 } |
| 1787 | 1775 |
| 1788 } // end of namespace Ice | 1776 } // end of namespace Ice |
| OLD | NEW |