[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:
Quentin Colombet 2017-05-05 22:48:22 +00:00
parent 58d2d9869a
commit ce22b10a6e
12 changed files with 211 additions and 132 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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());
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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:

View File

@ -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