summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h34
-rw-r--r--llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp27
2 files changed, 61 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
index 2965f409653..4285b11b91f 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
@@ -395,6 +395,22 @@ protected:
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI) const;
+ /// Helper method to apply something that is like the default mapping.
+ /// Basically, that means that \p OpdMapper.getMI() is left untouched
+ /// aside from the reassignment of the register operand that have been
+ /// remapped.
+ /// If the mapping of one of the operand spans several registers, this
+ /// method will abort as this is not like a default mapping anymore.
+ ///
+ /// \pre For OpIdx in {0..\p OpdMapper.getMI().getNumOperands())
+ /// the range OpdMapper.getVRegs(OpIdx) is empty or of size 1.
+ static void applyDefaultMapping(const OperandsMapper &OpdMapper);
+
+ /// See ::applyMapping.
+ virtual void applyMappingImpl(const OperandsMapper &OpdMapper) const {
+ llvm_unreachable("The target has to implement that part");
+ }
+
public:
virtual ~RegisterBankInfo() {}
@@ -503,6 +519,24 @@ public:
/// \post !returnedVal.empty().
InstructionMappings getInstrPossibleMappings(const MachineInstr &MI) const;
+ /// Apply \p OpdMapper.getInstrMapping() to \p OpdMapper.getMI().
+ /// After this call \p OpdMapper.getMI() may not be valid anymore.
+ /// \p OpdMapper.getInstrMapping().getID() carries the information of
+ /// what has been chosen to map \p OpdMapper.getMI(). This ID is set
+ /// by the various getInstrXXXMapping method.
+ ///
+ /// Therefore, getting the mapping and applying it should be kept in
+ /// sync.
+ void applyMapping(const OperandsMapper &OpdMapper) const {
+ // The only mapping we know how to handle is the default mapping.
+ if (OpdMapper.getInstrMapping().getID() == DefaultMappingID)
+ return applyDefaultMapping(OpdMapper);
+ // For other mapping, the target needs to do the right thing.
+ // If that means calling applyDefaultMapping, fine, but this
+ // must be explicitly stated.
+ applyMappingImpl(OpdMapper);
+ }
+
/// Get the size in bits of \p Reg.
/// Utility method to get the size of any registers. Unlike
/// MachineRegisterInfo::getSize, the register does not need to be a
diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
index 02abb60e625..6bee4808406 100644
--- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
@@ -332,6 +332,33 @@ RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const {
return InstructionMappings();
}
+void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) {
+ MachineInstr &MI = OpdMapper.getMI();
+ DEBUG(dbgs() << "Applying default-like mapping\n");
+ for (unsigned OpIdx = 0, EndIdx = MI.getNumOperands(); OpIdx != EndIdx;
+ ++OpIdx) {
+ DEBUG(dbgs() << "OpIdx " << OpIdx);
+ MachineOperand &MO = MI.getOperand(OpIdx);
+ if (!MO.isReg()) {
+ DEBUG(dbgs() << " is not a register, nothing to be done\n");
+ continue;
+ }
+ assert(
+ OpdMapper.getInstrMapping().getOperandMapping(OpIdx).BreakDown.size() ==
+ 1 &&
+ "This mapping is too complex for this function");
+ iterator_range<SmallVectorImpl<unsigned>::const_iterator> NewRegs =
+ OpdMapper.getVRegs(OpIdx);
+ if (NewRegs.begin() == NewRegs.end()) {
+ DEBUG(dbgs() << " has not been repaired, nothing to be done\n");
+ continue;
+ }
+ DEBUG(dbgs() << " changed, replace " << MO.getReg());
+ MO.setReg(*NewRegs.begin());
+ DEBUG(dbgs() << " with " << MO.getReg());
+ }
+}
+
unsigned RegisterBankInfo::getSizeInBits(unsigned Reg,
const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) {
OpenPOWER on IntegriCloud