mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 22:20:37 +00:00
[RegisterBankInfo] Uniquely allocate instruction mapping.
This is a step toward having statically allocated instruciton mapping. We are going to tablegen them eventually, so let us reflect that in the API. NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302316 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
58d2d9869a
commit
ce22b10a6e
@ -561,7 +561,7 @@ private:
|
||||
|
||||
/// Find the best mapping for \p MI from \p PossibleMappings.
|
||||
/// \return a reference on the best mapping in \p PossibleMappings.
|
||||
RegisterBankInfo::InstructionMapping &
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
findBestMapping(MachineInstr &MI,
|
||||
RegisterBankInfo::InstructionMappings &PossibleMappings,
|
||||
SmallVectorImpl<RepairingPlacement> &RepairPts);
|
||||
|
@ -264,7 +264,7 @@ public:
|
||||
/// Convenient type to represent the alternatives for mapping an
|
||||
/// instruction.
|
||||
/// \todo When we move to TableGen this should be an array ref.
|
||||
typedef SmallVector<InstructionMapping, 4> InstructionMappings;
|
||||
typedef SmallVector<const InstructionMapping *, 4> InstructionMappings;
|
||||
|
||||
/// Helper class used to get/create the virtual registers that will be used
|
||||
/// to replace the MachineOperand when applying a mapping.
|
||||
@ -391,6 +391,11 @@ protected:
|
||||
mutable DenseMap<unsigned, std::unique_ptr<ValueMapping[]>>
|
||||
MapOfOperandsMappings;
|
||||
|
||||
/// Keep dynamically allocated InstructionMapping in a separate map.
|
||||
/// This shouldn't be needed when everything gets TableGen'ed.
|
||||
mutable DenseMap<unsigned, std::unique_ptr<const InstructionMapping>>
|
||||
MapOfInstructionMappings;
|
||||
|
||||
/// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
|
||||
/// RegisterBank instances.
|
||||
RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
|
||||
@ -428,7 +433,7 @@ protected:
|
||||
/// register, a register class, or a register bank.
|
||||
/// In other words, this method will likely fail to find a mapping for
|
||||
/// any generic opcode that has not been lowered by target specific code.
|
||||
InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const;
|
||||
const InstructionMapping &getInstrMappingImpl(const MachineInstr &MI) const;
|
||||
|
||||
/// Get the uniquely generated PartialMapping for the
|
||||
/// given arguments.
|
||||
@ -481,6 +486,33 @@ protected:
|
||||
std::initializer_list<const ValueMapping *> OpdsMapping) const;
|
||||
/// @}
|
||||
|
||||
/// \name Methods to get a uniquely generated InstructionMapping.
|
||||
/// @{
|
||||
|
||||
private:
|
||||
/// Method to get a uniquely generated InstructionMapping.
|
||||
const InstructionMapping &
|
||||
getInstructionMappingImpl(bool IsInvalid, unsigned ID = InvalidMappingID,
|
||||
unsigned Cost = 0,
|
||||
const ValueMapping *OperandsMapping = nullptr,
|
||||
unsigned NumOperands = 0) const;
|
||||
|
||||
public:
|
||||
/// Method to get a uniquely generated InstructionMapping.
|
||||
const InstructionMapping &
|
||||
getInstructionMapping(unsigned ID, unsigned Cost,
|
||||
const ValueMapping *OperandsMapping,
|
||||
unsigned NumOperands) const {
|
||||
return getInstructionMappingImpl(/*IsInvalid*/ false, ID, Cost,
|
||||
OperandsMapping, NumOperands);
|
||||
}
|
||||
|
||||
/// Method to get a uniquely generated invalid InstructionMapping.
|
||||
const InstructionMapping &getInvalidInstructionMapping() const {
|
||||
return getInstructionMappingImpl(/*IsInvalid*/ true);
|
||||
}
|
||||
/// @}
|
||||
|
||||
/// Get the register bank for the \p OpIdx-th operand of \p MI form
|
||||
/// the encoding constraints, if any.
|
||||
///
|
||||
@ -606,7 +638,8 @@ public:
|
||||
///
|
||||
/// \note If returnedVal does not verify MI, this would probably mean
|
||||
/// that the target does not support that instruction.
|
||||
virtual InstructionMapping getInstrMapping(const MachineInstr &MI) const;
|
||||
virtual const InstructionMapping &
|
||||
getInstrMapping(const MachineInstr &MI) const;
|
||||
|
||||
/// Get the alternative mappings for \p MI.
|
||||
/// Alternative in the sense different from getInstrMapping.
|
||||
|
@ -213,21 +213,23 @@ uint64_t RegBankSelect::getRepairCost(
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping(
|
||||
const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping(
|
||||
MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings,
|
||||
SmallVectorImpl<RepairingPlacement> &RepairPts) {
|
||||
assert(!PossibleMappings.empty() &&
|
||||
"Do not know how to map this instruction");
|
||||
|
||||
RegisterBankInfo::InstructionMapping *BestMapping = nullptr;
|
||||
const RegisterBankInfo::InstructionMapping *BestMapping = nullptr;
|
||||
MappingCost Cost = MappingCost::ImpossibleCost();
|
||||
SmallVector<RepairingPlacement, 4> LocalRepairPts;
|
||||
for (RegisterBankInfo::InstructionMapping &CurMapping : PossibleMappings) {
|
||||
MappingCost CurCost = computeMapping(MI, CurMapping, LocalRepairPts, &Cost);
|
||||
for (const RegisterBankInfo::InstructionMapping *CurMapping :
|
||||
PossibleMappings) {
|
||||
MappingCost CurCost =
|
||||
computeMapping(MI, *CurMapping, LocalRepairPts, &Cost);
|
||||
if (CurCost < Cost) {
|
||||
DEBUG(dbgs() << "New best: " << CurCost << '\n');
|
||||
Cost = CurCost;
|
||||
BestMapping = &CurMapping;
|
||||
BestMapping = CurMapping;
|
||||
RepairPts.clear();
|
||||
for (RepairingPlacement &RepairPt : LocalRepairPts)
|
||||
RepairPts.emplace_back(std::move(RepairPt));
|
||||
@ -237,7 +239,7 @@ RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping(
|
||||
// If none of the mapping worked that means they are all impossible.
|
||||
// Thus, pick the first one and set an impossible repairing point.
|
||||
// It will trigger the failed isel mode.
|
||||
BestMapping = &(*PossibleMappings.begin());
|
||||
BestMapping = *PossibleMappings.begin();
|
||||
RepairPts.emplace_back(
|
||||
RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible));
|
||||
} else
|
||||
@ -543,10 +545,10 @@ bool RegBankSelect::assignInstr(MachineInstr &MI) {
|
||||
// Remember the repairing placement for all the operands.
|
||||
SmallVector<RepairingPlacement, 4> RepairPts;
|
||||
|
||||
RegisterBankInfo::InstructionMapping BestMapping;
|
||||
const RegisterBankInfo::InstructionMapping *BestMapping;
|
||||
if (OptMode == RegBankSelect::Mode::Fast) {
|
||||
BestMapping = RBI->getInstrMapping(MI);
|
||||
MappingCost DefaultCost = computeMapping(MI, BestMapping, RepairPts);
|
||||
BestMapping = &RBI->getInstrMapping(MI);
|
||||
MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts);
|
||||
(void)DefaultCost;
|
||||
if (DefaultCost == MappingCost::ImpossibleCost())
|
||||
return false;
|
||||
@ -555,16 +557,16 @@ bool RegBankSelect::assignInstr(MachineInstr &MI) {
|
||||
RBI->getInstrPossibleMappings(MI);
|
||||
if (PossibleMappings.empty())
|
||||
return false;
|
||||
BestMapping = std::move(findBestMapping(MI, PossibleMappings, RepairPts));
|
||||
BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts);
|
||||
}
|
||||
// Make sure the mapping is valid for MI.
|
||||
assert(BestMapping.verify(MI) && "Invalid instruction mapping");
|
||||
assert(BestMapping->verify(MI) && "Invalid instruction mapping");
|
||||
|
||||
DEBUG(dbgs() << "Best Mapping: " << BestMapping << '\n');
|
||||
DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n');
|
||||
|
||||
// After this call, MI may not be valid anymore.
|
||||
// Do not use it.
|
||||
return applyMapping(MI, BestMapping, RepairPts);
|
||||
return applyMapping(MI, *BestMapping, RepairPts);
|
||||
}
|
||||
|
||||
bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
@ -45,6 +45,10 @@ STATISTIC(NumOperandsMappingsCreated,
|
||||
"Number of operands mappings dynamically created");
|
||||
STATISTIC(NumOperandsMappingsAccessed,
|
||||
"Number of operands mappings dynamically accessed");
|
||||
STATISTIC(NumInstructionMappingsCreated,
|
||||
"Number of instruction mappings dynamically created");
|
||||
STATISTIC(NumInstructionMappingsAccessed,
|
||||
"Number of instruction mappings dynamically accessed");
|
||||
|
||||
const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX;
|
||||
const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1;
|
||||
@ -137,7 +141,7 @@ static bool isCopyLike(const MachineInstr &MI) {
|
||||
MI.getOpcode() == TargetOpcode::REG_SEQUENCE;
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
// For copies we want to walk over the operands and try to find one
|
||||
// that has a register bank since the instruction itself will not get
|
||||
@ -147,9 +151,6 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
// is important. The rest is not constrained.
|
||||
unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands();
|
||||
|
||||
RegisterBankInfo::InstructionMapping Mapping(DefaultMappingID, /*Cost*/ 1,
|
||||
/*OperandsMapping*/ nullptr,
|
||||
NumOperandsForMapping);
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const TargetSubtargetInfo &STI = MF.getSubtarget();
|
||||
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
|
||||
@ -190,7 +191,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
|
||||
if (!IsCopyLike)
|
||||
// MI does not carry enough information to guess the mapping.
|
||||
return InstructionMapping();
|
||||
return getInvalidInstructionMapping();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -206,11 +207,13 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
|
||||
if (IsCopyLike && !CompleteMapping)
|
||||
// No way to deduce the type from what we have.
|
||||
return InstructionMapping();
|
||||
return getInvalidInstructionMapping();
|
||||
|
||||
assert(CompleteMapping && "Setting an uncomplete mapping");
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OperandsMapping));
|
||||
return Mapping;
|
||||
return getInstructionMapping(
|
||||
DefaultMappingID, /*Cost*/ 1,
|
||||
/*OperandsMapping*/ getOperandsMapping(OperandsMapping),
|
||||
NumOperandsForMapping);
|
||||
}
|
||||
|
||||
/// Hashing function for PartialMapping.
|
||||
@ -320,9 +323,44 @@ const RegisterBankInfo::ValueMapping *RegisterBankInfo::getOperandsMapping(
|
||||
return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end());
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
static hash_code
|
||||
hashInstructionMapping(unsigned ID, unsigned Cost,
|
||||
const RegisterBankInfo::ValueMapping *OperandsMapping,
|
||||
unsigned NumOperands) {
|
||||
return hash_combine(ID, Cost, OperandsMapping, NumOperands);
|
||||
}
|
||||
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
RegisterBankInfo::getInstructionMappingImpl(
|
||||
bool IsInvalid, unsigned ID, unsigned Cost,
|
||||
const RegisterBankInfo::ValueMapping *OperandsMapping,
|
||||
unsigned NumOperands) const {
|
||||
assert(((IsInvalid && ID == InvalidMappingID && Cost == 0 &&
|
||||
OperandsMapping == nullptr && NumOperands == 0) ||
|
||||
!IsInvalid) &&
|
||||
"Mismatch argument for invalid input");
|
||||
++NumInstructionMappingsAccessed;
|
||||
|
||||
hash_code Hash =
|
||||
hashInstructionMapping(ID, Cost, OperandsMapping, NumOperands);
|
||||
const auto &It = MapOfInstructionMappings.find(Hash);
|
||||
if (It != MapOfInstructionMappings.end())
|
||||
return *It->second;
|
||||
|
||||
++NumInstructionMappingsCreated;
|
||||
|
||||
auto &InstrMapping = MapOfInstructionMappings[Hash];
|
||||
if (IsInvalid)
|
||||
InstrMapping = llvm::make_unique<InstructionMapping>();
|
||||
else
|
||||
InstrMapping = llvm::make_unique<InstructionMapping>(
|
||||
ID, Cost, OperandsMapping, NumOperands);
|
||||
return *InstrMapping;
|
||||
}
|
||||
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
|
||||
const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
|
||||
if (Mapping.isValid())
|
||||
return Mapping;
|
||||
llvm_unreachable("The target must implement this");
|
||||
@ -332,14 +370,14 @@ RegisterBankInfo::InstructionMappings
|
||||
RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const {
|
||||
InstructionMappings PossibleMappings;
|
||||
// Put the default mapping first.
|
||||
PossibleMappings.push_back(getInstrMapping(MI));
|
||||
PossibleMappings.push_back(&getInstrMapping(MI));
|
||||
// Then the alternative mapping, if any.
|
||||
InstructionMappings AltMappings = getInstrAlternativeMappings(MI);
|
||||
for (InstructionMapping &AltMapping : AltMappings)
|
||||
PossibleMappings.emplace_back(std::move(AltMapping));
|
||||
for (const InstructionMapping *AltMapping : AltMappings)
|
||||
PossibleMappings.push_back(AltMapping);
|
||||
#ifndef NDEBUG
|
||||
for (const InstructionMapping &Mapping : PossibleMappings)
|
||||
assert(Mapping.verify(MI) && "Mapping is invalid");
|
||||
for (const InstructionMapping *Mapping : PossibleMappings)
|
||||
assert(Mapping->verify(MI) && "Mapping is invalid");
|
||||
#endif
|
||||
return PossibleMappings;
|
||||
}
|
||||
|
@ -260,15 +260,15 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
|
||||
if (MI.getNumOperands() != 3)
|
||||
break;
|
||||
InstructionMappings AltMappings;
|
||||
InstructionMapping GPRMapping(
|
||||
const InstructionMapping &GPRMapping = getInstructionMapping(
|
||||
/*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
|
||||
/*NumOperands*/ 3);
|
||||
InstructionMapping FPRMapping(
|
||||
const InstructionMapping &FPRMapping = getInstructionMapping(
|
||||
/*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
|
||||
/*NumOperands*/ 3);
|
||||
|
||||
AltMappings.emplace_back(std::move(GPRMapping));
|
||||
AltMappings.emplace_back(std::move(FPRMapping));
|
||||
AltMappings.push_back(&GPRMapping);
|
||||
AltMappings.push_back(&FPRMapping);
|
||||
return AltMappings;
|
||||
}
|
||||
case TargetOpcode::G_BITCAST: {
|
||||
@ -282,29 +282,29 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
|
||||
break;
|
||||
|
||||
InstructionMappings AltMappings;
|
||||
InstructionMapping GPRMapping(
|
||||
const InstructionMapping &GPRMapping = getInstructionMapping(
|
||||
/*ID*/ 1, /*Cost*/ 1,
|
||||
getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
|
||||
/*NumOperands*/ 2);
|
||||
InstructionMapping FPRMapping(
|
||||
const InstructionMapping &FPRMapping = getInstructionMapping(
|
||||
/*ID*/ 2, /*Cost*/ 1,
|
||||
getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
|
||||
/*NumOperands*/ 2);
|
||||
InstructionMapping GPRToFPRMapping(
|
||||
const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
|
||||
/*ID*/ 3,
|
||||
/*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
|
||||
getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
|
||||
/*NumOperands*/ 2);
|
||||
InstructionMapping FPRToGPRMapping(
|
||||
const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
|
||||
/*ID*/ 3,
|
||||
/*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
|
||||
getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
|
||||
/*NumOperands*/ 2);
|
||||
|
||||
AltMappings.emplace_back(std::move(GPRMapping));
|
||||
AltMappings.emplace_back(std::move(FPRMapping));
|
||||
AltMappings.emplace_back(std::move(GPRToFPRMapping));
|
||||
AltMappings.emplace_back(std::move(FPRToGPRMapping));
|
||||
AltMappings.push_back(&GPRMapping);
|
||||
AltMappings.push_back(&FPRMapping);
|
||||
AltMappings.push_back(&GPRToFPRMapping);
|
||||
AltMappings.push_back(&FPRToGPRMapping);
|
||||
return AltMappings;
|
||||
}
|
||||
case TargetOpcode::G_LOAD: {
|
||||
@ -318,21 +318,21 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
|
||||
break;
|
||||
|
||||
InstructionMappings AltMappings;
|
||||
InstructionMapping GPRMapping(
|
||||
const InstructionMapping &GPRMapping = getInstructionMapping(
|
||||
/*ID*/ 1, /*Cost*/ 1,
|
||||
getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
|
||||
// Addresses are GPR 64-bit.
|
||||
getValueMapping(PMI_FirstGPR, 64)}),
|
||||
/*NumOperands*/ 2);
|
||||
InstructionMapping FPRMapping(
|
||||
const InstructionMapping &FPRMapping = getInstructionMapping(
|
||||
/*ID*/ 2, /*Cost*/ 1,
|
||||
getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
|
||||
// Addresses are GPR 64-bit.
|
||||
getValueMapping(PMI_FirstGPR, 64)}),
|
||||
/*NumOperands*/ 2);
|
||||
|
||||
AltMappings.emplace_back(std::move(GPRMapping));
|
||||
AltMappings.emplace_back(std::move(FPRMapping));
|
||||
AltMappings.push_back(&GPRMapping);
|
||||
AltMappings.push_back(&FPRMapping);
|
||||
return AltMappings;
|
||||
}
|
||||
default:
|
||||
@ -373,8 +373,9 @@ static bool isPreISelGenericFloatingPointOpcode(unsigned Opc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) {
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
|
||||
const MachineInstr &MI) const {
|
||||
const unsigned Opc = MI.getOpcode();
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
@ -411,11 +412,11 @@ AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) {
|
||||
}
|
||||
#endif // End NDEBUG.
|
||||
|
||||
return InstructionMapping{DefaultMappingID, 1, getValueMapping(RBIdx, Size),
|
||||
NumOperands};
|
||||
return getInstructionMapping(DefaultMappingID, 1,
|
||||
getValueMapping(RBIdx, Size), NumOperands);
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
const unsigned Opc = MI.getOpcode();
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
@ -424,7 +425,8 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
// Try the default logic for non-generic instructions that are either copies
|
||||
// or already have some operands assigned to banks.
|
||||
if (!isPreISelGenericOpcode(Opc)) {
|
||||
RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
|
||||
const RegisterBankInfo::InstructionMapping &Mapping =
|
||||
getInstrMappingImpl(MI);
|
||||
if (Mapping.isValid())
|
||||
return Mapping;
|
||||
}
|
||||
@ -462,15 +464,15 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
|
||||
const RegisterBank &SrcRB =
|
||||
SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
|
||||
return InstructionMapping{
|
||||
return getInstructionMapping(
|
||||
DefaultMappingID, copyCost(DstRB, SrcRB, Size),
|
||||
getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
|
||||
/*NumOperands*/ 2};
|
||||
/*NumOperands*/ 2);
|
||||
}
|
||||
case TargetOpcode::G_SEQUENCE:
|
||||
// FIXME: support this, but the generic code is really not going to do
|
||||
// anything sane.
|
||||
return InstructionMapping();
|
||||
return getInvalidInstructionMapping();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -533,19 +535,17 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
}
|
||||
|
||||
// Finally construct the computed mapping.
|
||||
RegisterBankInfo::InstructionMapping Mapping =
|
||||
InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands};
|
||||
SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
|
||||
for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
|
||||
if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
|
||||
auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
|
||||
if (!Mapping->isValid())
|
||||
return InstructionMapping();
|
||||
return getInvalidInstructionMapping();
|
||||
|
||||
OpdsMapping[Idx] = Mapping;
|
||||
}
|
||||
}
|
||||
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
|
||||
return Mapping;
|
||||
return getInstructionMapping(DefaultMappingID, Cost,
|
||||
getOperandsMapping(OpdsMapping), NumOperands);
|
||||
}
|
||||
|
@ -98,8 +98,8 @@ class AArch64RegisterBankInfo final : public AArch64GenRegisterBankInfo {
|
||||
///
|
||||
/// \return An InstructionMappings with a statically allocated
|
||||
/// OperandsMapping.
|
||||
static InstructionMapping
|
||||
getSameKindOfOperandsMapping(const MachineInstr &MI);
|
||||
const InstructionMapping &
|
||||
getSameKindOfOperandsMapping(const MachineInstr &MI) const;
|
||||
|
||||
public:
|
||||
AArch64RegisterBankInfo(const TargetRegisterInfo &TRI);
|
||||
@ -113,7 +113,8 @@ public:
|
||||
InstructionMappings
|
||||
getInstrAlternativeMappings(const MachineInstr &MI) const override;
|
||||
|
||||
InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
|
||||
const InstructionMapping &
|
||||
getInstrMapping(const MachineInstr &MI) const override;
|
||||
};
|
||||
} // End llvm namespace.
|
||||
#endif
|
||||
|
@ -82,25 +82,28 @@ AMDGPURegisterBankInfo::getInstrAlternativeMappings(
|
||||
switch (MI.getOpcode()) {
|
||||
case TargetOpcode::G_LOAD: {
|
||||
// FIXME: Should we be hard coding the size for these mappings?
|
||||
InstructionMapping SSMapping(1, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
|
||||
2); // Num Operands
|
||||
AltMappings.emplace_back(std::move(SSMapping));
|
||||
const InstructionMapping &SSMapping = getInstructionMapping(
|
||||
1, 1, getOperandsMapping(
|
||||
{AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
|
||||
2); // Num Operands
|
||||
AltMappings.push_back(&SSMapping);
|
||||
|
||||
InstructionMapping VVMapping(2, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
|
||||
2); // Num Operands
|
||||
AltMappings.emplace_back(std::move(VVMapping));
|
||||
const InstructionMapping &VVMapping = getInstructionMapping(
|
||||
2, 1, getOperandsMapping(
|
||||
{AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
|
||||
2); // Num Operands
|
||||
AltMappings.push_back(&VVMapping);
|
||||
|
||||
// FIXME: Should this be the pointer-size (64-bits) or the size of the
|
||||
// register that will hold the bufffer resourc (128-bits).
|
||||
InstructionMapping VSMapping(3, 1,
|
||||
getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
|
||||
2); // Num Operands
|
||||
AltMappings.emplace_back(std::move(VSMapping));
|
||||
const InstructionMapping &VSMapping = getInstructionMapping(
|
||||
3, 1, getOperandsMapping(
|
||||
{AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
|
||||
AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
|
||||
2); // Num Operands
|
||||
AltMappings.push_back(&VSMapping);
|
||||
|
||||
return AltMappings;
|
||||
|
||||
@ -124,13 +127,11 @@ static bool isInstrUniform(const MachineInstr &MI) {
|
||||
return AMDGPU::isUniformMMO(MMO);
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
|
||||
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
RegisterBankInfo::InstructionMapping Mapping =
|
||||
InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
|
||||
SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
|
||||
unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
|
||||
unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
|
||||
@ -150,32 +151,34 @@ AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
|
||||
|
||||
OpdsMapping[0] = ValMapping;
|
||||
OpdsMapping[1] = PtrMapping;
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
|
||||
const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
|
||||
1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
|
||||
return Mapping;
|
||||
|
||||
// FIXME: Do we want to add a mapping for FLAT load, or should we just
|
||||
// handle that during instruction selection?
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
|
||||
const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
|
||||
|
||||
if (Mapping.isValid())
|
||||
return Mapping;
|
||||
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
|
||||
SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands());
|
||||
|
||||
bool IsComplete = true;
|
||||
switch (MI.getOpcode()) {
|
||||
default: break;
|
||||
default:
|
||||
IsComplete = false;
|
||||
break;
|
||||
case AMDGPU::G_CONSTANT: {
|
||||
unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
|
||||
OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
|
||||
return Mapping;
|
||||
break;
|
||||
}
|
||||
case AMDGPU::G_GEP: {
|
||||
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
||||
@ -185,8 +188,7 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
|
||||
OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
|
||||
}
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
|
||||
return Mapping;
|
||||
break;
|
||||
}
|
||||
case AMDGPU::G_STORE: {
|
||||
assert(MI.getOperand(0).isReg());
|
||||
@ -203,28 +205,27 @@ AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
|
||||
OpdsMapping[0] = ValMapping;
|
||||
OpdsMapping[1] = PtrMapping;
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
|
||||
return Mapping;
|
||||
break;
|
||||
}
|
||||
|
||||
case AMDGPU::G_LOAD:
|
||||
return getInstrMappingForLoad(MI);
|
||||
}
|
||||
|
||||
unsigned BankID = AMDGPU::SGPRRegBankID;
|
||||
if (!IsComplete) {
|
||||
unsigned BankID = AMDGPU::SGPRRegBankID;
|
||||
|
||||
Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
|
||||
unsigned Size = 0;
|
||||
for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
|
||||
// If the operand is not a register default to the size of the previous
|
||||
// operand.
|
||||
// FIXME: Can't we pull the types from the MachineInstr rather than the
|
||||
// operands.
|
||||
if (MI.getOperand(Idx).isReg())
|
||||
Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
|
||||
OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
|
||||
unsigned Size = 0;
|
||||
for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
|
||||
// If the operand is not a register default to the size of the previous
|
||||
// operand.
|
||||
// FIXME: Can't we pull the types from the MachineInstr rather than the
|
||||
// operands.
|
||||
if (MI.getOperand(Idx).isReg())
|
||||
Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
|
||||
OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
|
||||
}
|
||||
}
|
||||
Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
|
||||
|
||||
return Mapping;
|
||||
return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
|
||||
MI.getNumOperands());
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class AMDGPURegisterBankInfo : public AMDGPUGenRegisterBankInfo {
|
||||
/// See RegisterBankInfo::applyMapping.
|
||||
void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
getInstrMappingForLoad(const MachineInstr &MI) const;
|
||||
|
||||
public:
|
||||
@ -59,7 +59,8 @@ public:
|
||||
InstructionMappings
|
||||
getInstrAlternativeMappings(const MachineInstr &MI) const override;
|
||||
|
||||
InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
|
||||
const InstructionMapping &
|
||||
getInstrMapping(const MachineInstr &MI) const override;
|
||||
};
|
||||
} // End llvm namespace.
|
||||
#endif
|
||||
|
@ -196,14 +196,14 @@ const RegisterBank &ARMRegisterBankInfo::getRegBankFromRegClass(
|
||||
llvm_unreachable("Switch should handle all register classes");
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
auto Opc = MI.getOpcode();
|
||||
|
||||
// Try the default logic for non-generic instructions that are either copies
|
||||
// or already have some operands assigned to banks.
|
||||
if (!isPreISelGenericOpcode(Opc)) {
|
||||
InstructionMapping Mapping = getInstrMappingImpl(MI);
|
||||
const InstructionMapping &Mapping = getInstrMappingImpl(MI);
|
||||
if (Mapping.isValid())
|
||||
return Mapping;
|
||||
}
|
||||
@ -258,7 +258,7 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
|
||||
if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 ||
|
||||
Ty2.getSizeInBits() != 32)
|
||||
return InstructionMapping{};
|
||||
return getInvalidInstructionMapping();
|
||||
OperandsMapping =
|
||||
getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
|
||||
&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr,
|
||||
@ -271,14 +271,14 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
|
||||
if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 64 ||
|
||||
MI.getOperand(2).getImm() % 32 != 0)
|
||||
return InstructionMapping{};
|
||||
return getInvalidInstructionMapping();
|
||||
OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
|
||||
&ARM::ValueMappings[ARM::DPR3OpsIdx],
|
||||
nullptr, nullptr});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return InstructionMapping{};
|
||||
return getInvalidInstructionMapping();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -292,6 +292,6 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
return InstructionMapping{DefaultMappingID, /*Cost=*/1, OperandsMapping,
|
||||
NumOperands};
|
||||
return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
|
||||
NumOperands);
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ public:
|
||||
const RegisterBank &
|
||||
getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
|
||||
|
||||
InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
|
||||
const InstructionMapping &
|
||||
getInstrMapping(const MachineInstr &MI) const override;
|
||||
};
|
||||
} // End llvm namespace.
|
||||
#endif
|
||||
|
@ -139,8 +139,9 @@ bool X86RegisterBankInfo::getInstrValueMapping(
|
||||
return true;
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) {
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
|
||||
bool isFP) const {
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
@ -152,10 +153,10 @@ X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) {
|
||||
llvm_unreachable("Unsupported operand mapping yet.");
|
||||
|
||||
auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
|
||||
return InstructionMapping{DefaultMappingID, 1, Mapping, NumOperands};
|
||||
return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
const RegisterBankInfo::InstructionMapping &
|
||||
X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
@ -164,7 +165,7 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
// Try the default logic for non-generic instructions that are either copies
|
||||
// or already have some operands assigned to banks.
|
||||
if (!isPreISelGenericOpcode(Opc)) {
|
||||
InstructionMapping Mapping = getInstrMappingImpl(MI);
|
||||
const InstructionMapping &Mapping = getInstrMappingImpl(MI);
|
||||
if (Mapping.isValid())
|
||||
return Mapping;
|
||||
}
|
||||
@ -193,10 +194,10 @@ X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
||||
// Finally construct the computed mapping.
|
||||
SmallVector<const ValueMapping *, 8> OpdsMapping(NumOperands);
|
||||
if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
|
||||
return InstructionMapping();
|
||||
return getInvalidInstructionMapping();
|
||||
|
||||
return InstructionMapping{DefaultMappingID, /* Cost */ 1,
|
||||
getOperandsMapping(OpdsMapping), NumOperands};
|
||||
return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
|
||||
getOperandsMapping(OpdsMapping), NumOperands);
|
||||
}
|
||||
|
||||
void X86RegisterBankInfo::applyMappingImpl(
|
||||
@ -231,10 +232,10 @@ X86RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
|
||||
if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
|
||||
break;
|
||||
|
||||
RegisterBankInfo::InstructionMapping Mapping = InstructionMapping{
|
||||
/*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands};
|
||||
const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
|
||||
/*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
|
||||
InstructionMappings AltMappings;
|
||||
AltMappings.emplace_back(std::move(Mapping));
|
||||
AltMappings.push_back(&Mapping);
|
||||
return AltMappings;
|
||||
}
|
||||
default:
|
||||
|
@ -46,8 +46,8 @@ private:
|
||||
/// Get an instruction mapping.
|
||||
/// \return An InstructionMappings with a statically allocated
|
||||
/// OperandsMapping.
|
||||
static InstructionMapping getSameOperandsMapping(const MachineInstr &MI,
|
||||
bool isFP);
|
||||
const InstructionMapping &getSameOperandsMapping(const MachineInstr &MI,
|
||||
bool isFP) const;
|
||||
|
||||
/// Track the bank of each instruction operand(register)
|
||||
static void
|
||||
@ -74,7 +74,8 @@ public:
|
||||
/// See RegisterBankInfo::applyMapping.
|
||||
void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
|
||||
|
||||
InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
|
||||
const InstructionMapping &
|
||||
getInstrMapping(const MachineInstr &MI) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
Loading…
Reference in New Issue
Block a user