Chromium Code Reviews| 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() { | |
|
John
2016/07/08 21:04:46
please create a helper function named "findLoopInv
| |
| 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 if (Header->getLoopNestDepth() < 1) | |
| 649 continue; | |
| 650 assert(Header); | |
| 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 // Detect invariant instructions | |
| 669 CfgUnorderedSet<Inst *> InvariantInsts; | |
|
John
2016/07/08 21:04:46
Given that this is a set, this will probably not h
manasijm
2016/07/08 21:09:31
This is why I was advocating a stack allocator :)
| |
| 670 CfgUnorderedSet<Variable *> InvariantVars; | |
|
John
2016/07/08 21:04:46
please create a helper function named "findLoopInv
manasijm
2016/07/08 21:09:31
Will do.
| |
| 671 for (auto *Var : getArgs()) { | |
| 672 InvariantVars.insert(Var); | |
| 673 } | |
| 674 bool Changed = false; | |
| 675 do { | |
|
John
2016/07/08 21:04:46
I tend to prefer using worklist-based iteration in
| |
| 676 Changed = false; | |
| 677 for (auto NodeIndex : Pair.second) { | |
| 678 auto *Node = Nodes[NodeIndex]; | |
| 679 CfgVector<std::reference_wrapper<Inst>> Insts(Node->getInsts().begin(), | |
| 680 Node->getInsts().end()); | |
| 681 | |
| 682 for (auto &InstRef : Insts) { | |
| 683 auto &Inst = InstRef.get(); | |
| 684 if (Inst.isDeleted() || | |
| 685 InvariantInsts.find(&Inst) != InvariantInsts.end()) | |
| 686 continue; | |
| 687 switch (Inst.getKind()) { | |
| 688 case Inst::InstKind::Alloca: | |
| 689 case Inst::InstKind::Br: | |
| 690 case Inst::InstKind::Ret: | |
| 691 case Inst::InstKind::Phi: | |
| 692 case Inst::InstKind::Call: | |
| 693 case Inst::InstKind::IntrinsicCall: | |
| 694 case Inst::InstKind::Load: | |
| 695 case Inst::InstKind::Store: | |
| 696 case Inst::InstKind::Switch: | |
| 697 continue; | |
| 698 default: | |
| 699 break; | |
| 700 } | |
| 701 | |
| 702 bool IsInvariant = true; | |
| 703 for (SizeT i = 0; i < Inst.getSrcSize(); ++i) { | |
| 704 if (auto *Var = llvm::dyn_cast<Variable>(Inst.getSrc(i))) { | |
| 705 if (InvariantVars.find(Var) == InvariantVars.end()) { | |
| 706 IsInvariant = false; | |
| 707 } | |
| 708 } | |
| 709 } | |
| 710 if (IsInvariant) { | |
| 711 Changed = true; | |
| 712 InvariantInsts.insert(&Inst); | |
| 713 Node->getInsts().remove(Inst); | |
| 714 if (Inst.getDest() != nullptr) { | |
| 715 InvariantVars.insert(Inst.getDest()); | |
| 716 } | |
| 717 } | |
| 718 } | |
| 719 } | |
| 720 } while (Changed); | |
| 721 | |
| 722 auto &Insts = PreHeader->getInsts(); | |
| 723 auto &LastInst = Insts.back(); | |
|
John
2016/07/08 21:04:46
Why the special handling of Insts.back?
manasijm
2016/07/08 21:09:31
It is a control flow instruction, can not insert o
| |
| 724 Insts.pop_back(); | |
| 725 CfgVector<Inst *> InstVector(InvariantInsts.begin(), InvariantInsts.end()); | |
| 726 std::sort(InstVector.begin(), InstVector.end(), | |
| 727 [](Inst *A, Inst *B) { return A->getNumber() < B->getNumber(); }); | |
| 728 for (auto *Inst : InstVector) { | |
| 729 PreHeader->appendInst(Inst); | |
| 730 } | |
| 731 PreHeader->appendInst(&LastInst); | |
| 732 } | |
| 733 } | |
| 734 | |
| 643 void Cfg::shortCircuitJumps() { | 735 void Cfg::shortCircuitJumps() { |
| 644 // Split Nodes whenever an early jump is possible. | 736 // Split Nodes whenever an early jump is possible. |
| 645 // __N : | 737 // __N : |
| 646 // a = <something> | 738 // a = <something> |
| 647 // Instruction 1 without side effect | 739 // Instruction 1 without side effect |
| 648 // ... b = <something> ... | 740 // ... b = <something> ... |
| 649 // Instruction N without side effect | 741 // Instruction N without side effect |
| 650 // t1 = or a b | 742 // t1 = or a b |
| 651 // br t1 __X __Y | 743 // br t1 __X __Y |
| 652 // | 744 // |
| (...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 | 1423 |
| 1332 // Compute the stack frame layout. | 1424 // Compute the stack frame layout. |
| 1333 void Cfg::genFrame() { | 1425 void Cfg::genFrame() { |
| 1334 TimerMarker T(TimerStack::TT_genFrame, this); | 1426 TimerMarker T(TimerStack::TT_genFrame, this); |
| 1335 getTarget()->addProlog(Entry); | 1427 getTarget()->addProlog(Entry); |
| 1336 for (CfgNode *Node : Nodes) | 1428 for (CfgNode *Node : Nodes) |
| 1337 if (Node->getHasReturn()) | 1429 if (Node->getHasReturn()) |
| 1338 getTarget()->addEpilog(Node); | 1430 getTarget()->addEpilog(Node); |
| 1339 } | 1431 } |
| 1340 | 1432 |
| 1341 void Cfg::computeLoopNestDepth() { | 1433 void Cfg::generateLoopInfo() { |
| 1342 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this); | 1434 TimerMarker T(TimerStack::TT_computeLoopNestDepth, this); |
| 1343 LoopAnalyzer LA(this); | 1435 LoopInfo = LoopAnalyzer(this).getLoopInfo(); |
| 1344 LA.computeLoopNestDepth(); | |
| 1345 } | 1436 } |
| 1346 | 1437 |
| 1347 // This is a lightweight version of live-range-end calculation. Marks the last | 1438 // 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 | 1439 // 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 | 1440 // single block. It is a quick single pass and doesn't need to iterate until |
| 1350 // convergence. | 1441 // convergence. |
| 1351 void Cfg::livenessLightweight() { | 1442 void Cfg::livenessLightweight() { |
| 1352 TimerMarker T(TimerStack::TT_livenessLightweight, this); | 1443 TimerMarker T(TimerStack::TT_livenessLightweight, this); |
| 1353 getVMetadata()->init(VMK_Uses); | 1444 getVMetadata()->init(VMK_Uses); |
| 1354 for (CfgNode *Node : Nodes) | 1445 for (CfgNode *Node : Nodes) |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1683 } | 1774 } |
| 1684 } | 1775 } |
| 1685 // Print each basic block | 1776 // Print each basic block |
| 1686 for (CfgNode *Node : Nodes) | 1777 for (CfgNode *Node : Nodes) |
| 1687 Node->dump(this); | 1778 Node->dump(this); |
| 1688 if (isVerbose(IceV_Instructions)) | 1779 if (isVerbose(IceV_Instructions)) |
| 1689 Str << "}\n"; | 1780 Str << "}\n"; |
| 1690 } | 1781 } |
| 1691 | 1782 |
| 1692 } // end of namespace Ice | 1783 } // end of namespace Ice |
| OLD | NEW |