1c62eefb8SMircea Trofin //===- llvm/CodeGen/GlobalISel/RegisterBankInfo.cpp --------------*- C++ -*-==// 2c62eefb8SMircea Trofin // 3c62eefb8SMircea Trofin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4c62eefb8SMircea Trofin // See https://llvm.org/LICENSE.txt for license information. 5c62eefb8SMircea Trofin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c62eefb8SMircea Trofin // 7c62eefb8SMircea Trofin //===----------------------------------------------------------------------===// 8c62eefb8SMircea Trofin /// \file 9c62eefb8SMircea Trofin /// This file implements the RegisterBankInfo class. 10c62eefb8SMircea Trofin //===----------------------------------------------------------------------===// 11c62eefb8SMircea Trofin 12cb216076SMircea Trofin #include "llvm/CodeGen/RegisterBankInfo.h" 13b0abd489SElliot Goodrich #include "llvm/ADT/APInt.h" 14c62eefb8SMircea Trofin #include "llvm/ADT/SmallVector.h" 15c62eefb8SMircea Trofin #include "llvm/ADT/Statistic.h" 16c62eefb8SMircea Trofin #include "llvm/ADT/iterator_range.h" 17c62eefb8SMircea Trofin #include "llvm/CodeGen/MachineFunction.h" 18c62eefb8SMircea Trofin #include "llvm/CodeGen/MachineRegisterInfo.h" 19cb216076SMircea Trofin #include "llvm/CodeGen/RegisterBank.h" 20c62eefb8SMircea Trofin #include "llvm/CodeGen/TargetOpcodes.h" 21c62eefb8SMircea Trofin #include "llvm/CodeGen/TargetRegisterInfo.h" 22c62eefb8SMircea Trofin #include "llvm/CodeGen/TargetSubtargetInfo.h" 23c62eefb8SMircea Trofin #include "llvm/Config/llvm-config.h" 24c62eefb8SMircea Trofin #include "llvm/Support/Debug.h" 25c62eefb8SMircea Trofin #include "llvm/Support/raw_ostream.h" 26c62eefb8SMircea Trofin 27c62eefb8SMircea Trofin #include <algorithm> // For std::max. 28c62eefb8SMircea Trofin 29c62eefb8SMircea Trofin #define DEBUG_TYPE "registerbankinfo" 30c62eefb8SMircea Trofin 31c62eefb8SMircea Trofin using namespace llvm; 32c62eefb8SMircea Trofin 33c62eefb8SMircea Trofin STATISTIC(NumPartialMappingsCreated, 34c62eefb8SMircea Trofin "Number of partial mappings dynamically created"); 35c62eefb8SMircea Trofin STATISTIC(NumPartialMappingsAccessed, 36c62eefb8SMircea Trofin "Number of partial mappings dynamically accessed"); 37c62eefb8SMircea Trofin STATISTIC(NumValueMappingsCreated, 38c62eefb8SMircea Trofin "Number of value mappings dynamically created"); 39c62eefb8SMircea Trofin STATISTIC(NumValueMappingsAccessed, 40c62eefb8SMircea Trofin "Number of value mappings dynamically accessed"); 41c62eefb8SMircea Trofin STATISTIC(NumOperandsMappingsCreated, 42c62eefb8SMircea Trofin "Number of operands mappings dynamically created"); 43c62eefb8SMircea Trofin STATISTIC(NumOperandsMappingsAccessed, 44c62eefb8SMircea Trofin "Number of operands mappings dynamically accessed"); 45c62eefb8SMircea Trofin STATISTIC(NumInstructionMappingsCreated, 46c62eefb8SMircea Trofin "Number of instruction mappings dynamically created"); 47c62eefb8SMircea Trofin STATISTIC(NumInstructionMappingsAccessed, 48c62eefb8SMircea Trofin "Number of instruction mappings dynamically accessed"); 49c62eefb8SMircea Trofin 50c62eefb8SMircea Trofin const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX; 51c62eefb8SMircea Trofin const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1; 52c62eefb8SMircea Trofin 53c62eefb8SMircea Trofin //------------------------------------------------------------------------------ 54c62eefb8SMircea Trofin // RegisterBankInfo implementation. 55c62eefb8SMircea Trofin //------------------------------------------------------------------------------ 56aa7eace8SNitin John Raj RegisterBankInfo::RegisterBankInfo(const RegisterBank **RegBanks, 57aa7eace8SNitin John Raj unsigned NumRegBanks, const unsigned *Sizes, 58aa7eace8SNitin John Raj unsigned HwMode) 59aa7eace8SNitin John Raj : RegBanks(RegBanks), NumRegBanks(NumRegBanks), Sizes(Sizes), 60aa7eace8SNitin John Raj HwMode(HwMode) { 61c62eefb8SMircea Trofin #ifndef NDEBUG 62c62eefb8SMircea Trofin for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) { 63c62eefb8SMircea Trofin assert(RegBanks[Idx] != nullptr && "Invalid RegisterBank"); 64d22d42ceSCraig Topper assert(RegBanks[Idx]->getID() == Idx && 65d22d42ceSCraig Topper "RegisterBank ID should match index"); 66c62eefb8SMircea Trofin } 67c62eefb8SMircea Trofin #endif // NDEBUG 68c62eefb8SMircea Trofin } 69c62eefb8SMircea Trofin 70c62eefb8SMircea Trofin bool RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const { 71c62eefb8SMircea Trofin #ifndef NDEBUG 72c62eefb8SMircea Trofin for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) { 73c62eefb8SMircea Trofin const RegisterBank &RegBank = getRegBank(Idx); 74c62eefb8SMircea Trofin assert(Idx == RegBank.getID() && 75c62eefb8SMircea Trofin "ID does not match the index in the array"); 76c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << "Verify " << RegBank << '\n'); 77aa7eace8SNitin John Raj assert(RegBank.verify(*this, TRI) && "RegBank is invalid"); 78c62eefb8SMircea Trofin } 79c62eefb8SMircea Trofin #endif // NDEBUG 80c62eefb8SMircea Trofin return true; 81c62eefb8SMircea Trofin } 82c62eefb8SMircea Trofin 83c62eefb8SMircea Trofin const RegisterBank * 84c62eefb8SMircea Trofin RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI, 85c62eefb8SMircea Trofin const TargetRegisterInfo &TRI) const { 86490e348eSMatt Arsenault if (!Reg.isVirtual()) { 87c62eefb8SMircea Trofin // FIXME: This was probably a copy to a virtual register that does have a 88c62eefb8SMircea Trofin // type we could use. 89490e348eSMatt Arsenault const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, TRI); 90490e348eSMatt Arsenault return RC ? &getRegBankFromRegClass(*RC, LLT()) : nullptr; 91c62eefb8SMircea Trofin } 92c62eefb8SMircea Trofin 93c62eefb8SMircea Trofin const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg); 947021182dSShraiysh Vaishay if (auto *RB = dyn_cast_if_present<const RegisterBank *>(RegClassOrBank)) 95c62eefb8SMircea Trofin return RB; 967021182dSShraiysh Vaishay if (auto *RC = 977021182dSShraiysh Vaishay dyn_cast_if_present<const TargetRegisterClass *>(RegClassOrBank)) 98c62eefb8SMircea Trofin return &getRegBankFromRegClass(*RC, MRI.getType(Reg)); 99c62eefb8SMircea Trofin return nullptr; 100c62eefb8SMircea Trofin } 101c62eefb8SMircea Trofin 102490e348eSMatt Arsenault const TargetRegisterClass * 103c62eefb8SMircea Trofin RegisterBankInfo::getMinimalPhysRegClass(Register Reg, 104c62eefb8SMircea Trofin const TargetRegisterInfo &TRI) const { 105e72ca520SCraig Topper assert(Reg.isPhysical() && "Reg must be a physreg"); 106bea28037SKazu Hirata const auto [RegRCIt, Inserted] = PhysRegMinimalRCs.try_emplace(Reg); 107bea28037SKazu Hirata if (Inserted) 108bea28037SKazu Hirata RegRCIt->second = TRI.getMinimalPhysRegClassLLT(Reg, LLT()); 109490e348eSMatt Arsenault return RegRCIt->second; 110c62eefb8SMircea Trofin } 111c62eefb8SMircea Trofin 112c62eefb8SMircea Trofin const RegisterBank *RegisterBankInfo::getRegBankFromConstraints( 113c62eefb8SMircea Trofin const MachineInstr &MI, unsigned OpIdx, const TargetInstrInfo &TII, 114c62eefb8SMircea Trofin const MachineRegisterInfo &MRI) const { 115c62eefb8SMircea Trofin const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); 116c62eefb8SMircea Trofin 117c62eefb8SMircea Trofin // The mapping of the registers may be available via the 118c62eefb8SMircea Trofin // register class constraints. 119c62eefb8SMircea Trofin const TargetRegisterClass *RC = MI.getRegClassConstraint(OpIdx, &TII, TRI); 120c62eefb8SMircea Trofin 121c62eefb8SMircea Trofin if (!RC) 122c62eefb8SMircea Trofin return nullptr; 123c62eefb8SMircea Trofin 124c62eefb8SMircea Trofin Register Reg = MI.getOperand(OpIdx).getReg(); 125c62eefb8SMircea Trofin const RegisterBank &RegBank = getRegBankFromRegClass(*RC, MRI.getType(Reg)); 126c62eefb8SMircea Trofin // Check that the target properly implemented getRegBankFromRegClass. 127c62eefb8SMircea Trofin assert(RegBank.covers(*RC) && 128c62eefb8SMircea Trofin "The mapping of the register bank does not make sense"); 129c62eefb8SMircea Trofin return &RegBank; 130c62eefb8SMircea Trofin } 131c62eefb8SMircea Trofin 132c62eefb8SMircea Trofin const TargetRegisterClass *RegisterBankInfo::constrainGenericRegister( 133c62eefb8SMircea Trofin Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI) { 134c62eefb8SMircea Trofin 135c62eefb8SMircea Trofin // If the register already has a class, fallback to MRI::constrainRegClass. 136c62eefb8SMircea Trofin auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg); 137*a475ae05SSergei Barannikov if (isa<const TargetRegisterClass *>(RegClassOrBank)) 138c62eefb8SMircea Trofin return MRI.constrainRegClass(Reg, &RC); 139c62eefb8SMircea Trofin 140*a475ae05SSergei Barannikov const RegisterBank *RB = cast<const RegisterBank *>(RegClassOrBank); 141c62eefb8SMircea Trofin // Otherwise, all we can do is ensure the bank covers the class, and set it. 142c62eefb8SMircea Trofin if (RB && !RB->covers(RC)) 143c62eefb8SMircea Trofin return nullptr; 144c62eefb8SMircea Trofin 145c62eefb8SMircea Trofin // If nothing was set or the class is simply compatible, set it. 146c62eefb8SMircea Trofin MRI.setRegClass(Reg, &RC); 147c62eefb8SMircea Trofin return &RC; 148c62eefb8SMircea Trofin } 149c62eefb8SMircea Trofin 150c62eefb8SMircea Trofin /// Check whether or not \p MI should be treated like a copy 151c62eefb8SMircea Trofin /// for the mappings. 152c62eefb8SMircea Trofin /// Copy like instruction are special for mapping because 153c62eefb8SMircea Trofin /// they don't have actual register constraints. Moreover, 154c62eefb8SMircea Trofin /// they sometimes have register classes assigned and we can 155c62eefb8SMircea Trofin /// just use that instead of failing to provide a generic mapping. 156c62eefb8SMircea Trofin static bool isCopyLike(const MachineInstr &MI) { 157c62eefb8SMircea Trofin return MI.isCopy() || MI.isPHI() || 158c62eefb8SMircea Trofin MI.getOpcode() == TargetOpcode::REG_SEQUENCE; 159c62eefb8SMircea Trofin } 160c62eefb8SMircea Trofin 161c62eefb8SMircea Trofin const RegisterBankInfo::InstructionMapping & 162c62eefb8SMircea Trofin RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { 163c62eefb8SMircea Trofin // For copies we want to walk over the operands and try to find one 164c62eefb8SMircea Trofin // that has a register bank since the instruction itself will not get 165c62eefb8SMircea Trofin // us any constraint. 166c62eefb8SMircea Trofin bool IsCopyLike = isCopyLike(MI); 167c62eefb8SMircea Trofin // For copy like instruction, only the mapping of the definition 168c62eefb8SMircea Trofin // is important. The rest is not constrained. 169c62eefb8SMircea Trofin unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands(); 170c62eefb8SMircea Trofin 171c62eefb8SMircea Trofin const MachineFunction &MF = *MI.getMF(); 172c62eefb8SMircea Trofin const TargetSubtargetInfo &STI = MF.getSubtarget(); 173c62eefb8SMircea Trofin const TargetRegisterInfo &TRI = *STI.getRegisterInfo(); 174c62eefb8SMircea Trofin const MachineRegisterInfo &MRI = MF.getRegInfo(); 175c62eefb8SMircea Trofin // We may need to query the instruction encoding to guess the mapping. 176c62eefb8SMircea Trofin const TargetInstrInfo &TII = *STI.getInstrInfo(); 177c62eefb8SMircea Trofin 178c62eefb8SMircea Trofin // Before doing anything complicated check if the mapping is not 179c62eefb8SMircea Trofin // directly available. 180c62eefb8SMircea Trofin bool CompleteMapping = true; 181c62eefb8SMircea Trofin 182c62eefb8SMircea Trofin SmallVector<const ValueMapping *, 8> OperandsMapping(NumOperandsForMapping); 183c62eefb8SMircea Trofin for (unsigned OpIdx = 0, EndIdx = MI.getNumOperands(); OpIdx != EndIdx; 184c62eefb8SMircea Trofin ++OpIdx) { 185c62eefb8SMircea Trofin const MachineOperand &MO = MI.getOperand(OpIdx); 186c62eefb8SMircea Trofin if (!MO.isReg()) 187c62eefb8SMircea Trofin continue; 188c62eefb8SMircea Trofin Register Reg = MO.getReg(); 189c62eefb8SMircea Trofin if (!Reg) 190c62eefb8SMircea Trofin continue; 191c62eefb8SMircea Trofin // The register bank of Reg is just a side effect of the current 192c62eefb8SMircea Trofin // excution and in particular, there is no reason to believe this 193c62eefb8SMircea Trofin // is the best default mapping for the current instruction. Keep 194c62eefb8SMircea Trofin // it as an alternative register bank if we cannot figure out 195c62eefb8SMircea Trofin // something. 196c62eefb8SMircea Trofin const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI); 197c62eefb8SMircea Trofin // For copy-like instruction, we want to reuse the register bank 198c62eefb8SMircea Trofin // that is already set on Reg, if any, since those instructions do 199c62eefb8SMircea Trofin // not have any constraints. 200c62eefb8SMircea Trofin const RegisterBank *CurRegBank = IsCopyLike ? AltRegBank : nullptr; 201c62eefb8SMircea Trofin if (!CurRegBank) { 202c62eefb8SMircea Trofin // If this is a target specific instruction, we can deduce 203c62eefb8SMircea Trofin // the register bank from the encoding constraints. 204c62eefb8SMircea Trofin CurRegBank = getRegBankFromConstraints(MI, OpIdx, TII, MRI); 205c62eefb8SMircea Trofin if (!CurRegBank) { 206c62eefb8SMircea Trofin // All our attempts failed, give up. 207c62eefb8SMircea Trofin CompleteMapping = false; 208c62eefb8SMircea Trofin 209c62eefb8SMircea Trofin if (!IsCopyLike) 210c62eefb8SMircea Trofin // MI does not carry enough information to guess the mapping. 211c62eefb8SMircea Trofin return getInvalidInstructionMapping(); 212c62eefb8SMircea Trofin continue; 213c62eefb8SMircea Trofin } 214c62eefb8SMircea Trofin } 215c62eefb8SMircea Trofin 2161c66ef91SJiahan Xie TypeSize Size = getSizeInBits(Reg, MRI, TRI); 2171c66ef91SJiahan Xie const ValueMapping *ValMapping = 2181c66ef91SJiahan Xie &getValueMapping(0, Size.getKnownMinValue(), *CurRegBank); 219c62eefb8SMircea Trofin if (IsCopyLike) { 220c62eefb8SMircea Trofin if (!OperandsMapping[0]) { 221c62eefb8SMircea Trofin if (MI.isRegSequence()) { 222c62eefb8SMircea Trofin // For reg_sequence, the result size does not match the input. 223c62eefb8SMircea Trofin unsigned ResultSize = getSizeInBits(MI.getOperand(0).getReg(), 224c62eefb8SMircea Trofin MRI, TRI); 225c62eefb8SMircea Trofin OperandsMapping[0] = &getValueMapping(0, ResultSize, *CurRegBank); 226c62eefb8SMircea Trofin } else { 227c62eefb8SMircea Trofin OperandsMapping[0] = ValMapping; 228c62eefb8SMircea Trofin } 229c62eefb8SMircea Trofin } 230c62eefb8SMircea Trofin 231c62eefb8SMircea Trofin // The default handling assumes any register bank can be copied to any 232c62eefb8SMircea Trofin // other. If this isn't the case, the target should specially deal with 233c62eefb8SMircea Trofin // reg_sequence/phi. There may also be unsatisfiable copies. 234c62eefb8SMircea Trofin for (; OpIdx != EndIdx; ++OpIdx) { 235c62eefb8SMircea Trofin const MachineOperand &MO = MI.getOperand(OpIdx); 236c62eefb8SMircea Trofin if (!MO.isReg()) 237c62eefb8SMircea Trofin continue; 238c62eefb8SMircea Trofin Register Reg = MO.getReg(); 239c62eefb8SMircea Trofin if (!Reg) 240c62eefb8SMircea Trofin continue; 241c62eefb8SMircea Trofin 242c62eefb8SMircea Trofin const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI); 243c62eefb8SMircea Trofin if (AltRegBank && 244c62eefb8SMircea Trofin cannotCopy(*CurRegBank, *AltRegBank, getSizeInBits(Reg, MRI, TRI))) 245c62eefb8SMircea Trofin return getInvalidInstructionMapping(); 246c62eefb8SMircea Trofin } 247c62eefb8SMircea Trofin 248c62eefb8SMircea Trofin CompleteMapping = true; 249c62eefb8SMircea Trofin break; 250c62eefb8SMircea Trofin } 251c62eefb8SMircea Trofin 252c62eefb8SMircea Trofin OperandsMapping[OpIdx] = ValMapping; 253c62eefb8SMircea Trofin } 254c62eefb8SMircea Trofin 255c62eefb8SMircea Trofin if (IsCopyLike && !CompleteMapping) { 256c62eefb8SMircea Trofin // No way to deduce the type from what we have. 257c62eefb8SMircea Trofin return getInvalidInstructionMapping(); 258c62eefb8SMircea Trofin } 259c62eefb8SMircea Trofin 260c62eefb8SMircea Trofin assert(CompleteMapping && "Setting an uncomplete mapping"); 261c62eefb8SMircea Trofin return getInstructionMapping( 262c62eefb8SMircea Trofin DefaultMappingID, /*Cost*/ 1, 263c62eefb8SMircea Trofin /*OperandsMapping*/ getOperandsMapping(OperandsMapping), 264c62eefb8SMircea Trofin NumOperandsForMapping); 265c62eefb8SMircea Trofin } 266c62eefb8SMircea Trofin 267c62eefb8SMircea Trofin /// Hashing function for PartialMapping. 268c62eefb8SMircea Trofin static hash_code hashPartialMapping(unsigned StartIdx, unsigned Length, 269c62eefb8SMircea Trofin const RegisterBank *RegBank) { 270c62eefb8SMircea Trofin return hash_combine(StartIdx, Length, RegBank ? RegBank->getID() : 0); 271c62eefb8SMircea Trofin } 272c62eefb8SMircea Trofin 273c62eefb8SMircea Trofin /// Overloaded version of hash_value for a PartialMapping. 274c62eefb8SMircea Trofin hash_code 275c62eefb8SMircea Trofin llvm::hash_value(const RegisterBankInfo::PartialMapping &PartMapping) { 276c62eefb8SMircea Trofin return hashPartialMapping(PartMapping.StartIdx, PartMapping.Length, 277c62eefb8SMircea Trofin PartMapping.RegBank); 278c62eefb8SMircea Trofin } 279c62eefb8SMircea Trofin 280c62eefb8SMircea Trofin const RegisterBankInfo::PartialMapping & 281c62eefb8SMircea Trofin RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length, 282c62eefb8SMircea Trofin const RegisterBank &RegBank) const { 283c62eefb8SMircea Trofin ++NumPartialMappingsAccessed; 284c62eefb8SMircea Trofin 285c62eefb8SMircea Trofin hash_code Hash = hashPartialMapping(StartIdx, Length, &RegBank); 286c62eefb8SMircea Trofin const auto &It = MapOfPartialMappings.find(Hash); 287c62eefb8SMircea Trofin if (It != MapOfPartialMappings.end()) 288c62eefb8SMircea Trofin return *It->second; 289c62eefb8SMircea Trofin 290c62eefb8SMircea Trofin ++NumPartialMappingsCreated; 291c62eefb8SMircea Trofin 292c62eefb8SMircea Trofin auto &PartMapping = MapOfPartialMappings[Hash]; 293c62eefb8SMircea Trofin PartMapping = std::make_unique<PartialMapping>(StartIdx, Length, RegBank); 294c62eefb8SMircea Trofin return *PartMapping; 295c62eefb8SMircea Trofin } 296c62eefb8SMircea Trofin 297c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping & 298c62eefb8SMircea Trofin RegisterBankInfo::getValueMapping(unsigned StartIdx, unsigned Length, 299c62eefb8SMircea Trofin const RegisterBank &RegBank) const { 300c62eefb8SMircea Trofin return getValueMapping(&getPartialMapping(StartIdx, Length, RegBank), 1); 301c62eefb8SMircea Trofin } 302c62eefb8SMircea Trofin 303c62eefb8SMircea Trofin static hash_code 304c62eefb8SMircea Trofin hashValueMapping(const RegisterBankInfo::PartialMapping *BreakDown, 305c62eefb8SMircea Trofin unsigned NumBreakDowns) { 306c62eefb8SMircea Trofin if (LLVM_LIKELY(NumBreakDowns == 1)) 307c62eefb8SMircea Trofin return hash_value(*BreakDown); 308c62eefb8SMircea Trofin SmallVector<size_t, 8> Hashes(NumBreakDowns); 309c62eefb8SMircea Trofin for (unsigned Idx = 0; Idx != NumBreakDowns; ++Idx) 310c62eefb8SMircea Trofin Hashes.push_back(hash_value(BreakDown[Idx])); 311c62eefb8SMircea Trofin return hash_combine_range(Hashes.begin(), Hashes.end()); 312c62eefb8SMircea Trofin } 313c62eefb8SMircea Trofin 314c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping & 315c62eefb8SMircea Trofin RegisterBankInfo::getValueMapping(const PartialMapping *BreakDown, 316c62eefb8SMircea Trofin unsigned NumBreakDowns) const { 317c62eefb8SMircea Trofin ++NumValueMappingsAccessed; 318c62eefb8SMircea Trofin 319c62eefb8SMircea Trofin hash_code Hash = hashValueMapping(BreakDown, NumBreakDowns); 320c62eefb8SMircea Trofin const auto &It = MapOfValueMappings.find(Hash); 321c62eefb8SMircea Trofin if (It != MapOfValueMappings.end()) 322c62eefb8SMircea Trofin return *It->second; 323c62eefb8SMircea Trofin 324c62eefb8SMircea Trofin ++NumValueMappingsCreated; 325c62eefb8SMircea Trofin 326c62eefb8SMircea Trofin auto &ValMapping = MapOfValueMappings[Hash]; 327c62eefb8SMircea Trofin ValMapping = std::make_unique<ValueMapping>(BreakDown, NumBreakDowns); 328c62eefb8SMircea Trofin return *ValMapping; 329c62eefb8SMircea Trofin } 330c62eefb8SMircea Trofin 331c62eefb8SMircea Trofin template <typename Iterator> 332c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping * 333c62eefb8SMircea Trofin RegisterBankInfo::getOperandsMapping(Iterator Begin, Iterator End) const { 334c62eefb8SMircea Trofin 335c62eefb8SMircea Trofin ++NumOperandsMappingsAccessed; 336c62eefb8SMircea Trofin 337c62eefb8SMircea Trofin // The addresses of the value mapping are unique. 338c62eefb8SMircea Trofin // Therefore, we can use them directly to hash the operand mapping. 339c62eefb8SMircea Trofin hash_code Hash = hash_combine_range(Begin, End); 340c62eefb8SMircea Trofin auto &Res = MapOfOperandsMappings[Hash]; 341c62eefb8SMircea Trofin if (Res) 342c62eefb8SMircea Trofin return Res.get(); 343c62eefb8SMircea Trofin 344c62eefb8SMircea Trofin ++NumOperandsMappingsCreated; 345c62eefb8SMircea Trofin 346c62eefb8SMircea Trofin // Create the array of ValueMapping. 347c62eefb8SMircea Trofin // Note: this array will not hash to this instance of operands 348c62eefb8SMircea Trofin // mapping, because we use the pointer of the ValueMapping 349c62eefb8SMircea Trofin // to hash and we expect them to uniquely identify an instance 350c62eefb8SMircea Trofin // of value mapping. 351c62eefb8SMircea Trofin Res = std::make_unique<ValueMapping[]>(std::distance(Begin, End)); 352c62eefb8SMircea Trofin unsigned Idx = 0; 353c62eefb8SMircea Trofin for (Iterator It = Begin; It != End; ++It, ++Idx) { 354c62eefb8SMircea Trofin const ValueMapping *ValMap = *It; 355c62eefb8SMircea Trofin if (!ValMap) 356c62eefb8SMircea Trofin continue; 357c62eefb8SMircea Trofin Res[Idx] = *ValMap; 358c62eefb8SMircea Trofin } 359c62eefb8SMircea Trofin return Res.get(); 360c62eefb8SMircea Trofin } 361c62eefb8SMircea Trofin 362c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping *RegisterBankInfo::getOperandsMapping( 363c62eefb8SMircea Trofin const SmallVectorImpl<const RegisterBankInfo::ValueMapping *> &OpdsMapping) 364c62eefb8SMircea Trofin const { 365c62eefb8SMircea Trofin return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end()); 366c62eefb8SMircea Trofin } 367c62eefb8SMircea Trofin 368c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping *RegisterBankInfo::getOperandsMapping( 369c62eefb8SMircea Trofin std::initializer_list<const RegisterBankInfo::ValueMapping *> OpdsMapping) 370c62eefb8SMircea Trofin const { 371c62eefb8SMircea Trofin return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end()); 372c62eefb8SMircea Trofin } 373c62eefb8SMircea Trofin 374c62eefb8SMircea Trofin static hash_code 375c62eefb8SMircea Trofin hashInstructionMapping(unsigned ID, unsigned Cost, 376c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping *OperandsMapping, 377c62eefb8SMircea Trofin unsigned NumOperands) { 378c62eefb8SMircea Trofin return hash_combine(ID, Cost, OperandsMapping, NumOperands); 379c62eefb8SMircea Trofin } 380c62eefb8SMircea Trofin 381c62eefb8SMircea Trofin const RegisterBankInfo::InstructionMapping & 382c62eefb8SMircea Trofin RegisterBankInfo::getInstructionMappingImpl( 383c62eefb8SMircea Trofin bool IsInvalid, unsigned ID, unsigned Cost, 384c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping *OperandsMapping, 385c62eefb8SMircea Trofin unsigned NumOperands) const { 386c62eefb8SMircea Trofin assert(((IsInvalid && ID == InvalidMappingID && Cost == 0 && 387c62eefb8SMircea Trofin OperandsMapping == nullptr && NumOperands == 0) || 388c62eefb8SMircea Trofin !IsInvalid) && 389c62eefb8SMircea Trofin "Mismatch argument for invalid input"); 390c62eefb8SMircea Trofin ++NumInstructionMappingsAccessed; 391c62eefb8SMircea Trofin 392c62eefb8SMircea Trofin hash_code Hash = 393c62eefb8SMircea Trofin hashInstructionMapping(ID, Cost, OperandsMapping, NumOperands); 394c62eefb8SMircea Trofin const auto &It = MapOfInstructionMappings.find(Hash); 395c62eefb8SMircea Trofin if (It != MapOfInstructionMappings.end()) 396c62eefb8SMircea Trofin return *It->second; 397c62eefb8SMircea Trofin 398c62eefb8SMircea Trofin ++NumInstructionMappingsCreated; 399c62eefb8SMircea Trofin 400c62eefb8SMircea Trofin auto &InstrMapping = MapOfInstructionMappings[Hash]; 401c62eefb8SMircea Trofin InstrMapping = std::make_unique<InstructionMapping>( 402c62eefb8SMircea Trofin ID, Cost, OperandsMapping, NumOperands); 403c62eefb8SMircea Trofin return *InstrMapping; 404c62eefb8SMircea Trofin } 405c62eefb8SMircea Trofin 406c62eefb8SMircea Trofin const RegisterBankInfo::InstructionMapping & 407c62eefb8SMircea Trofin RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 408c62eefb8SMircea Trofin const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 409c62eefb8SMircea Trofin if (Mapping.isValid()) 410c62eefb8SMircea Trofin return Mapping; 411c62eefb8SMircea Trofin llvm_unreachable("The target must implement this"); 412c62eefb8SMircea Trofin } 413c62eefb8SMircea Trofin 414c62eefb8SMircea Trofin RegisterBankInfo::InstructionMappings 415c62eefb8SMircea Trofin RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const { 416c62eefb8SMircea Trofin InstructionMappings PossibleMappings; 417c62eefb8SMircea Trofin const auto &Mapping = getInstrMapping(MI); 418c62eefb8SMircea Trofin if (Mapping.isValid()) { 419c62eefb8SMircea Trofin // Put the default mapping first. 420c62eefb8SMircea Trofin PossibleMappings.push_back(&Mapping); 421c62eefb8SMircea Trofin } 422c62eefb8SMircea Trofin 423c62eefb8SMircea Trofin // Then the alternative mapping, if any. 424c62eefb8SMircea Trofin InstructionMappings AltMappings = getInstrAlternativeMappings(MI); 425c62eefb8SMircea Trofin append_range(PossibleMappings, AltMappings); 426c62eefb8SMircea Trofin #ifndef NDEBUG 427c62eefb8SMircea Trofin for (const InstructionMapping *Mapping : PossibleMappings) 428c62eefb8SMircea Trofin assert(Mapping->verify(MI) && "Mapping is invalid"); 429c62eefb8SMircea Trofin #endif 430c62eefb8SMircea Trofin return PossibleMappings; 431c62eefb8SMircea Trofin } 432c62eefb8SMircea Trofin 433c62eefb8SMircea Trofin RegisterBankInfo::InstructionMappings 434c62eefb8SMircea Trofin RegisterBankInfo::getInstrAlternativeMappings(const MachineInstr &MI) const { 435c62eefb8SMircea Trofin // No alternative for MI. 436c62eefb8SMircea Trofin return InstructionMappings(); 437c62eefb8SMircea Trofin } 438c62eefb8SMircea Trofin 439c62eefb8SMircea Trofin void RegisterBankInfo::applyDefaultMapping(const OperandsMapper &OpdMapper) { 440c62eefb8SMircea Trofin MachineInstr &MI = OpdMapper.getMI(); 441c62eefb8SMircea Trofin MachineRegisterInfo &MRI = OpdMapper.getMRI(); 442c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << "Applying default-like mapping\n"); 443c62eefb8SMircea Trofin for (unsigned OpIdx = 0, 444c62eefb8SMircea Trofin EndIdx = OpdMapper.getInstrMapping().getNumOperands(); 445c62eefb8SMircea Trofin OpIdx != EndIdx; ++OpIdx) { 446c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << "OpIdx " << OpIdx); 447c62eefb8SMircea Trofin MachineOperand &MO = MI.getOperand(OpIdx); 448c62eefb8SMircea Trofin if (!MO.isReg()) { 449c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << " is not a register, nothing to be done\n"); 450c62eefb8SMircea Trofin continue; 451c62eefb8SMircea Trofin } 452c62eefb8SMircea Trofin if (!MO.getReg()) { 453c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << " is $noreg, nothing to be done\n"); 454c62eefb8SMircea Trofin continue; 455c62eefb8SMircea Trofin } 456aaf6c7b0SLuo, Yuanke LLT Ty = MRI.getType(MO.getReg()); 457aaf6c7b0SLuo, Yuanke if (!Ty.isValid()) 458aaf6c7b0SLuo, Yuanke continue; 459c62eefb8SMircea Trofin assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns != 460c62eefb8SMircea Trofin 0 && 461c62eefb8SMircea Trofin "Invalid mapping"); 462c62eefb8SMircea Trofin assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns == 463c62eefb8SMircea Trofin 1 && 464c62eefb8SMircea Trofin "This mapping is too complex for this function"); 465c62eefb8SMircea Trofin iterator_range<SmallVectorImpl<Register>::const_iterator> NewRegs = 466c62eefb8SMircea Trofin OpdMapper.getVRegs(OpIdx); 467c62eefb8SMircea Trofin if (NewRegs.empty()) { 468c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << " has not been repaired, nothing to be done\n"); 469c62eefb8SMircea Trofin continue; 470c62eefb8SMircea Trofin } 471c62eefb8SMircea Trofin Register OrigReg = MO.getReg(); 472c62eefb8SMircea Trofin Register NewReg = *NewRegs.begin(); 473c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << " changed, replace " << printReg(OrigReg, nullptr)); 474c62eefb8SMircea Trofin MO.setReg(NewReg); 475c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << " with " << printReg(NewReg, nullptr)); 476c62eefb8SMircea Trofin 477c62eefb8SMircea Trofin // The OperandsMapper creates plain scalar, we may have to fix that. 478c62eefb8SMircea Trofin // Check if the types match and if not, fix that. 479c62eefb8SMircea Trofin LLT OrigTy = MRI.getType(OrigReg); 480c62eefb8SMircea Trofin LLT NewTy = MRI.getType(NewReg); 481c62eefb8SMircea Trofin if (OrigTy != NewTy) { 482c62eefb8SMircea Trofin // The default mapping is not supposed to change the size of 483c62eefb8SMircea Trofin // the storage. However, right now we don't necessarily bump all 484c62eefb8SMircea Trofin // the types to storage size. For instance, we can consider 485c62eefb8SMircea Trofin // s16 G_AND legal whereas the storage size is going to be 32. 486d345599cSMichael Maitland assert( 487d345599cSMichael Maitland TypeSize::isKnownLE(OrigTy.getSizeInBits(), NewTy.getSizeInBits()) && 488c62eefb8SMircea Trofin "Types with difference size cannot be handled by the default " 489c62eefb8SMircea Trofin "mapping"); 490c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << "\nChange type of new opd from " << NewTy << " to " 491c62eefb8SMircea Trofin << OrigTy); 492c62eefb8SMircea Trofin MRI.setType(NewReg, OrigTy); 493c62eefb8SMircea Trofin } 494c62eefb8SMircea Trofin LLVM_DEBUG(dbgs() << '\n'); 495c62eefb8SMircea Trofin } 496c62eefb8SMircea Trofin } 497c62eefb8SMircea Trofin 498f219e03fSMichael Maitland TypeSize RegisterBankInfo::getSizeInBits(Register Reg, 499c62eefb8SMircea Trofin const MachineRegisterInfo &MRI, 500c62eefb8SMircea Trofin const TargetRegisterInfo &TRI) const { 501e72ca520SCraig Topper if (Reg.isPhysical()) { 502c62eefb8SMircea Trofin // The size is not directly available for physical registers. 503c62eefb8SMircea Trofin // Instead, we need to access a register class that contains Reg and 504c62eefb8SMircea Trofin // get the size of that register class. 505c62eefb8SMircea Trofin // Because this is expensive, we'll cache the register class by calling 506490e348eSMatt Arsenault auto *RC = getMinimalPhysRegClass(Reg, TRI); 507c62eefb8SMircea Trofin assert(RC && "Expecting Register class"); 508c62eefb8SMircea Trofin return TRI.getRegSizeInBits(*RC); 509c62eefb8SMircea Trofin } 510c62eefb8SMircea Trofin return TRI.getRegSizeInBits(Reg, MRI); 511c62eefb8SMircea Trofin } 512c62eefb8SMircea Trofin 513c62eefb8SMircea Trofin //------------------------------------------------------------------------------ 514c62eefb8SMircea Trofin // Helper classes implementation. 515c62eefb8SMircea Trofin //------------------------------------------------------------------------------ 516c62eefb8SMircea Trofin #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 517c62eefb8SMircea Trofin LLVM_DUMP_METHOD void RegisterBankInfo::PartialMapping::dump() const { 518c62eefb8SMircea Trofin print(dbgs()); 519c62eefb8SMircea Trofin dbgs() << '\n'; 520c62eefb8SMircea Trofin } 521c62eefb8SMircea Trofin #endif 522c62eefb8SMircea Trofin 523aa7eace8SNitin John Raj bool RegisterBankInfo::PartialMapping::verify( 524aa7eace8SNitin John Raj const RegisterBankInfo &RBI) const { 525c62eefb8SMircea Trofin assert(RegBank && "Register bank not set"); 526c62eefb8SMircea Trofin assert(Length && "Empty mapping"); 527c62eefb8SMircea Trofin assert((StartIdx <= getHighBitIdx()) && "Overflow, switch to APInt?"); 528c62eefb8SMircea Trofin // Check if the minimum width fits into RegBank. 529aa7eace8SNitin John Raj assert(RBI.getMaximumSize(RegBank->getID()) >= Length && 530aa7eace8SNitin John Raj "Register bank too small for Mask"); 531c62eefb8SMircea Trofin return true; 532c62eefb8SMircea Trofin } 533c62eefb8SMircea Trofin 534c62eefb8SMircea Trofin void RegisterBankInfo::PartialMapping::print(raw_ostream &OS) const { 535c62eefb8SMircea Trofin OS << "[" << StartIdx << ", " << getHighBitIdx() << "], RegBank = "; 536c62eefb8SMircea Trofin if (RegBank) 537c62eefb8SMircea Trofin OS << *RegBank; 538c62eefb8SMircea Trofin else 539c62eefb8SMircea Trofin OS << "nullptr"; 540c62eefb8SMircea Trofin } 541c62eefb8SMircea Trofin 542c62eefb8SMircea Trofin bool RegisterBankInfo::ValueMapping::partsAllUniform() const { 543c62eefb8SMircea Trofin if (NumBreakDowns < 2) 544c62eefb8SMircea Trofin return true; 545c62eefb8SMircea Trofin 546c62eefb8SMircea Trofin const PartialMapping *First = begin(); 547c62eefb8SMircea Trofin for (const PartialMapping *Part = First + 1; Part != end(); ++Part) { 548c62eefb8SMircea Trofin if (Part->Length != First->Length || Part->RegBank != First->RegBank) 549c62eefb8SMircea Trofin return false; 550c62eefb8SMircea Trofin } 551c62eefb8SMircea Trofin 552c62eefb8SMircea Trofin return true; 553c62eefb8SMircea Trofin } 554c62eefb8SMircea Trofin 555aa7eace8SNitin John Raj bool RegisterBankInfo::ValueMapping::verify(const RegisterBankInfo &RBI, 556f219e03fSMichael Maitland TypeSize MeaningfulBitWidth) const { 557c62eefb8SMircea Trofin assert(NumBreakDowns && "Value mapped nowhere?!"); 558c62eefb8SMircea Trofin unsigned OrigValueBitWidth = 0; 559c62eefb8SMircea Trofin for (const RegisterBankInfo::PartialMapping &PartMap : *this) { 560c62eefb8SMircea Trofin // Check that each register bank is big enough to hold the partial value: 561c62eefb8SMircea Trofin // this check is done by PartialMapping::verify 562aa7eace8SNitin John Raj assert(PartMap.verify(RBI) && "Partial mapping is invalid"); 563c62eefb8SMircea Trofin // The original value should completely be mapped. 564c62eefb8SMircea Trofin // Thus the maximum accessed index + 1 is the size of the original value. 565c62eefb8SMircea Trofin OrigValueBitWidth = 566c62eefb8SMircea Trofin std::max(OrigValueBitWidth, PartMap.getHighBitIdx() + 1); 567c62eefb8SMircea Trofin } 56841481587SDavid Green assert((MeaningfulBitWidth.isScalable() || 56941481587SDavid Green OrigValueBitWidth >= MeaningfulBitWidth) && 570c62eefb8SMircea Trofin "Meaningful bits not covered by the mapping"); 571c62eefb8SMircea Trofin APInt ValueMask(OrigValueBitWidth, 0); 572c62eefb8SMircea Trofin for (const RegisterBankInfo::PartialMapping &PartMap : *this) { 573c62eefb8SMircea Trofin // Check that the union of the partial mappings covers the whole value, 574c62eefb8SMircea Trofin // without overlaps. 575c62eefb8SMircea Trofin // The high bit is exclusive in the APInt API, thus getHighBitIdx + 1. 576c62eefb8SMircea Trofin APInt PartMapMask = APInt::getBitsSet(OrigValueBitWidth, PartMap.StartIdx, 577c62eefb8SMircea Trofin PartMap.getHighBitIdx() + 1); 578c62eefb8SMircea Trofin ValueMask ^= PartMapMask; 579c62eefb8SMircea Trofin assert((ValueMask & PartMapMask) == PartMapMask && 580c62eefb8SMircea Trofin "Some partial mappings overlap"); 581c62eefb8SMircea Trofin } 582c62eefb8SMircea Trofin assert(ValueMask.isAllOnes() && "Value is not fully mapped"); 583c62eefb8SMircea Trofin return true; 584c62eefb8SMircea Trofin } 585c62eefb8SMircea Trofin 586c62eefb8SMircea Trofin #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 587c62eefb8SMircea Trofin LLVM_DUMP_METHOD void RegisterBankInfo::ValueMapping::dump() const { 588c62eefb8SMircea Trofin print(dbgs()); 589c62eefb8SMircea Trofin dbgs() << '\n'; 590c62eefb8SMircea Trofin } 591c62eefb8SMircea Trofin #endif 592c62eefb8SMircea Trofin 593c62eefb8SMircea Trofin void RegisterBankInfo::ValueMapping::print(raw_ostream &OS) const { 594c62eefb8SMircea Trofin OS << "#BreakDown: " << NumBreakDowns << " "; 595c62eefb8SMircea Trofin bool IsFirst = true; 596c62eefb8SMircea Trofin for (const PartialMapping &PartMap : *this) { 597c62eefb8SMircea Trofin if (!IsFirst) 598c62eefb8SMircea Trofin OS << ", "; 599c62eefb8SMircea Trofin OS << '[' << PartMap << ']'; 600c62eefb8SMircea Trofin IsFirst = false; 601c62eefb8SMircea Trofin } 602c62eefb8SMircea Trofin } 603c62eefb8SMircea Trofin 604c62eefb8SMircea Trofin bool RegisterBankInfo::InstructionMapping::verify( 605c62eefb8SMircea Trofin const MachineInstr &MI) const { 606c62eefb8SMircea Trofin // Check that all the register operands are properly mapped. 607c62eefb8SMircea Trofin // Check the constructor invariant. 608c62eefb8SMircea Trofin // For PHI, we only care about mapping the definition. 609c62eefb8SMircea Trofin assert(NumOperands == (isCopyLike(MI) ? 1 : MI.getNumOperands()) && 610c62eefb8SMircea Trofin "NumOperands must match, see constructor"); 611c62eefb8SMircea Trofin assert(MI.getParent() && MI.getMF() && 612c62eefb8SMircea Trofin "MI must be connected to a MachineFunction"); 613c62eefb8SMircea Trofin const MachineFunction &MF = *MI.getMF(); 614c62eefb8SMircea Trofin const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo(); 615c62eefb8SMircea Trofin (void)RBI; 616aaf6c7b0SLuo, Yuanke const MachineRegisterInfo &MRI = MF.getRegInfo(); 617c62eefb8SMircea Trofin 618c62eefb8SMircea Trofin for (unsigned Idx = 0; Idx < NumOperands; ++Idx) { 619c62eefb8SMircea Trofin const MachineOperand &MO = MI.getOperand(Idx); 620c62eefb8SMircea Trofin if (!MO.isReg()) { 621c62eefb8SMircea Trofin assert(!getOperandMapping(Idx).isValid() && 622c62eefb8SMircea Trofin "We should not care about non-reg mapping"); 623c62eefb8SMircea Trofin continue; 624c62eefb8SMircea Trofin } 625c62eefb8SMircea Trofin Register Reg = MO.getReg(); 626c62eefb8SMircea Trofin if (!Reg) 627c62eefb8SMircea Trofin continue; 628aaf6c7b0SLuo, Yuanke LLT Ty = MRI.getType(Reg); 629aaf6c7b0SLuo, Yuanke if (!Ty.isValid()) 630aaf6c7b0SLuo, Yuanke continue; 631c62eefb8SMircea Trofin assert(getOperandMapping(Idx).isValid() && 632c62eefb8SMircea Trofin "We must have a mapping for reg operands"); 633c62eefb8SMircea Trofin const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx); 634c62eefb8SMircea Trofin (void)MOMapping; 635c62eefb8SMircea Trofin // Register size in bits. 636c62eefb8SMircea Trofin // This size must match what the mapping expects. 637aa7eace8SNitin John Raj assert(MOMapping.verify(*RBI, RBI->getSizeInBits( 638aa7eace8SNitin John Raj Reg, MF.getRegInfo(), 639aa7eace8SNitin John Raj *MF.getSubtarget().getRegisterInfo())) && 640c62eefb8SMircea Trofin "Value mapping is invalid"); 641c62eefb8SMircea Trofin } 642c62eefb8SMircea Trofin return true; 643c62eefb8SMircea Trofin } 644c62eefb8SMircea Trofin 645c62eefb8SMircea Trofin #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 646c62eefb8SMircea Trofin LLVM_DUMP_METHOD void RegisterBankInfo::InstructionMapping::dump() const { 647c62eefb8SMircea Trofin print(dbgs()); 648c62eefb8SMircea Trofin dbgs() << '\n'; 649c62eefb8SMircea Trofin } 650c62eefb8SMircea Trofin #endif 651c62eefb8SMircea Trofin 652c62eefb8SMircea Trofin void RegisterBankInfo::InstructionMapping::print(raw_ostream &OS) const { 653c62eefb8SMircea Trofin OS << "ID: " << getID() << " Cost: " << getCost() << " Mapping: "; 654c62eefb8SMircea Trofin 655c62eefb8SMircea Trofin for (unsigned OpIdx = 0; OpIdx != NumOperands; ++OpIdx) { 656c62eefb8SMircea Trofin const ValueMapping &ValMapping = getOperandMapping(OpIdx); 657c62eefb8SMircea Trofin if (OpIdx) 658c62eefb8SMircea Trofin OS << ", "; 659c62eefb8SMircea Trofin OS << "{ Idx: " << OpIdx << " Map: " << ValMapping << '}'; 660c62eefb8SMircea Trofin } 661c62eefb8SMircea Trofin } 662c62eefb8SMircea Trofin 663c62eefb8SMircea Trofin const int RegisterBankInfo::OperandsMapper::DontKnowIdx = -1; 664c62eefb8SMircea Trofin 665c62eefb8SMircea Trofin RegisterBankInfo::OperandsMapper::OperandsMapper( 666c62eefb8SMircea Trofin MachineInstr &MI, const InstructionMapping &InstrMapping, 667c62eefb8SMircea Trofin MachineRegisterInfo &MRI) 668c62eefb8SMircea Trofin : MRI(MRI), MI(MI), InstrMapping(InstrMapping) { 669c62eefb8SMircea Trofin unsigned NumOpds = InstrMapping.getNumOperands(); 670c62eefb8SMircea Trofin OpToNewVRegIdx.resize(NumOpds, OperandsMapper::DontKnowIdx); 671c62eefb8SMircea Trofin assert(InstrMapping.verify(MI) && "Invalid mapping for MI"); 672c62eefb8SMircea Trofin } 673c62eefb8SMircea Trofin 674c62eefb8SMircea Trofin iterator_range<SmallVectorImpl<Register>::iterator> 675c62eefb8SMircea Trofin RegisterBankInfo::OperandsMapper::getVRegsMem(unsigned OpIdx) { 676c62eefb8SMircea Trofin assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); 677c62eefb8SMircea Trofin unsigned NumPartialVal = 678c62eefb8SMircea Trofin getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns; 679c62eefb8SMircea Trofin int StartIdx = OpToNewVRegIdx[OpIdx]; 680c62eefb8SMircea Trofin 681c62eefb8SMircea Trofin if (StartIdx == OperandsMapper::DontKnowIdx) { 682c62eefb8SMircea Trofin // This is the first time we try to access OpIdx. 683c62eefb8SMircea Trofin // Create the cells that will hold all the partial values at the 684c62eefb8SMircea Trofin // end of the list of NewVReg. 685c62eefb8SMircea Trofin StartIdx = NewVRegs.size(); 686c62eefb8SMircea Trofin OpToNewVRegIdx[OpIdx] = StartIdx; 687c62eefb8SMircea Trofin for (unsigned i = 0; i < NumPartialVal; ++i) 688c62eefb8SMircea Trofin NewVRegs.push_back(0); 689c62eefb8SMircea Trofin } 690c62eefb8SMircea Trofin SmallVectorImpl<Register>::iterator End = 691c62eefb8SMircea Trofin getNewVRegsEnd(StartIdx, NumPartialVal); 692c62eefb8SMircea Trofin 693c62eefb8SMircea Trofin return make_range(&NewVRegs[StartIdx], End); 694c62eefb8SMircea Trofin } 695c62eefb8SMircea Trofin 696c62eefb8SMircea Trofin SmallVectorImpl<Register>::const_iterator 697c62eefb8SMircea Trofin RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx, 698c62eefb8SMircea Trofin unsigned NumVal) const { 699c62eefb8SMircea Trofin return const_cast<OperandsMapper *>(this)->getNewVRegsEnd(StartIdx, NumVal); 700c62eefb8SMircea Trofin } 701c62eefb8SMircea Trofin SmallVectorImpl<Register>::iterator 702c62eefb8SMircea Trofin RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx, 703c62eefb8SMircea Trofin unsigned NumVal) { 704c62eefb8SMircea Trofin assert((NewVRegs.size() == StartIdx + NumVal || 705c62eefb8SMircea Trofin NewVRegs.size() > StartIdx + NumVal) && 706c62eefb8SMircea Trofin "NewVRegs too small to contain all the partial mapping"); 707c62eefb8SMircea Trofin return NewVRegs.size() <= StartIdx + NumVal ? NewVRegs.end() 708c62eefb8SMircea Trofin : &NewVRegs[StartIdx + NumVal]; 709c62eefb8SMircea Trofin } 710c62eefb8SMircea Trofin 711c62eefb8SMircea Trofin void RegisterBankInfo::OperandsMapper::createVRegs(unsigned OpIdx) { 712c62eefb8SMircea Trofin assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); 713c62eefb8SMircea Trofin iterator_range<SmallVectorImpl<Register>::iterator> NewVRegsForOpIdx = 714c62eefb8SMircea Trofin getVRegsMem(OpIdx); 715c62eefb8SMircea Trofin const ValueMapping &ValMapping = getInstrMapping().getOperandMapping(OpIdx); 716c62eefb8SMircea Trofin const PartialMapping *PartMap = ValMapping.begin(); 717c62eefb8SMircea Trofin for (Register &NewVReg : NewVRegsForOpIdx) { 718c62eefb8SMircea Trofin assert(PartMap != ValMapping.end() && "Out-of-bound access"); 719c62eefb8SMircea Trofin assert(NewVReg == 0 && "Register has already been created"); 720c62eefb8SMircea Trofin // The new registers are always bound to scalar with the right size. 721c62eefb8SMircea Trofin // The actual type has to be set when the target does the mapping 722c62eefb8SMircea Trofin // of the instruction. 723c62eefb8SMircea Trofin // The rationale is that this generic code cannot guess how the 724c62eefb8SMircea Trofin // target plans to split the input type. 725c62eefb8SMircea Trofin NewVReg = MRI.createGenericVirtualRegister(LLT::scalar(PartMap->Length)); 726c62eefb8SMircea Trofin MRI.setRegBank(NewVReg, *PartMap->RegBank); 727c62eefb8SMircea Trofin ++PartMap; 728c62eefb8SMircea Trofin } 729c62eefb8SMircea Trofin } 730c62eefb8SMircea Trofin 731c62eefb8SMircea Trofin void RegisterBankInfo::OperandsMapper::setVRegs(unsigned OpIdx, 732c62eefb8SMircea Trofin unsigned PartialMapIdx, 733c62eefb8SMircea Trofin Register NewVReg) { 734c62eefb8SMircea Trofin assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); 735c62eefb8SMircea Trofin assert(getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns > 736c62eefb8SMircea Trofin PartialMapIdx && 737c62eefb8SMircea Trofin "Out-of-bound access for partial mapping"); 738c62eefb8SMircea Trofin // Make sure the memory is initialized for that operand. 739c62eefb8SMircea Trofin (void)getVRegsMem(OpIdx); 740c62eefb8SMircea Trofin assert(NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] == 0 && 741c62eefb8SMircea Trofin "This value is already set"); 742c62eefb8SMircea Trofin NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] = NewVReg; 743c62eefb8SMircea Trofin } 744c62eefb8SMircea Trofin 745c62eefb8SMircea Trofin iterator_range<SmallVectorImpl<Register>::const_iterator> 746c62eefb8SMircea Trofin RegisterBankInfo::OperandsMapper::getVRegs(unsigned OpIdx, 747c62eefb8SMircea Trofin bool ForDebug) const { 748c62eefb8SMircea Trofin (void)ForDebug; 749c62eefb8SMircea Trofin assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access"); 750c62eefb8SMircea Trofin int StartIdx = OpToNewVRegIdx[OpIdx]; 751c62eefb8SMircea Trofin 752c62eefb8SMircea Trofin if (StartIdx == OperandsMapper::DontKnowIdx) 753c62eefb8SMircea Trofin return make_range(NewVRegs.end(), NewVRegs.end()); 754c62eefb8SMircea Trofin 755c62eefb8SMircea Trofin unsigned PartMapSize = 756c62eefb8SMircea Trofin getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns; 757c62eefb8SMircea Trofin SmallVectorImpl<Register>::const_iterator End = 758c62eefb8SMircea Trofin getNewVRegsEnd(StartIdx, PartMapSize); 759c62eefb8SMircea Trofin iterator_range<SmallVectorImpl<Register>::const_iterator> Res = 760c62eefb8SMircea Trofin make_range(&NewVRegs[StartIdx], End); 761c62eefb8SMircea Trofin #ifndef NDEBUG 762c62eefb8SMircea Trofin for (Register VReg : Res) 763c62eefb8SMircea Trofin assert((VReg || ForDebug) && "Some registers are uninitialized"); 764c62eefb8SMircea Trofin #endif 765c62eefb8SMircea Trofin return Res; 766c62eefb8SMircea Trofin } 767c62eefb8SMircea Trofin 768c62eefb8SMircea Trofin #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 769c62eefb8SMircea Trofin LLVM_DUMP_METHOD void RegisterBankInfo::OperandsMapper::dump() const { 770c62eefb8SMircea Trofin print(dbgs(), true); 771c62eefb8SMircea Trofin dbgs() << '\n'; 772c62eefb8SMircea Trofin } 773c62eefb8SMircea Trofin #endif 774c62eefb8SMircea Trofin 775c62eefb8SMircea Trofin void RegisterBankInfo::OperandsMapper::print(raw_ostream &OS, 776c62eefb8SMircea Trofin bool ForDebug) const { 777c62eefb8SMircea Trofin unsigned NumOpds = getInstrMapping().getNumOperands(); 778c62eefb8SMircea Trofin if (ForDebug) { 779c62eefb8SMircea Trofin OS << "Mapping for " << getMI() << "\nwith " << getInstrMapping() << '\n'; 780c62eefb8SMircea Trofin // Print out the internal state of the index table. 781c62eefb8SMircea Trofin OS << "Populated indices (CellNumber, IndexInNewVRegs): "; 782c62eefb8SMircea Trofin bool IsFirst = true; 783c62eefb8SMircea Trofin for (unsigned Idx = 0; Idx != NumOpds; ++Idx) { 784c62eefb8SMircea Trofin if (OpToNewVRegIdx[Idx] != DontKnowIdx) { 785c62eefb8SMircea Trofin if (!IsFirst) 786c62eefb8SMircea Trofin OS << ", "; 787c62eefb8SMircea Trofin OS << '(' << Idx << ", " << OpToNewVRegIdx[Idx] << ')'; 788c62eefb8SMircea Trofin IsFirst = false; 789c62eefb8SMircea Trofin } 790c62eefb8SMircea Trofin } 791c62eefb8SMircea Trofin OS << '\n'; 792c62eefb8SMircea Trofin } else 793c62eefb8SMircea Trofin OS << "Mapping ID: " << getInstrMapping().getID() << ' '; 794c62eefb8SMircea Trofin 795c62eefb8SMircea Trofin OS << "Operand Mapping: "; 796c62eefb8SMircea Trofin // If we have a function, we can pretty print the name of the registers. 797c62eefb8SMircea Trofin // Otherwise we will print the raw numbers. 798c62eefb8SMircea Trofin const TargetRegisterInfo *TRI = 799c62eefb8SMircea Trofin getMI().getParent() && getMI().getMF() 800c62eefb8SMircea Trofin ? getMI().getMF()->getSubtarget().getRegisterInfo() 801c62eefb8SMircea Trofin : nullptr; 802c62eefb8SMircea Trofin bool IsFirst = true; 803c62eefb8SMircea Trofin for (unsigned Idx = 0; Idx != NumOpds; ++Idx) { 804c62eefb8SMircea Trofin if (OpToNewVRegIdx[Idx] == DontKnowIdx) 805c62eefb8SMircea Trofin continue; 806c62eefb8SMircea Trofin if (!IsFirst) 807c62eefb8SMircea Trofin OS << ", "; 808c62eefb8SMircea Trofin IsFirst = false; 809c62eefb8SMircea Trofin OS << '(' << printReg(getMI().getOperand(Idx).getReg(), TRI) << ", ["; 810c62eefb8SMircea Trofin bool IsFirstNewVReg = true; 811c62eefb8SMircea Trofin for (Register VReg : getVRegs(Idx)) { 812c62eefb8SMircea Trofin if (!IsFirstNewVReg) 813c62eefb8SMircea Trofin OS << ", "; 814c62eefb8SMircea Trofin IsFirstNewVReg = false; 815c62eefb8SMircea Trofin OS << printReg(VReg, TRI); 816c62eefb8SMircea Trofin } 817c62eefb8SMircea Trofin OS << "])"; 818c62eefb8SMircea Trofin } 819c62eefb8SMircea Trofin } 820