LLVM学习笔记(64)

4.4.3.3.3. 设置寄存器类对类型的行为

1679行调用computeRegisterProperties()来计算寄存器类的衍生属性。TargetLoweringBase的容器RegisterTypeForVT、RegClassForVT以及NumRegistersForVT用于记录原生支持每个ValueType目标机器寄存器类的信息,即类型对应的寄存器类型、寄存器类别以及寄存器数量。前面每次调用addRegisterClass()时,就会设置上RegClassForVT中对应的项,因此1074~1087行确定需要一个以上寄存器来保存的类型。

1060   void TargetLoweringBase::computeRegisterProperties(

1061       const TargetRegisterInfo *TRI) {

1062     static_assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE,

1063                   "Too many value types for ValueTypeActions to hold!");

1064  

1065     // Everything defaults to needing one register.

1066     for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i) {

1067       NumRegistersForVT[i] = 1;

1068       RegisterTypeForVT[i] = TransformToType[i] = (MVT::SimpleValueType)i;

1069     }

1070     // ...except isVoid, which doesn't need any registers.

1071     NumRegistersForVT[MVT::isVoid] = 0;

1072  

1073     // Find the largest integer register class.

1074     unsigned LargestIntReg = MVT::LAST_INTEGER_VALUETYPE;

1075     for (; RegClassForVT[LargestIntReg] == nullptr; --LargestIntReg)

1076       assert(LargestIntReg != MVT::i1 && "No integer registers defined!");

1077  

1078     // Every integer value type larger than this largest register takes twice as

1079     // many registers to represent as the previous ValueType.

1080     for (unsigned ExpandedReg = LargestIntReg + 1;

1081          ExpandedReg <= MVT::LAST_INTEGER_VALUETYPE; ++ExpandedReg) {

1082       NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1];

1083       RegisterTypeForVT[ExpandedReg] = (MVT::SimpleValueType)LargestIntReg;

1084       TransformToType[ExpandedReg] = (MVT::SimpleValueType)(ExpandedReg - 1);

1085       ValueTypeActions.setTypeAction((MVT::SimpleValueType)ExpandedReg,

1086                                      TypeExpandInteger);

1087     }

1088  

1089     // Inspect all of the ValueType's smaller than the largest integer

1090     // register to see which ones need promotion.

1091     unsigned LegalIntReg = LargestIntReg;

1092     for (unsigned IntReg = LargestIntReg - 1;

1093          IntReg >= (unsigned)MVT::i1; --IntReg) {

1094       MVT IVT = (MVT::SimpleValueType)IntReg;

1095       if (isTypeLegal(IVT)) {

1096         LegalIntReg = IntReg;

1097       } else {

1098         RegisterTypeForVT[IntReg] = TransformToType[IntReg] =

1099           (const MVT::SimpleValueType)LegalIntReg;

1100         ValueTypeActions.setTypeAction(IVT, TypePromoteInteger);

1101       }

1102     }

1103  

1104     // ppcf128 type is really two f64's.

1105     if (!isTypeLegal(MVT::ppcf128)) {

1106       if (isTypeLegal(MVT::f64)) {

1107        NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64];

1108         RegisterTypeForVT[MVT::ppcf128] = MVT::f64;

1109         TransformToType[MVT::ppcf128] = MVT::f64;

1110         ValueTypeActions.setTypeAction(MVT::ppcf128, TypeExpandFloat);

1111      } else {

1112         NumRegistersForVT[MVT::ppcf128] = NumRegistersForVT[MVT::i128];

1113         RegisterTypeForVT[MVT::ppcf128] = RegisterTypeForVT[MVT::i128];

1114         TransformToType[MVT::ppcf128] = MVT::i128;

1115       ValueTypeActions.setTypeAction(MVT::ppcf128, TypeSoftenFloat);

1116       }

1117     }

1118  

1119     // Decide how to handle f128. If the target does not have native f128 support,

1120     // expand it to i128 and we will be generating soft float library calls.

1121     if (!isTypeLegal(MVT::f128)) {

1122       NumRegistersForVT[MVT::f128] = NumRegistersForVT[MVT::i128];

1123       RegisterTypeForVT[MVT::f128] = RegisterTypeForVT[MVT::i128];

1124       TransformToType[MVT::f128] = MVT::i128;

1125       ValueTypeActions.setTypeAction(MVT::f128, TypeSoftenFloat);

1126     }

1127  

1128     // Decide how to handle f64. If the target does not have native f64 support,

1129     // expand it to i64 and we will be generating soft float library calls.

1130     if (!isTypeLegal(MVT::f64)) {

1131       NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64];

1132       RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64];

1133       TransformToType[MVT::f64] = MVT::i64;

1134       ValueTypeActions.setTypeAction(MVT::f64, TypeSoftenFloat);

1135     }

1136  

1137     // Decide how to handle f32. If the target does not have native f32 support,

1138     // expand it to i32 and we will be generating soft float library calls.

1139     if (!isTypeLegal(MVT::f32)) {

1140       NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];

1141       RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32];

1142       TransformToType[MVT::f32] = MVT::i32;

1143       ValueTypeActions.setTypeAction(MVT::f32, TypeSoftenFloat);

1144     }

1145  

1146     // Decide how to handle f16. If the target does not have native f16 support,

1147     // promote it to f32, because there are no f16 library calls (except for

1148     // conversions).

1149     if (isTypeLegal(MVT::f32)) {

1150       NumRegistersForVT[MVT::f16] = NumRegistersForVT[MVT::f32];

1151       RegisterTypeForVT[MVT::f16] = RegisterTypeForVT[MVT::f32];

1152        TransformToType[MVT::f16] = MVT::f32;

1153        ValueTypeActions.setTypeAction(MVT::f16, TypePromoteFloat);

1154     }

容器TransformToType用于记录值类型间的提升或扩展关系。对于扩展类型,它包含了该扩展的一步(比如i64 -> i32),即使这个扩展要求多个步骤(比如i64 -> i16)。至于系统内在就支持的类型,容器会保存相同的类型(比如i32 -> i32)(1066行循环初始化)。注意,TransformToType与PromoteToType的含义是不同的。PromoteToType给出了对指定操作,指定类型所要提升到的类型。而TransformToType则是通用的提升规则(即PromoteToType给的是特例)。

与TransformToType伴随的容器ValueTypeActions则记录了该提升或扩展所需的操作,这些操作通过枚举类型LegalizeTypeAction来描述。

122       enum LegalizeTypeAction : uint8_t {

123         TypeLegal,           // The target natively supports this type.

124         TypePromoteInteger,  // Replace this integer with a larger one.

125         TypeExpandInteger,   // Split this integer into two of half the size.

126         TypeSoftenFloat,     // Convert this float to a same size integer type.

127                              // if an operation is not supported in target HW.

128         TypeExpandFloat,     // Split this float into two of half the size.

129         TypeScalarizeVector, // Replace this one-element vector with its element.

130         TypeSplitVector,     // Split this vector into two of half the size.

131         TypeWidenVector,     // This vector should be widened into a larger vector.

132         TypePromoteFloat     // Replace this float with a larger one.

133       };

computeRegisterProperties()下半部分处理向量类型提升。1166行的getPreferredVectorAction(),如果类型是v32i1,支持AVX-512但不支持指令集,返回TypeSplitVector;如果开启了X86实验性的向量拓宽合法化,返回TypeWidenVector;如果该向量只包含一个元素,返回TypeScalarizeVector;否则返回TypePromoteInteger。

TargetLoweringBase::computeRegisterProperties(续)

1156     // Loop over all of the vector value types to see which need transformations.

1157     for (unsigned i = MVT::FIRST_VECTOR_VALUETYPE;

1158          i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {

1159       MVT VT = (MVT::SimpleValueType) i;

1160       if (isTypeLegal(VT))

1161         continue;

1162  

1163       MVT EltVT = VT.getVectorElementType();

1164       unsigned NElts = VT.getVectorNumElements();

1165       bool IsLegalWiderType = false;

1166       LegalizeTypeAction PreferredAction = getPreferredVectorAction(VT);

1167       switch (PreferredAction) {

1168       case TypePromoteInteger: {

1169         // Try to promote the elements of integer vectors. If no legal

1170         // promotion was found, fall through to the widen-vector method.

1171         for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {

1172           MVT SVT = (MVT::SimpleValueType) nVT;

1173           // Promote vectors of integers to vectors with the same number

1174           // of elements, with a wider element type.

1175           if (SVT.getScalarSizeInBits() > EltVT.getSizeInBits() &&

1176               SVT.getVectorNumElements() == NElts && isTypeLegal(SVT)) {

1177             TransformToType[i] = SVT;

1178             RegisterTypeForVT[i] = SVT;

1179             NumRegistersForVT[i] = 1;

1180             ValueTypeActions.setTypeAction(VT, TypePromoteInteger);

1181             IsLegalWiderType = true;

1182             break;

1183           }

1184         }

1185         if (IsLegalWiderType)

1186           break;

1187         LLVM_FALLTHROUGH;

1188       }

1189       case TypeWidenVector:

1190         // Try to widen the vector.

1191         for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {

1192           MVT SVT = (MVT::SimpleValueType) nVT;

1193           if (SVT.getVectorElementType() == EltVT

1194               && SVT.getVectorNumElements() > NElts && isTypeLegal(SVT)) {

1195             TransformToType[i] = SVT;

1196             RegisterTypeForVT[i] = SVT;

1197             NumRegistersForVT[i] = 1;

1198             ValueTypeActions.setTypeAction(VT, TypeWidenVector);

1199             IsLegalWiderType = true;

1200             break;

1201           }

1202         }

1203         if (IsLegalWiderType)

1204           break;

1205         LLVM_FALLTHROUGH;

1206  

1207       case TypeSplitVector:

1208       case TypeScalarizeVector: {

1209         MVT IntermediateVT;

1210         MVT RegisterVT;

1211         unsigned NumIntermediates;

1212         NumRegistersForVT[i] = getVectorTypeBreakdownMVT(VT, IntermediateVT,

1213             NumIntermediates, RegisterVT, this);

1214         RegisterTypeForVT[i] = RegisterVT;

1215  

1216         MVT NVT = VT.getPow2VectorType();

1217         if (NVT == VT) {

1218           // Type is already a power of 2.  The default action is to split.

1219           TransformToType[i] = MVT::Other;

1220           if (PreferredAction == TypeScalarizeVector)

1221             ValueTypeActions.setTypeAction(VT, TypeScalarizeVector);

1222           else if (PreferredAction == TypeSplitVector)

1223             ValueTypeActions.setTypeAction(VT, TypeSplitVector);

1224           else

1225             // Set type action according to the number of elements.

1226             ValueTypeActions.setTypeAction(VT, NElts == 1 ? TypeScalarizeVector

1227                                                           : TypeSplitVector);

1228         } else {

1229           TransformToType[i] = NVT;

1230           ValueTypeActions.setTypeAction(VT, TypeWidenVector);

1231         }

1232         break;

1233       }

1234       default:

1235         llvm_unreachable("Unknown vector legalization action!");

1236       }

1237     }

1238  

1239     // Determine the 'representative' register class for each value type.

1240     // An representative register class is the largest (meaning one which is

1241     // not a sub-register class / subreg register class) legal register class for

1242     // a group of value types. For example, on i386, i8, i16, and i32

1243     // representative would be GR32; while on x86_64 it's GR64.

1244     for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i) {

1245       const TargetRegisterClass* RRC;

1246       uint8_t Cost;

1247       std::tie(RRC, Cost) = findRepresentativeClass(TRI, (MVT::SimpleValueType)i);

1248       RepRegClassForVT[i] = RRC;

1249       RepRegClassCostForVT[i] = Cost;

1250     }

1251   }

注意1168行与1189行的case分支,如果1185行与1203行的条件语句不满足,它们将执行下一个case分支的语句。因此对扩展无望的类型,就会谋求分裂类型,即通过多个更小的向量类型来支持。对于TypeSplitVector操作,源向量类型必须是2幂次大小,getVectorTypeBreakdownMVT()获取可能的分裂类型,它的返回值是所需寄存器的个数。

856     static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,

857                                               unsigned &NumIntermediates,

858                                               MVT &RegisterVT,

859                                               TargetLoweringBase *TLI) {

860       // Figure out the right, legal destination reg to copy into.

861       unsigned NumElts = VT.getVectorNumElements();

862       MVT EltTy = VT.getVectorElementType();

863    

864       unsigned NumVectorRegs = 1;

865    

866       // FIXME: We don't support non-power-of-2-sized vectors for now.  Ideally we

867       // could break down into LHS/RHS like LegalizeDAG does.

868       if (!isPowerOf2_32(NumElts)) {

869         NumVectorRegs = NumElts;

870         NumElts = 1;

871       }

872    

873       // Divide the input until we get to a supported size.  This will always

874       // end with a scalar if the target doesn't support vectors.

875       while (NumElts > 1 && !TLI->isTypeLegal(MVT::getVectorVT(EltTy, NumElts))) {

876         NumElts >>= 1;

877         NumVectorRegs <<= 1;

878       }

879    

880       NumIntermediates = NumVectorRegs;

881    

882       MVT NewVT = MVT::getVectorVT(EltTy, NumElts);

883       if (!TLI->isTypeLegal(NewVT))

884         NewVT = EltTy;

885       IntermediateVT = NewVT;

886    

887       unsigned NewVTSize = NewVT.getSizeInBits();

888    

889       // Convert sizes such as i33 to i64.

890       if (!isPowerOf2_32(NewVTSize))

891         NewVTSize = NextPowerOf2(NewVTSize);

892    

893       MVT DestVT = TLI->getRegisterType(NewVT);

894       RegisterVT = DestVT;

895       if (EVT(DestVT).bitsLT(NewVT))    // Value is expanded, e.g. i64 -> i16.

896         return NumVectorRegs*(NewVTSize/DestVT.getSizeInBits());

897    

898       // Otherwise, promotion or legal types use the same number of registers as

899       // the vector decimated to the appropriate level.

900       return NumVectorRegs;

901     }

向量类型有一些限制,它元素的个数必须是2的幂。因此,如果要求的类型不是由2的幂个元素组成,就需要使用这么多个元素大小的类型来替换(868行条件)。如果这个检查通过了,那么在875行循环,我们每次将元素个数减半(换而言之寄存器数个数加倍),直到找到合法的向量类型为止。因此如果883行条件不满足,这意味着我们把元素个数降到1,也没找到合法的类型。那么以元素类型为出发点,在891行通过NextPowerOf2()向上查找大小为2次幂且最接近的类型。

在computeRegisterProperties()的1212与1214行通过NumRegistersForVT与RegisterTypeForVT记录下了getVectorTypeBreakdownMVT()给出的结果。在1216行,getPow2VectorType()返回大小为2次幂且最接近VT的上级类型,如果VT本身不是2次幂大小,就要提升到这个类型。

最后,在1244行循环,通过findRepresentativeClass()找出每个类型的代表寄存器。

1032   std::pair<const TargetRegisterClass *, uint8_t>

1033   TargetLoweringBase::findRepresentativeClass(const TargetRegisterInfo *TRI,

1034                                               MVT VT) const {

1035     const TargetRegisterClass *RC = RegClassForVT[VT.SimpleTy];

1036     if (!RC)

1037       return std::make_pair(RC, 0);

1038  

1039     // Compute the set of all super-register classes.

1040     BitVector SuperRegRC(TRI->getNumRegClasses());

1041     for (SuperRegClassIterator RCI(RC, TRI); RCI.isValid(); ++RCI)

1042       SuperRegRC.setBitsInMask(RCI.getMask());

1043  

1044     // Find the first legal register class with the largest spill size.

1045     const TargetRegisterClass *BestRC = RC;

1046     for (unsigned i : SuperRegRC.set_bits()) {

1047       const TargetRegisterClass *SuperRC = TRI->getRegClass(i);

1048      // We want the largest possible spill size.

1049       if (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC))

1050         continue;

1051       if (!isLegalRC(*TRI, *SuperRC))

1052         continue;

1053       BestRC = SuperRC;

1054     }

1055     return std::make_pair(BestRC, 1);

1056   }

1041行的SuperRegClassIterator是一个定制的迭代器,可以遍历一个指定寄存器类的上级寄存器。而容器SuperRegRC记录的就是这些上级寄存器类的序号。因此1046行循环就是查找最大的寄存器类,并连同使用代价返回它(这里代价总是1,它被调度器用来估算寄存器压力)。

从computeRegisterProperties()返回,X86TargetLowering构造函数完成剩下的配置就结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值