diff options
Diffstat (limited to 'lib/CodeGen/GlobalISel/RegisterBankInfo.cpp')
| -rw-r--r-- | lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 115 |
1 files changed, 79 insertions, 36 deletions
diff --git a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 28404e52d6ea9..159422e388789 100644 --- a/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -1,9 +1,8 @@ //===- llvm/CodeGen/GlobalISel/RegisterBankInfo.cpp --------------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file @@ -81,7 +80,7 @@ bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const { } const RegisterBank * -RegisterBankInfo::getRegBank(unsigned Reg, const MachineRegisterInfo &MRI, +RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const { if (TargetRegisterInfo::isPhysicalRegister(Reg)) return &getRegBankFromRegClass(getMinimalPhysRegClass(Reg, TRI)); @@ -96,7 +95,7 @@ RegisterBankInfo::getRegBank(unsigned Reg, const MachineRegisterInfo &MRI, } const TargetRegisterClass & -RegisterBankInfo::getMinimalPhysRegClass(unsigned Reg, +RegisterBankInfo::getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const { assert(TargetRegisterInfo::isPhysicalRegister(Reg) && "Reg must be a physreg"); @@ -126,7 +125,7 @@ const RegisterBank *RegisterBankInfo::getRegBankFromConstraints( } const TargetRegisterClass *RegisterBankInfo::constrainGenericRegister( - unsigned Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI) { + Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI) { // If the register already has a class, fallback to MRI::constrainRegClass. auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg); @@ -181,7 +180,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { const MachineOperand &MO = MI.getOperand(OpIdx); if (!MO.isReg()) continue; - unsigned Reg = MO.getReg(); + Register Reg = MO.getReg(); if (!Reg) continue; // The register bank of Reg is just a side effect of the current @@ -208,19 +207,49 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { continue; } } - const ValueMapping *ValMapping = - &getValueMapping(0, getSizeInBits(Reg, MRI, TRI), *CurRegBank); + + unsigned Size = getSizeInBits(Reg, MRI, TRI); + const ValueMapping *ValMapping = &getValueMapping(0, Size, *CurRegBank); if (IsCopyLike) { - OperandsMapping[0] = ValMapping; + if (!OperandsMapping[0]) { + if (MI.isRegSequence()) { + // For reg_sequence, the result size does not match the input. + unsigned ResultSize = getSizeInBits(MI.getOperand(0).getReg(), + MRI, TRI); + OperandsMapping[0] = &getValueMapping(0, ResultSize, *CurRegBank); + } else { + OperandsMapping[0] = ValMapping; + } + } + + // The default handling assumes any register bank can be copied to any + // other. If this isn't the case, the target should specially deal with + // reg_sequence/phi. There may also be unsatisfiable copies. + for (; OpIdx != EndIdx; ++OpIdx) { + const MachineOperand &MO = MI.getOperand(OpIdx); + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + + const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI); + if (AltRegBank && + cannotCopy(*CurRegBank, *AltRegBank, getSizeInBits(Reg, MRI, TRI))) + return getInvalidInstructionMapping(); + } + CompleteMapping = true; break; } + OperandsMapping[OpIdx] = ValMapping; } - if (IsCopyLike && !CompleteMapping) + if (IsCopyLike && !CompleteMapping) { // No way to deduce the type from what we have. return getInvalidInstructionMapping(); + } assert(CompleteMapping && "Setting an uncomplete mapping"); return getInstructionMapping( @@ -363,11 +392,8 @@ RegisterBankInfo::getInstructionMappingImpl( ++NumInstructionMappingsCreated; auto &InstrMapping = MapOfInstructionMappings[Hash]; - if (IsInvalid) - InstrMapping = llvm::make_unique<InstructionMapping>(); - else - InstrMapping = llvm::make_unique<InstructionMapping>( - ID, Cost, OperandsMapping, NumOperands); + InstrMapping = llvm::make_unique<InstructionMapping>( + ID, Cost, OperandsMapping, NumOperands); return *InstrMapping; } @@ -382,8 +408,12 @@ RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { RegisterBankInfo::InstructionMappings RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const { InstructionMappings PossibleMappings; - // Put the default mapping first. - PossibleMappings.push_back(&getInstrMapping(MI)); + const auto &Mapping = getInstrMapping(MI); + if (Mapping.isValid()) { + // Put the default mapping first. + PossibleMappings.push_back(&Mapping); + } + // Then the alternative mapping, if any. InstructionMappings AltMappings = getInstrAlternativeMappings(MI); for (const InstructionMapping *AltMapping : AltMappings) @@ -424,14 +454,14 @@ void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) { assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns == 1 && "This mapping is too complex for this function"); - iterator_range<SmallVectorImpl<unsigned>::const_iterator> NewRegs = + iterator_range<SmallVectorImpl<Register>::const_iterator> NewRegs = OpdMapper.getVRegs(OpIdx); if (empty(NewRegs)) { LLVM_DEBUG(dbgs() << " has not been repaired, nothing to be done\n"); continue; } - unsigned OrigReg = MO.getReg(); - unsigned NewReg = *NewRegs.begin(); + Register OrigReg = MO.getReg(); + Register NewReg = *NewRegs.begin(); LLVM_DEBUG(dbgs() << " changed, replace " << printReg(OrigReg, nullptr)); MO.setReg(NewReg); LLVM_DEBUG(dbgs() << " with " << printReg(NewReg, nullptr)); @@ -456,7 +486,7 @@ void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) { } } -unsigned RegisterBankInfo::getSizeInBits(unsigned Reg, +unsigned RegisterBankInfo::getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const { if (TargetRegisterInfo::isPhysicalRegister(Reg)) { @@ -498,6 +528,19 @@ void RegisterBankInfo::PartialMapping::print(raw_ostream &OS) const { OS << "nullptr"; } +bool RegisterBankInfo::ValueMapping::partsAllUniform() const { + if (NumBreakDowns < 2) + return true; + + const PartialMapping *First = begin(); + for (const PartialMapping *Part = First + 1; Part != end(); ++Part) { + if (Part->Length != First->Length || Part->RegBank != First->RegBank) + return false; + } + + return true; +} + bool RegisterBankInfo::ValueMapping::verify(unsigned MeaningfulBitWidth) const { assert(NumBreakDowns && "Value mapped nowhere?!"); unsigned OrigValueBitWidth = 0; @@ -565,7 +608,7 @@ bool RegisterBankInfo::InstructionMapping::verify( "We should not care about non-reg mapping"); continue; } - unsigned Reg = MO.getReg(); + Register Reg = MO.getReg(); if (!Reg) continue; assert(getOperandMapping(Idx).isValid() && @@ -610,7 +653,7 @@ RegisterBankInfo::OperandsMapper::OperandsMapper( assert(InstrMapping.verify(MI) && "Invalid mapping for MI"); } -iterator_range<SmallVectorImpl<unsigned>::iterator> +iterator_range<SmallVectorImpl<Register>::iterator> RegisterBankInfo::OperandsMapper::getVRegsMem(unsigned OpIdx) { assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); unsigned NumPartialVal = @@ -626,18 +669,18 @@ RegisterBankInfo::OperandsMapper::getVRegsMem(unsigned OpIdx) { for (unsigned i = 0; i < NumPartialVal; ++i) NewVRegs.push_back(0); } - SmallVectorImpl<unsigned>::iterator End = + SmallVectorImpl<Register>::iterator End = getNewVRegsEnd(StartIdx, NumPartialVal); return make_range(&NewVRegs[StartIdx], End); } -SmallVectorImpl<unsigned>::const_iterator +SmallVectorImpl<Register>::const_iterator RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx, unsigned NumVal) const { return const_cast<OperandsMapper *>(this)->getNewVRegsEnd(StartIdx, NumVal); } -SmallVectorImpl<unsigned>::iterator +SmallVectorImpl<Register>::iterator RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx, unsigned NumVal) { assert((NewVRegs.size() == StartIdx + NumVal || @@ -649,11 +692,11 @@ RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx, void RegisterBankInfo::OperandsMapper::createVRegs(unsigned OpIdx) { assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); - iterator_range<SmallVectorImpl<unsigned>::iterator> NewVRegsForOpIdx = + iterator_range<SmallVectorImpl<Register>::iterator> NewVRegsForOpIdx = getVRegsMem(OpIdx); const ValueMapping &ValMapping = getInstrMapping().getOperandMapping(OpIdx); const PartialMapping *PartMap = ValMapping.begin(); - for (unsigned &NewVReg : NewVRegsForOpIdx) { + for (Register &NewVReg : NewVRegsForOpIdx) { assert(PartMap != ValMapping.end() && "Out-of-bound access"); assert(NewVReg == 0 && "Register has already been created"); // The new registers are always bound to scalar with the right size. @@ -669,7 +712,7 @@ void RegisterBankInfo::OperandsMapper::createVRegs(unsigned OpIdx) { void RegisterBankInfo::OperandsMapper::setVRegs(unsigned OpIdx, unsigned PartialMapIdx, - unsigned NewVReg) { + Register NewVReg) { assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); assert(getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns > PartialMapIdx && @@ -681,7 +724,7 @@ void RegisterBankInfo::OperandsMapper::setVRegs(unsigned OpIdx, NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] = NewVReg; } -iterator_range<SmallVectorImpl<unsigned>::const_iterator> +iterator_range<SmallVectorImpl<Register>::const_iterator> RegisterBankInfo::OperandsMapper::getVRegs(unsigned OpIdx, bool ForDebug) const { (void)ForDebug; @@ -693,12 +736,12 @@ RegisterBankInfo::OperandsMapper::getVRegs(unsigned OpIdx, unsigned PartMapSize = getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns; - SmallVectorImpl<unsigned>::const_iterator End = + SmallVectorImpl<Register>::const_iterator End = getNewVRegsEnd(StartIdx, PartMapSize); - iterator_range<SmallVectorImpl<unsigned>::const_iterator> Res = + iterator_range<SmallVectorImpl<Register>::const_iterator> Res = make_range(&NewVRegs[StartIdx], End); #ifndef NDEBUG - for (unsigned VReg : Res) + for (Register VReg : Res) assert((VReg || ForDebug) && "Some registers are uninitialized"); #endif return Res; @@ -747,7 +790,7 @@ void RegisterBankInfo::OperandsMapper::print(raw_ostream &OS, IsFirst = false; OS << '(' << printReg(getMI().getOperand(Idx).getReg(), TRI) << ", ["; bool IsFirstNewVReg = true; - for (unsigned VReg : getVRegs(Idx)) { + for (Register VReg : getVRegs(Idx)) { if (!IsFirstNewVReg) OS << ", "; IsFirstNewVReg = false; |
