[llvm] r272161 - [RegisterBankInfo] Introduce OperandsMapper class.
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 8 09:18:14 PDT 2016
Author: qcolombet
Date: Wed Jun 8 11:18:13 2016
New Revision: 272161
URL: http://llvm.org/viewvc/llvm-project?rev=272161&view=rev
Log:
[RegisterBankInfo] Introduce OperandsMapper class.
This helper class is used to encapsulate the necessary information
to remap an instruction.
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h?rev=272161&r1=272160&r2=272161&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h Wed Jun 8 11:18:13 2016
@@ -188,6 +188,86 @@ public:
/// \todo When we move to TableGen this should be an array ref.
typedef SmallVector<InstructionMapping, 4> InstructionMappings;
+ /// Helper class use to get/create the virtual registers that will be used
+ /// to replace the MachineOperand when applying a mapping.
+ class OperandsMapper {
+ /// The OpIdx-th cell contains the index in NewVRegs where the VRegs of the
+ /// OpIdx-th operand starts. -1 means we do not have such mapping yet.
+ std::unique_ptr<int[]> OpToNewVRegIdx;
+ /// Hold the registers that will be used to map MI with InstrMapping.
+ SmallVector<unsigned, 8> NewVRegs;
+ /// Current MachineRegisterInfo, used to create new virtual registers.
+ MachineRegisterInfo &MRI;
+ /// Instruction being remapped.
+ MachineInstr &MI;
+ /// New mapping of the instruction.
+ const InstructionMapping &InstrMapping;
+
+ /// Constant value identifying that the index in OpToNewVRegIdx
+ /// for an operand has not been set yet.
+ static const int DontKnowIdx;
+
+ /// Get the range in NewVRegs to store all the partial
+ /// values for the \p OpIdx-th operand.
+ ///
+ /// \return The iterator range for the space created.
+ //
+ /// \pre getMI().getOperand(OpIdx).isReg()
+ iterator_range<SmallVectorImpl<unsigned>::iterator>
+ getVRegsMem(unsigned OpIdx);
+
+ public:
+ /// Create an OperandsMapper that will hold the information to apply \p
+ /// InstrMapping to \p MI.
+ /// \pre InstrMapping.verify(MI)
+ OperandsMapper(MachineInstr &MI, const InstructionMapping &InstrMapping,
+ MachineRegisterInfo &MRI);
+
+ /// Getters.
+ /// @{
+ /// The MachineInstr being remapped.
+ MachineInstr &getMI() const { return MI; }
+
+ /// The final mapping of the instruction.
+ const InstructionMapping &getInstrMapping() const { return InstrMapping; }
+ /// @}
+
+ /// Create as many new virtual registers as needed for the mapping of the \p
+ /// OpIdx-th operand.
+ /// The number of registers is determined by the number of breakdown for the
+ /// related operand in the instruction mapping.
+ ///
+ /// \pre getMI().getOperand(OpIdx).isReg()
+ ///
+ /// \post All the partial mapping of the \p OpIdx-th operand have been
+ /// assigned a new virtual register.
+ void createVRegs(unsigned OpIdx);
+
+ /// Set the virtual register of the \p PartialMapIdx-th partial mapping of
+ /// the OpIdx-th operand to \p NewVReg.
+ ///
+ /// \pre getMI().getOperand(OpIdx).isReg()
+ /// \pre getInstrMapping().getOperandMapping(OpIdx).BreakDown.size() >
+ /// PartialMapIdx
+ /// \pre NewReg != 0
+ ///
+ /// \post the \p PartialMapIdx-th register of the value mapping of the \p
+ /// OpIdx-th operand has been set.
+ void setVRegs(unsigned OpIdx, unsigned PartialMapIdx, unsigned NewVReg);
+
+ /// Get all the virtual registers required to map the \p OpIdx-th operand of
+ /// the instruction.
+ ///
+ /// This return an empty range when createVRegs or setVRegs has not been
+ /// called.
+ /// The iterator may be invalidated by a call to setVRegs or createVRegs.
+ ///
+ /// \pre getMI().getOperand(OpIdx).isReg()
+ /// \pre All partial mappings have been set a register
+ iterator_range<SmallVectorImpl<unsigned>::const_iterator>
+ getVRegs(unsigned OpIdx) const;
+ };
+
protected:
/// Hold the set of supported register banks.
std::unique_ptr<RegisterBank[]> RegBanks;
Modified: llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp?rev=272161&r1=272160&r2=272161&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp Wed Jun 8 11:18:13 2016
@@ -480,3 +480,93 @@ void RegisterBankInfo::InstructionMappin
OS << "{ Idx: " << OpIdx << " Map: " << ValMapping << '}';
}
}
+
+const int RegisterBankInfo::OperandsMapper::DontKnowIdx = -1;
+
+RegisterBankInfo::OperandsMapper::OperandsMapper(
+ MachineInstr &MI, const InstructionMapping &InstrMapping,
+ MachineRegisterInfo &MRI)
+ : MRI(MRI), MI(MI), InstrMapping(InstrMapping) {
+ unsigned NumOpds = MI.getNumOperands();
+ OpToNewVRegIdx.reset(new int[NumOpds]);
+ std::fill(&OpToNewVRegIdx[0], &OpToNewVRegIdx[NumOpds],
+ OperandsMapper::DontKnowIdx);
+ assert(InstrMapping.verify(MI) && "Invalid mapping for MI");
+}
+
+iterator_range<SmallVectorImpl<unsigned>::iterator>
+RegisterBankInfo::OperandsMapper::getVRegsMem(unsigned OpIdx) {
+ assert(OpIdx < getMI().getNumOperands() && "Out-of-bound access");
+ unsigned NumPartialVal =
+ getInstrMapping().getOperandMapping(OpIdx).BreakDown.size();
+ int StartIdx = OpToNewVRegIdx[OpIdx];
+
+ if (StartIdx == OperandsMapper::DontKnowIdx) {
+ // This is the first time we try to access OpIdx.
+ // Create the cells that will hold all the partial values at the
+ // end of the list of NewVReg.
+ StartIdx = NewVRegs.size();
+ OpToNewVRegIdx[OpIdx] = StartIdx;
+ for (unsigned i = 0; i < NumPartialVal; ++i)
+ NewVRegs.push_back(0);
+ }
+ SmallVectorImpl<unsigned>::iterator End =
+ NewVRegs.size() <= StartIdx + NumPartialVal + 1
+ ? NewVRegs.end()
+ : &NewVRegs[StartIdx + NumPartialVal + 1];
+
+ return make_range(&NewVRegs[StartIdx], End);
+}
+
+void RegisterBankInfo::OperandsMapper::createVRegs(unsigned OpIdx) {
+ assert(OpIdx < getMI().getNumOperands() && "Out-of-bound access");
+ iterator_range<SmallVectorImpl<unsigned>::iterator> NewVRegsForOpIdx =
+ getVRegsMem(OpIdx);
+ const SmallVectorImpl<PartialMapping> &PartMapList =
+ getInstrMapping().getOperandMapping(OpIdx).BreakDown;
+ SmallVectorImpl<PartialMapping>::const_iterator PartMap = PartMapList.begin();
+ for (unsigned &NewVReg : NewVRegsForOpIdx) {
+ assert(PartMap != PartMapList.end() && "Out-of-bound access");
+ assert(NewVReg == 0 && "Register has already been created");
+ NewVReg = MRI.createGenericVirtualRegister(PartMap->Length);
+ MRI.setRegBank(NewVReg, *PartMap->RegBank);
+ ++PartMap;
+ }
+}
+
+void RegisterBankInfo::OperandsMapper::setVRegs(unsigned OpIdx,
+ unsigned PartialMapIdx,
+ unsigned NewVReg) {
+ assert(OpIdx < getMI().getNumOperands() && "Out-of-bound access");
+ assert(getInstrMapping().getOperandMapping(OpIdx).BreakDown.size() >
+ PartialMapIdx &&
+ "Out-of-bound access for partial mapping");
+ // Make sure the memory is initialized for that operand.
+ (void)getVRegsMem(OpIdx);
+ assert(NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] == 0 &&
+ "This value is already set");
+ NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] = NewVReg;
+}
+
+iterator_range<SmallVectorImpl<unsigned>::const_iterator>
+RegisterBankInfo::OperandsMapper::getVRegs(unsigned OpIdx) const {
+ assert(OpIdx < getMI().getNumOperands() && "Out-of-bound access");
+ int StartIdx = OpToNewVRegIdx[OpIdx];
+
+ if (StartIdx == OperandsMapper::DontKnowIdx)
+ return make_range(NewVRegs.end(), NewVRegs.end());
+
+ unsigned PartMapSize =
+ getInstrMapping().getOperandMapping(OpIdx).BreakDown.size();
+ SmallVectorImpl<unsigned>::const_iterator End =
+ NewVRegs.size() <= StartIdx + PartMapSize + 1
+ ? NewVRegs.end()
+ : &NewVRegs[StartIdx + PartMapSize + 1];
+ iterator_range<SmallVectorImpl<unsigned>::const_iterator> Res =
+ make_range(&NewVRegs[StartIdx], End);
+#ifndef NDEBUG
+ for (unsigned VReg : Res)
+ assert(VReg && "Some registers are uninitialized");
+#endif
+ return Res;
+}
More information about the llvm-commits
mailing list