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 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 } | 791 } |
792 } | 792 } |
793 | 793 |
794 SizeT NodeIndex = 0; | 794 SizeT NodeIndex = 0; |
795 for (auto *Node : NewList) { | 795 for (auto *Node : NewList) { |
796 Node->resetIndex(NodeIndex++); | 796 Node->resetIndex(NodeIndex++); |
797 } | 797 } |
798 Nodes = NewList; | 798 Nodes = NewList; |
799 } | 799 } |
800 | 800 |
| 801 void Cfg::floatConstantCSE() { |
| 802 // Load multiple uses of a floating point constant (between two call |
| 803 // instructions or block start/end) into a variable before its first use. |
| 804 // t1 = b + 1.0 |
| 805 // t2 = c + 1.0 |
| 806 // Gets transformed to: |
| 807 // t0 = 1.0 |
| 808 // t0_1 = t0 |
| 809 // t1 = b + t0_1 |
| 810 // t2 = c + t0_1 |
| 811 // Call instructions reset the procedure, but use the same variable, just in |
| 812 // case it got a register. We are assuming floating point registers are not |
| 813 // callee saved in general. Example, continuing from before: |
| 814 // result = call <some function> |
| 815 // t3 = d + 1.0 |
| 816 // Gets transformed to: |
| 817 // result = call <some function> |
| 818 // t0_2 = t0 |
| 819 // t3 = d + t0_2 |
| 820 // TODO(manasijm, stichnot): Figure out how to 'link' t0 to the stack slot of |
| 821 // 1.0. When t0 does not get a register, introducing an extra assignment |
| 822 // statement does not make sense. The relevant portion is marked below. |
| 823 |
| 824 TimerMarker _(TimerStack::TT_floatConstantCse, this); |
| 825 for (CfgNode *Node : getNodes()) { |
| 826 |
| 827 CfgUnorderedMap<Constant *, Variable *> ConstCache; |
| 828 auto Current = Node->getInsts().begin(); |
| 829 auto End = Node->getInsts().end(); |
| 830 while (Current != End) { |
| 831 CfgUnorderedMap<Constant *, CfgVector<Inst *>> FloatUses; |
| 832 if (llvm::isa<InstCall>(iteratorToInst(Current))) { |
| 833 ++Current; |
| 834 assert(Current != End); |
| 835 // Block should not end with a call |
| 836 } |
| 837 while (Current != End && !llvm::isa<InstCall>(iteratorToInst(Current))) { |
| 838 for (SizeT i = 0; i < Current->getSrcSize(); ++i) { |
| 839 if (auto *Const = llvm::dyn_cast<Constant>(Current->getSrc(i))) { |
| 840 if (Const->getType() == IceType_f32 || |
| 841 Const->getType() == IceType_f64) { |
| 842 FloatUses[Const].push_back(Current); |
| 843 } |
| 844 } |
| 845 } |
| 846 Current++; |
| 847 } |
| 848 for (auto &Pair : FloatUses) { |
| 849 static constexpr SizeT MinUseThreshold = 3; |
| 850 if (Pair.second.size() < MinUseThreshold) |
| 851 continue; |
| 852 // Only consider constants with at least `MinUseThreshold` uses |
| 853 auto &Insts = Node->getInsts(); |
| 854 |
| 855 if (ConstCache.find(Pair.first) == ConstCache.end()) { |
| 856 // Saw a constant (which is used at least twice) for the first time |
| 857 auto *NewVar = makeVariable(Pair.first->getType()); |
| 858 // NewVar->setLinkedTo(Pair.first); |
| 859 // TODO(manasijm): Plumbing for linking to an Operand. |
| 860 auto *Assign = InstAssign::create(Node->getCfg(), NewVar, Pair.first); |
| 861 Insts.insert(Pair.second[0], Assign); |
| 862 ConstCache[Pair.first] = NewVar; |
| 863 } |
| 864 |
| 865 auto *NewVar = makeVariable(Pair.first->getType()); |
| 866 NewVar->setLinkedTo(ConstCache[Pair.first]); |
| 867 auto *Assign = |
| 868 InstAssign::create(Node->getCfg(), NewVar, ConstCache[Pair.first]); |
| 869 |
| 870 Insts.insert(Pair.second[0], Assign); |
| 871 for (auto *InstUse : Pair.second) { |
| 872 for (SizeT i = 0; i < InstUse->getSrcSize(); ++i) { |
| 873 if (auto *Const = llvm::dyn_cast<Constant>(InstUse->getSrc(i))) { |
| 874 if (Const == Pair.first) { |
| 875 InstUse->replaceSource(i, NewVar); |
| 876 } |
| 877 } |
| 878 } |
| 879 } |
| 880 } |
| 881 } |
| 882 } |
| 883 } |
| 884 |
801 void Cfg::doArgLowering() { | 885 void Cfg::doArgLowering() { |
802 TimerMarker T(TimerStack::TT_doArgLowering, this); | 886 TimerMarker T(TimerStack::TT_doArgLowering, this); |
803 getTarget()->lowerArguments(); | 887 getTarget()->lowerArguments(); |
804 } | 888 } |
805 | 889 |
806 void Cfg::sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas, | 890 void Cfg::sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas, |
807 uint32_t CombinedAlignment, InstList &Insts, | 891 uint32_t CombinedAlignment, InstList &Insts, |
808 AllocaBaseVariableType BaseVariableType) { | 892 AllocaBaseVariableType BaseVariableType) { |
809 if (Allocas.empty()) | 893 if (Allocas.empty()) |
810 return; | 894 return; |
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 } | 1861 } |
1778 } | 1862 } |
1779 // Print each basic block | 1863 // Print each basic block |
1780 for (CfgNode *Node : Nodes) | 1864 for (CfgNode *Node : Nodes) |
1781 Node->dump(this); | 1865 Node->dump(this); |
1782 if (isVerbose(IceV_Instructions)) | 1866 if (isVerbose(IceV_Instructions)) |
1783 Str << "}\n"; | 1867 Str << "}\n"; |
1784 } | 1868 } |
1785 | 1869 |
1786 } // end of namespace Ice | 1870 } // end of namespace Ice |
OLD | NEW |