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 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 if (auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 633 if (auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
634 Dependency[Var].push_back(&Instr); | 634 Dependency[Var].push_back(&Instr); |
635 } | 635 } |
636 } | 636 } |
637 } | 637 } |
638 } | 638 } |
639 } | 639 } |
640 } | 640 } |
641 } | 641 } |
642 | 642 |
| 643 void Cfg::loopInvariantCodeMotion() { |
| 644 TimerMarker T(TimerStack::TT_loopInvariantCodeMotion, this); |
| 645 // Does not introduce new nodes as of now. |
| 646 for (auto &Pair : LoopInfo) { |
| 647 CfgNode *Header = Nodes[Pair.first]; |
| 648 assert(Header); |
| 649 if (Header->getLoopNestDepth() < 1) |
| 650 continue; |
| 651 CfgNode *PreHeader = nullptr; |
| 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) { |
| 665 continue; // to next loop |
| 666 } |
| 667 |
| 668 auto &Insts = PreHeader->getInsts(); |
| 669 auto &LastInst = Insts.back(); |
| 670 Insts.pop_back(); |
| 671 |
| 672 for (auto *Inst : findLoopInvariantInstructions(Pair.first)) { |
| 673 PreHeader->appendInst(Inst); |
| 674 } |
| 675 PreHeader->appendInst(&LastInst); |
| 676 } |
| 677 } |
| 678 |
| 679 Ice::CfgVector<Inst *> |
| 680 Cfg::findLoopInvariantInstructions(Ice::SizeT LoopHeaderIndex) { |
| 681 CfgUnorderedSet<Inst *> InvariantInsts; |
| 682 CfgUnorderedSet<Variable *> InvariantVars; |
| 683 for (auto *Var : getArgs()) { |
| 684 InvariantVars.insert(Var); |
| 685 } |
| 686 bool Changed = false; |
| 687 do { |
| 688 Changed = false; |
| 689 for (auto NodeIndex : LoopInfo[LoopHeaderIndex]) { |
| 690 auto *Node = Nodes[NodeIndex]; |
| 691 CfgVector<std::reference_wrapper<Inst>> Insts(Node->getInsts().begin(), |
| 692 Node->getInsts().end()); |
| 693 |
| 694 for (auto &InstRef : Insts) { |
| 695 auto &Inst = InstRef.get(); |
| 696 if (Inst.isDeleted() || |
| 697 InvariantInsts.find(&Inst) != InvariantInsts.end()) |
| 698 continue; |
| 699 switch (Inst.getKind()) { |
| 700 case Inst::InstKind::Alloca: |
| 701 case Inst::InstKind::Br: |
| 702 case Inst::InstKind::Ret: |
| 703 case Inst::InstKind::Phi: |
| 704 case Inst::InstKind::Call: |
| 705 case Inst::InstKind::IntrinsicCall: |
| 706 case Inst::InstKind::Load: |
| 707 case Inst::InstKind::Store: |
| 708 case Inst::InstKind::Switch: |
| 709 continue; |
| 710 default: |
| 711 break; |
| 712 } |
| 713 |
| 714 bool IsInvariant = true; |
| 715 for (SizeT i = 0; i < Inst.getSrcSize(); ++i) { |
| 716 if (auto *Var = llvm::dyn_cast<Variable>(Inst.getSrc(i))) { |
| 717 if (InvariantVars.find(Var) == InvariantVars.end()) { |
| 718 IsInvariant = false; |
| 719 } |
| 720 } |
| 721 } |
| 722 if (IsInvariant) { |
| 723 Changed = true; |
| 724 InvariantInsts.insert(&Inst); |
| 725 Node->getInsts().remove(Inst); |
| 726 if (Inst.getDest() != nullptr) { |
| 727 InvariantVars.insert(Inst.getDest()); |
| 728 } |
| 729 } |
| 730 } |
| 731 } |
| 732 } while (Changed); |
| 733 |
| 734 CfgVector<Inst *> InstVector(InvariantInsts.begin(), InvariantInsts.end()); |
| 735 std::sort(InstVector.begin(), InstVector.end(), |
| 736 [](Inst *A, Inst *B) { return A->getNumber() < B->getNumber(); }); |
| 737 return InstVector; |
| 738 } |
| 739 |
643 void Cfg::shortCircuitJumps() { | 740 void Cfg::shortCircuitJumps() { |
644 // Split Nodes whenever an early jump is possible. | 741 // Split Nodes whenever an early jump is possible. |
645 // __N : | 742 // __N : |
646 // a = <something> | 743 // a = <something> |
647 // Instruction 1 without side effect | 744 // Instruction 1 without side effect |
648 // ... b = <something> ... | 745 // ... b = <something> ... |
649 // Instruction N without side effect | 746 // Instruction N without side effect |
650 // t1 = or a b | 747 // t1 = or a b |
651 // br t1 __X __Y | 748 // br t1 __X __Y |
652 // | 749 // |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 | 1428 |
1332 // Compute the stack frame layout. | 1429 // Compute the stack frame layout. |
1333 void Cfg::genFrame() { | 1430 void Cfg::genFrame() { |
1334 TimerMarker T(TimerStack::TT_genFrame, this); | 1431 TimerMarker T(TimerStack::TT_genFrame, this); |
1335 getTarget()->addProlog(Entry); | 1432 getTarget()->addProlog(Entry); |
1336 for (CfgNode *Node : Nodes) | 1433 for (CfgNode *Node : Nodes) |
1337 if (Node->getHasReturn()) | 1434 if (Node->getHasReturn()) |
1338 getTarget()->addEpilog(Node); | 1435 getTarget()->addEpilog(Node); |
1339 } | 1436 } |
1340 | 1437 |
1341 void Cfg::computeLoopNestDepth() { | 1438 void Cfg::generateLoopInfo() { |
1342 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this); | 1439 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this); |
1343 LoopAnalyzer LA(this); | 1440 LoopInfo = LoopAnalyzer(this).getLoopInfo(); |
1344 LA.computeLoopNestDepth(); | |
1345 } | 1441 } |
1346 | 1442 |
1347 // This is a lightweight version of live-range-end calculation. Marks the last | 1443 // This is a lightweight version of live-range-end calculation. Marks the last |
1348 // use of only those variables whose definition and uses are completely with a | 1444 // use of only those variables whose definition and uses are completely with a |
1349 // single block. It is a quick single pass and doesn't need to iterate until | 1445 // single block. It is a quick single pass and doesn't need to iterate until |
1350 // convergence. | 1446 // convergence. |
1351 void Cfg::livenessLightweight() { | 1447 void Cfg::livenessLightweight() { |
1352 TimerMarker T(TimerStack::TT_livenessLightweight, this); | 1448 TimerMarker T(TimerStack::TT_livenessLightweight, this); |
1353 getVMetadata()->init(VMK_Uses); | 1449 getVMetadata()->init(VMK_Uses); |
1354 for (CfgNode *Node : Nodes) | 1450 for (CfgNode *Node : Nodes) |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 } | 1779 } |
1684 } | 1780 } |
1685 // Print each basic block | 1781 // Print each basic block |
1686 for (CfgNode *Node : Nodes) | 1782 for (CfgNode *Node : Nodes) |
1687 Node->dump(this); | 1783 Node->dump(this); |
1688 if (isVerbose(IceV_Instructions)) | 1784 if (isVerbose(IceV_Instructions)) |
1689 Str << "}\n"; | 1785 Str << "}\n"; |
1690 } | 1786 } |
1691 | 1787 |
1692 } // end of namespace Ice | 1788 } // end of namespace Ice |
OLD | NEW |