X86GenRegisterBankInfo::PartialMappingIdx X86GenRegisterBankInfo::getPartialMappingIdx(const LLT &Ty, bool isFP) { if ((Ty.isScalar() && !isFP) || Ty.isPointer()) { switch (Ty.getSizeInBits()) { case 1: case 8: return PMI_GPR8; case 16: return PMI_GPR16; case 32: return PMI_GPR32; case 64: return PMI_GPR64; case 128: return PMI_VEC128; break; default: llvm_unreachable("Unsupported register size."); } } else if (Ty.isScalar()) { switch (Ty.getSizeInBits()) { case 32: return PMI_FP32; case 64: return PMI_FP64; case 128: return PMI_VEC128; default: llvm_unreachable("Unsupported register size."); } } else { switch (Ty.getSizeInBits()) { case 128: return PMI_VEC128; case 256: return PMI_VEC256; case 512: return PMI_VEC512; default: llvm_unreachable("Unsupported register size."); } } return PMI_None; }
void LegalizerInfo::computeTables() { assert(TablesInitialized == false); for (unsigned OpcodeIdx = 0; OpcodeIdx <= LastOp - FirstOp; ++OpcodeIdx) { const unsigned Opcode = FirstOp + OpcodeIdx; for (unsigned TypeIdx = 0; TypeIdx != SpecifiedActions[OpcodeIdx].size(); ++TypeIdx) { // 0. Collect information specified through the setAction API, i.e. // for specific bit sizes. // For scalar types: SizeAndActionsVec ScalarSpecifiedActions; // For pointer types: std::map<uint16_t, SizeAndActionsVec> AddressSpace2SpecifiedActions; // For vector types: std::map<uint16_t, SizeAndActionsVec> ElemSize2SpecifiedActions; for (auto LLT2Action : SpecifiedActions[OpcodeIdx][TypeIdx]) { const LLT Type = LLT2Action.first; const LegalizeAction Action = LLT2Action.second; auto SizeAction = std::make_pair(Type.getSizeInBits(), Action); if (Type.isPointer()) AddressSpace2SpecifiedActions[Type.getAddressSpace()].push_back( SizeAction); else if (Type.isVector()) ElemSize2SpecifiedActions[Type.getElementType().getSizeInBits()] .push_back(SizeAction); else ScalarSpecifiedActions.push_back(SizeAction); } // 1. Handle scalar types { // Decide how to handle bit sizes for which no explicit specification // was given. SizeChangeStrategy S = &unsupportedForDifferentSizes; if (TypeIdx < ScalarSizeChangeStrategies[OpcodeIdx].size() && ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr) S = ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx]; std::sort(ScalarSpecifiedActions.begin(), ScalarSpecifiedActions.end()); checkPartialSizeAndActionsVector(ScalarSpecifiedActions); setScalarAction(Opcode, TypeIdx, S(ScalarSpecifiedActions)); } // 2. Handle pointer types for (auto PointerSpecifiedActions : AddressSpace2SpecifiedActions) { std::sort(PointerSpecifiedActions.second.begin(), PointerSpecifiedActions.second.end()); checkPartialSizeAndActionsVector(PointerSpecifiedActions.second); // For pointer types, we assume that there isn't a meaningfull way // to change the number of bits used in the pointer. setPointerAction( Opcode, TypeIdx, PointerSpecifiedActions.first, unsupportedForDifferentSizes(PointerSpecifiedActions.second)); } // 3. Handle vector types SizeAndActionsVec ElementSizesSeen; for (auto VectorSpecifiedActions : ElemSize2SpecifiedActions) { std::sort(VectorSpecifiedActions.second.begin(), VectorSpecifiedActions.second.end()); const uint16_t ElementSize = VectorSpecifiedActions.first; ElementSizesSeen.push_back({ElementSize, Legal}); checkPartialSizeAndActionsVector(VectorSpecifiedActions.second); // For vector types, we assume that the best way to adapt the number // of elements is to the next larger number of elements type for which // the vector type is legal, unless there is no such type. In that case, // legalize towards a vector type with a smaller number of elements. SizeAndActionsVec NumElementsActions; for (SizeAndAction BitsizeAndAction : VectorSpecifiedActions.second) { assert(BitsizeAndAction.first % ElementSize == 0); const uint16_t NumElements = BitsizeAndAction.first / ElementSize; NumElementsActions.push_back({NumElements, BitsizeAndAction.second}); } setVectorNumElementAction( Opcode, TypeIdx, ElementSize, moreToWiderTypesAndLessToWidest(NumElementsActions)); } std::sort(ElementSizesSeen.begin(), ElementSizesSeen.end()); SizeChangeStrategy VectorElementSizeChangeStrategy = &unsupportedForDifferentSizes; if (TypeIdx < VectorElementSizeChangeStrategies[OpcodeIdx].size() && VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] != nullptr) VectorElementSizeChangeStrategy = VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx]; setScalarInVectorAction( Opcode, TypeIdx, VectorElementSizeChangeStrategy(ElementSizesSeen)); } } TablesInitialized = true; }