Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: src/IceCfg.cpp

Issue 2138443002: Subzero: Loop Invariant Code Motion (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceCfg.h ('k') | src/IceClFlags.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceCfg.h ('k') | src/IceClFlags.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698