OLD | NEW |
1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// | 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) 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 // This file implements the CfgNode class, including the complexities | 10 // This file implements the CfgNode class, including the complexities |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 } | 821 } |
822 Str << "\n"; | 822 Str << "\n"; |
823 } | 823 } |
824 | 824 |
825 void emitLiveRangesEnded(Ostream &Str, const Cfg *Func, const Inst *Instr, | 825 void emitLiveRangesEnded(Ostream &Str, const Cfg *Func, const Inst *Instr, |
826 std::vector<SizeT> &LiveRegCount) { | 826 std::vector<SizeT> &LiveRegCount) { |
827 if (!ALLOW_DUMP) | 827 if (!ALLOW_DUMP) |
828 return; | 828 return; |
829 bool First = true; | 829 bool First = true; |
830 Variable *Dest = Instr->getDest(); | 830 Variable *Dest = Instr->getDest(); |
831 if (Dest && Dest->hasReg()) | 831 // Normally we increment the live count for the dest register. But |
| 832 // we shouldn't if the instruction's IsDestNonKillable flag is set, |
| 833 // because this means that the target lowering created this |
| 834 // instruction as a non-SSA assignment; i.e., a different, previous |
| 835 // instruction started the dest variable's live range. |
| 836 if (!Instr->isDestNonKillable() && Dest && Dest->hasReg()) |
832 ++LiveRegCount[Dest->getRegNum()]; | 837 ++LiveRegCount[Dest->getRegNum()]; |
833 for (SizeT I = 0; I < Instr->getSrcSize(); ++I) { | 838 for (SizeT I = 0; I < Instr->getSrcSize(); ++I) { |
834 Operand *Src = Instr->getSrc(I); | 839 Operand *Src = Instr->getSrc(I); |
835 SizeT NumVars = Src->getNumVars(); | 840 SizeT NumVars = Src->getNumVars(); |
836 for (SizeT J = 0; J < NumVars; ++J) { | 841 for (SizeT J = 0; J < NumVars; ++J) { |
837 const Variable *Var = Src->getVar(J); | 842 const Variable *Var = Src->getVar(J); |
838 bool ShouldEmit = Instr->isLastUse(Var); | 843 bool ShouldReport = Instr->isLastUse(Var); |
839 if (Var->hasReg()) { | 844 if (ShouldReport && Var->hasReg()) { |
840 // Don't report end of live range until the live count reaches 0. | 845 // Don't report end of live range until the live count reaches 0. |
841 SizeT NewCount = --LiveRegCount[Var->getRegNum()]; | 846 SizeT NewCount = --LiveRegCount[Var->getRegNum()]; |
842 if (NewCount) | 847 if (NewCount) |
843 ShouldEmit = false; | 848 ShouldReport = false; |
844 } | 849 } |
845 if (ShouldEmit) { | 850 if (ShouldReport) { |
846 if (First) | 851 if (First) |
847 Str << " \t# END="; | 852 Str << " \t# END="; |
848 else | 853 else |
849 Str << ","; | 854 Str << ","; |
850 Var->emit(Func); | 855 Var->emit(Func); |
851 First = false; | 856 First = false; |
852 } | 857 } |
853 } | 858 } |
854 } | 859 } |
855 } | 860 } |
(...skipping 22 matching lines...) Expand all Loading... |
878 | 883 |
879 void CfgNode::emit(Cfg *Func) const { | 884 void CfgNode::emit(Cfg *Func) const { |
880 if (!ALLOW_DUMP) | 885 if (!ALLOW_DUMP) |
881 return; | 886 return; |
882 Func->setCurrentNode(this); | 887 Func->setCurrentNode(this); |
883 Ostream &Str = Func->getContext()->getStrEmit(); | 888 Ostream &Str = Func->getContext()->getStrEmit(); |
884 Liveness *Liveness = Func->getLiveness(); | 889 Liveness *Liveness = Func->getLiveness(); |
885 bool DecorateAsm = | 890 bool DecorateAsm = |
886 Liveness && Func->getContext()->getFlags().getDecorateAsm(); | 891 Liveness && Func->getContext()->getFlags().getDecorateAsm(); |
887 Str << getAsmName() << ":\n"; | 892 Str << getAsmName() << ":\n"; |
| 893 // LiveRegCount keeps track of the number of currently live |
| 894 // variables that each register is assigned to. Normally that would |
| 895 // be only 0 or 1, but the register allocator's AllowOverlap |
| 896 // inference allows it to be greater than 1 for short periods. |
888 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters()); | 897 std::vector<SizeT> LiveRegCount(Func->getTarget()->getNumRegisters()); |
889 if (DecorateAsm) { | 898 if (DecorateAsm) { |
890 const bool IsLiveIn = true; | 899 const bool IsLiveIn = true; |
891 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount); | 900 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount); |
892 } | 901 } |
893 | 902 |
894 for (const Inst &I : Phis) { | 903 for (const Inst &I : Phis) { |
895 if (I.isDeleted()) | 904 if (I.isDeleted()) |
896 continue; | 905 continue; |
897 // Emitting a Phi instruction should cause an error. | 906 // Emitting a Phi instruction should cause an error. |
898 I.emit(Func); | 907 I.emit(Func); |
899 } | 908 } |
900 for (const Inst &I : Insts) { | 909 for (const Inst &I : Insts) { |
901 if (I.isDeleted()) | 910 if (I.isDeleted()) |
902 continue; | 911 continue; |
903 if (I.isRedundantAssign()) | 912 if (I.isRedundantAssign()) { |
| 913 // Usually, redundant assignments end the live range of the src |
| 914 // variable and begin the live range of the dest variable, with |
| 915 // no net effect on the liveness of their register. However, if |
| 916 // the register allocator infers the AllowOverlap condition, |
| 917 // then this may be a redundant assignment that does not end the |
| 918 // src variable's live range, in which case the active variable |
| 919 // count for that register needs to be bumped. That normally |
| 920 // would have happened as part of emitLiveRangesEnded(), but |
| 921 // that isn't called for redundant assignments. |
| 922 Variable *Dest = I.getDest(); |
| 923 if (DecorateAsm && Dest->hasReg() && !I.isLastUse(I.getSrc(0))) |
| 924 ++LiveRegCount[Dest->getRegNum()]; |
904 continue; | 925 continue; |
| 926 } |
905 I.emit(Func); | 927 I.emit(Func); |
906 if (DecorateAsm) | 928 if (DecorateAsm) |
907 emitLiveRangesEnded(Str, Func, &I, LiveRegCount); | 929 emitLiveRangesEnded(Str, Func, &I, LiveRegCount); |
908 Str << "\n"; | 930 Str << "\n"; |
909 updateStats(Func, &I); | 931 updateStats(Func, &I); |
910 } | 932 } |
911 if (DecorateAsm) { | 933 if (DecorateAsm) { |
912 const bool IsLiveIn = false; | 934 const bool IsLiveIn = false; |
913 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount); | 935 emitRegisterUsage(Str, Func, this, IsLiveIn, LiveRegCount); |
914 } | 936 } |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 if (!First) | 1237 if (!First) |
1216 Str << ", "; | 1238 Str << ", "; |
1217 First = false; | 1239 First = false; |
1218 Str << "%" << I->getName(); | 1240 Str << "%" << I->getName(); |
1219 } | 1241 } |
1220 Str << "\n"; | 1242 Str << "\n"; |
1221 } | 1243 } |
1222 } | 1244 } |
1223 | 1245 |
1224 } // end of namespace Ice | 1246 } // end of namespace Ice |
OLD | NEW |