LLVM 20.0.0git
RegisterBankInfo.cpp
Go to the documentation of this file.
1//===- llvm/CodeGen/GlobalISel/RegisterBankInfo.cpp --------------*- C++ -*-==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements the RegisterBankInfo class.
10//===----------------------------------------------------------------------===//
11
13#include "llvm/ADT/APInt.h"
15#include "llvm/ADT/Statistic.h"
23#include "llvm/Config/llvm-config.h"
24#include "llvm/Support/Debug.h"
26
27#include <algorithm> // For std::max.
28
29#define DEBUG_TYPE "registerbankinfo"
30
31using namespace llvm;
32
33STATISTIC(NumPartialMappingsCreated,
34 "Number of partial mappings dynamically created");
35STATISTIC(NumPartialMappingsAccessed,
36 "Number of partial mappings dynamically accessed");
37STATISTIC(NumValueMappingsCreated,
38 "Number of value mappings dynamically created");
39STATISTIC(NumValueMappingsAccessed,
40 "Number of value mappings dynamically accessed");
41STATISTIC(NumOperandsMappingsCreated,
42 "Number of operands mappings dynamically created");
43STATISTIC(NumOperandsMappingsAccessed,
44 "Number of operands mappings dynamically accessed");
45STATISTIC(NumInstructionMappingsCreated,
46 "Number of instruction mappings dynamically created");
47STATISTIC(NumInstructionMappingsAccessed,
48 "Number of instruction mappings dynamically accessed");
49
50const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX;
51const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1;
52
53//------------------------------------------------------------------------------
54// RegisterBankInfo implementation.
55//------------------------------------------------------------------------------
57 unsigned NumRegBanks, const unsigned *Sizes,
58 unsigned HwMode)
59 : RegBanks(RegBanks), NumRegBanks(NumRegBanks), Sizes(Sizes),
60 HwMode(HwMode) {
61#ifndef NDEBUG
62 for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
63 assert(RegBanks[Idx] != nullptr && "Invalid RegisterBank");
64 assert(RegBanks[Idx]->getID() == Idx &&
65 "RegisterBank ID should match index");
66 }
67#endif // NDEBUG
68}
69
71#ifndef NDEBUG
72 for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
73 const RegisterBank &RegBank = getRegBank(Idx);
74 assert(Idx == RegBank.getID() &&
75 "ID does not match the index in the array");
76 LLVM_DEBUG(dbgs() << "Verify " << RegBank << '\n');
77 assert(RegBank.verify(*this, TRI) && "RegBank is invalid");
78 }
79#endif // NDEBUG
80 return true;
81}
82
83const RegisterBank *
85 const TargetRegisterInfo &TRI) const {
86 if (!Reg.isVirtual()) {
87 // FIXME: This was probably a copy to a virtual register that does have a
88 // type we could use.
90 return RC ? &getRegBankFromRegClass(*RC, LLT()) : nullptr;
91 }
92
93 const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
94 if (auto *RB = dyn_cast_if_present<const RegisterBank *>(RegClassOrBank))
95 return RB;
96 if (auto *RC =
97 dyn_cast_if_present<const TargetRegisterClass *>(RegClassOrBank))
98 return &getRegBankFromRegClass(*RC, MRI.getType(Reg));
99 return nullptr;
100}
101
104 const TargetRegisterInfo &TRI) const {
105 assert(Reg.isPhysical() && "Reg must be a physreg");
106 const auto &RegRCIt = PhysRegMinimalRCs.find(Reg);
107 if (RegRCIt != PhysRegMinimalRCs.end())
108 return RegRCIt->second;
109 const TargetRegisterClass *PhysRC = TRI.getMinimalPhysRegClassLLT(Reg, LLT());
110 PhysRegMinimalRCs[Reg] = PhysRC;
111 return PhysRC;
112}
113
115 const MachineInstr &MI, unsigned OpIdx, const TargetInstrInfo &TII,
116 const MachineRegisterInfo &MRI) const {
117 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
118
119 // The mapping of the registers may be available via the
120 // register class constraints.
121 const TargetRegisterClass *RC = MI.getRegClassConstraint(OpIdx, &TII, TRI);
122
123 if (!RC)
124 return nullptr;
125
126 Register Reg = MI.getOperand(OpIdx).getReg();
127 const RegisterBank &RegBank = getRegBankFromRegClass(*RC, MRI.getType(Reg));
128 // Check that the target properly implemented getRegBankFromRegClass.
129 assert(RegBank.covers(*RC) &&
130 "The mapping of the register bank does not make sense");
131 return &RegBank;
132}
133
136
137 // If the register already has a class, fallback to MRI::constrainRegClass.
138 auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);
139 if (isa<const TargetRegisterClass *>(RegClassOrBank))
140 return MRI.constrainRegClass(Reg, &RC);
141
142 const RegisterBank *RB = cast<const RegisterBank *>(RegClassOrBank);
143 // Otherwise, all we can do is ensure the bank covers the class, and set it.
144 if (RB && !RB->covers(RC))
145 return nullptr;
146
147 // If nothing was set or the class is simply compatible, set it.
148 MRI.setRegClass(Reg, &RC);
149 return &RC;
150}
151
152/// Check whether or not \p MI should be treated like a copy
153/// for the mappings.
154/// Copy like instruction are special for mapping because
155/// they don't have actual register constraints. Moreover,
156/// they sometimes have register classes assigned and we can
157/// just use that instead of failing to provide a generic mapping.
158static bool isCopyLike(const MachineInstr &MI) {
159 return MI.isCopy() || MI.isPHI() ||
160 MI.getOpcode() == TargetOpcode::REG_SEQUENCE;
161}
162
165 // For copies we want to walk over the operands and try to find one
166 // that has a register bank since the instruction itself will not get
167 // us any constraint.
168 bool IsCopyLike = isCopyLike(MI);
169 // For copy like instruction, only the mapping of the definition
170 // is important. The rest is not constrained.
171 unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands();
172
173 const MachineFunction &MF = *MI.getMF();
174 const TargetSubtargetInfo &STI = MF.getSubtarget();
175 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
176 const MachineRegisterInfo &MRI = MF.getRegInfo();
177 // We may need to query the instruction encoding to guess the mapping.
178 const TargetInstrInfo &TII = *STI.getInstrInfo();
179
180 // Before doing anything complicated check if the mapping is not
181 // directly available.
182 bool CompleteMapping = true;
183
184 SmallVector<const ValueMapping *, 8> OperandsMapping(NumOperandsForMapping);
185 for (unsigned OpIdx = 0, EndIdx = MI.getNumOperands(); OpIdx != EndIdx;
186 ++OpIdx) {
187 const MachineOperand &MO = MI.getOperand(OpIdx);
188 if (!MO.isReg())
189 continue;
190 Register Reg = MO.getReg();
191 if (!Reg)
192 continue;
193 // The register bank of Reg is just a side effect of the current
194 // excution and in particular, there is no reason to believe this
195 // is the best default mapping for the current instruction. Keep
196 // it as an alternative register bank if we cannot figure out
197 // something.
198 const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI);
199 // For copy-like instruction, we want to reuse the register bank
200 // that is already set on Reg, if any, since those instructions do
201 // not have any constraints.
202 const RegisterBank *CurRegBank = IsCopyLike ? AltRegBank : nullptr;
203 if (!CurRegBank) {
204 // If this is a target specific instruction, we can deduce
205 // the register bank from the encoding constraints.
206 CurRegBank = getRegBankFromConstraints(MI, OpIdx, TII, MRI);
207 if (!CurRegBank) {
208 // All our attempts failed, give up.
209 CompleteMapping = false;
210
211 if (!IsCopyLike)
212 // MI does not carry enough information to guess the mapping.
214 continue;
215 }
216 }
217
219 const ValueMapping *ValMapping =
220 &getValueMapping(0, Size.getKnownMinValue(), *CurRegBank);
221 if (IsCopyLike) {
222 if (!OperandsMapping[0]) {
223 if (MI.isRegSequence()) {
224 // For reg_sequence, the result size does not match the input.
225 unsigned ResultSize = getSizeInBits(MI.getOperand(0).getReg(),
226 MRI, TRI);
227 OperandsMapping[0] = &getValueMapping(0, ResultSize, *CurRegBank);
228 } else {
229 OperandsMapping[0] = ValMapping;
230 }
231 }
232
233 // The default handling assumes any register bank can be copied to any
234 // other. If this isn't the case, the target should specially deal with
235 // reg_sequence/phi. There may also be unsatisfiable copies.
236 for (; OpIdx != EndIdx; ++OpIdx) {
237 const MachineOperand &MO = MI.getOperand(OpIdx);
238 if (!MO.isReg())
239 continue;
240 Register Reg = MO.getReg();
241 if (!Reg)
242 continue;
243
244 const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI);
245 if (AltRegBank &&
246 cannotCopy(*CurRegBank, *AltRegBank, getSizeInBits(Reg, MRI, TRI)))
248 }
249
250 CompleteMapping = true;
251 break;
252 }
253
254 OperandsMapping[OpIdx] = ValMapping;
255 }
256
257 if (IsCopyLike && !CompleteMapping) {
258 // No way to deduce the type from what we have.
260 }
261
262 assert(CompleteMapping && "Setting an uncomplete mapping");
264 DefaultMappingID, /*Cost*/ 1,
265 /*OperandsMapping*/ getOperandsMapping(OperandsMapping),
266 NumOperandsForMapping);
267}
268
269/// Hashing function for PartialMapping.
270static hash_code hashPartialMapping(unsigned StartIdx, unsigned Length,
271 const RegisterBank *RegBank) {
272 return hash_combine(StartIdx, Length, RegBank ? RegBank->getID() : 0);
273}
274
275/// Overloaded version of hash_value for a PartialMapping.
278 return hashPartialMapping(PartMapping.StartIdx, PartMapping.Length,
279 PartMapping.RegBank);
280}
281
283RegisterBankInfo::getPartialMapping(unsigned StartIdx, unsigned Length,
284 const RegisterBank &RegBank) const {
285 ++NumPartialMappingsAccessed;
286
287 hash_code Hash = hashPartialMapping(StartIdx, Length, &RegBank);
288 const auto &It = MapOfPartialMappings.find(Hash);
289 if (It != MapOfPartialMappings.end())
290 return *It->second;
291
292 ++NumPartialMappingsCreated;
293
294 auto &PartMapping = MapOfPartialMappings[Hash];
295 PartMapping = std::make_unique<PartialMapping>(StartIdx, Length, RegBank);
296 return *PartMapping;
297}
298
300RegisterBankInfo::getValueMapping(unsigned StartIdx, unsigned Length,
301 const RegisterBank &RegBank) const {
302 return getValueMapping(&getPartialMapping(StartIdx, Length, RegBank), 1);
303}
304
305static hash_code
307 unsigned NumBreakDowns) {
308 if (LLVM_LIKELY(NumBreakDowns == 1))
309 return hash_value(*BreakDown);
310 SmallVector<size_t, 8> Hashes(NumBreakDowns);
311 for (unsigned Idx = 0; Idx != NumBreakDowns; ++Idx)
312 Hashes.push_back(hash_value(BreakDown[Idx]));
313 return hash_combine_range(Hashes.begin(), Hashes.end());
314}
315
318 unsigned NumBreakDowns) const {
319 ++NumValueMappingsAccessed;
320
321 hash_code Hash = hashValueMapping(BreakDown, NumBreakDowns);
322 const auto &It = MapOfValueMappings.find(Hash);
323 if (It != MapOfValueMappings.end())
324 return *It->second;
325
326 ++NumValueMappingsCreated;
327
328 auto &ValMapping = MapOfValueMappings[Hash];
329 ValMapping = std::make_unique<ValueMapping>(BreakDown, NumBreakDowns);
330 return *ValMapping;
331}
332
333template <typename Iterator>
335RegisterBankInfo::getOperandsMapping(Iterator Begin, Iterator End) const {
336
337 ++NumOperandsMappingsAccessed;
338
339 // The addresses of the value mapping are unique.
340 // Therefore, we can use them directly to hash the operand mapping.
341 hash_code Hash = hash_combine_range(Begin, End);
342 auto &Res = MapOfOperandsMappings[Hash];
343 if (Res)
344 return Res.get();
345
346 ++NumOperandsMappingsCreated;
347
348 // Create the array of ValueMapping.
349 // Note: this array will not hash to this instance of operands
350 // mapping, because we use the pointer of the ValueMapping
351 // to hash and we expect them to uniquely identify an instance
352 // of value mapping.
353 Res = std::make_unique<ValueMapping[]>(std::distance(Begin, End));
354 unsigned Idx = 0;
355 for (Iterator It = Begin; It != End; ++It, ++Idx) {
356 const ValueMapping *ValMap = *It;
357 if (!ValMap)
358 continue;
359 Res[Idx] = *ValMap;
360 }
361 return Res.get();
362}
363
366 const {
367 return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end());
368}
369
371 std::initializer_list<const RegisterBankInfo::ValueMapping *> OpdsMapping)
372 const {
373 return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end());
374}
375
376static hash_code
377hashInstructionMapping(unsigned ID, unsigned Cost,
378 const RegisterBankInfo::ValueMapping *OperandsMapping,
379 unsigned NumOperands) {
380 return hash_combine(ID, Cost, OperandsMapping, NumOperands);
381}
382
384RegisterBankInfo::getInstructionMappingImpl(
385 bool IsInvalid, unsigned ID, unsigned Cost,
386 const RegisterBankInfo::ValueMapping *OperandsMapping,
387 unsigned NumOperands) const {
388 assert(((IsInvalid && ID == InvalidMappingID && Cost == 0 &&
389 OperandsMapping == nullptr && NumOperands == 0) ||
390 !IsInvalid) &&
391 "Mismatch argument for invalid input");
392 ++NumInstructionMappingsAccessed;
393
394 hash_code Hash =
395 hashInstructionMapping(ID, Cost, OperandsMapping, NumOperands);
396 const auto &It = MapOfInstructionMappings.find(Hash);
397 if (It != MapOfInstructionMappings.end())
398 return *It->second;
399
400 ++NumInstructionMappingsCreated;
401
402 auto &InstrMapping = MapOfInstructionMappings[Hash];
403 InstrMapping = std::make_unique<InstructionMapping>(
404 ID, Cost, OperandsMapping, NumOperands);
405 return *InstrMapping;
406}
407
411 if (Mapping.isValid())
412 return Mapping;
413 llvm_unreachable("The target must implement this");
414}
415
418 InstructionMappings PossibleMappings;
419 const auto &Mapping = getInstrMapping(MI);
420 if (Mapping.isValid()) {
421 // Put the default mapping first.
422 PossibleMappings.push_back(&Mapping);
423 }
424
425 // Then the alternative mapping, if any.
427 append_range(PossibleMappings, AltMappings);
428#ifndef NDEBUG
429 for (const InstructionMapping *Mapping : PossibleMappings)
430 assert(Mapping->verify(MI) && "Mapping is invalid");
431#endif
432 return PossibleMappings;
433}
434
437 // No alternative for MI.
438 return InstructionMappings();
439}
440
442 MachineInstr &MI = OpdMapper.getMI();
443 MachineRegisterInfo &MRI = OpdMapper.getMRI();
444 LLVM_DEBUG(dbgs() << "Applying default-like mapping\n");
445 for (unsigned OpIdx = 0,
446 EndIdx = OpdMapper.getInstrMapping().getNumOperands();
447 OpIdx != EndIdx; ++OpIdx) {
448 LLVM_DEBUG(dbgs() << "OpIdx " << OpIdx);
449 MachineOperand &MO = MI.getOperand(OpIdx);
450 if (!MO.isReg()) {
451 LLVM_DEBUG(dbgs() << " is not a register, nothing to be done\n");
452 continue;
453 }
454 if (!MO.getReg()) {
455 LLVM_DEBUG(dbgs() << " is $noreg, nothing to be done\n");
456 continue;
457 }
458 LLT Ty = MRI.getType(MO.getReg());
459 if (!Ty.isValid())
460 continue;
461 assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns !=
462 0 &&
463 "Invalid mapping");
464 assert(OpdMapper.getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns ==
465 1 &&
466 "This mapping is too complex for this function");
468 OpdMapper.getVRegs(OpIdx);
469 if (NewRegs.empty()) {
470 LLVM_DEBUG(dbgs() << " has not been repaired, nothing to be done\n");
471 continue;
472 }
473 Register OrigReg = MO.getReg();
474 Register NewReg = *NewRegs.begin();
475 LLVM_DEBUG(dbgs() << " changed, replace " << printReg(OrigReg, nullptr));
476 MO.setReg(NewReg);
477 LLVM_DEBUG(dbgs() << " with " << printReg(NewReg, nullptr));
478
479 // The OperandsMapper creates plain scalar, we may have to fix that.
480 // Check if the types match and if not, fix that.
481 LLT OrigTy = MRI.getType(OrigReg);
482 LLT NewTy = MRI.getType(NewReg);
483 if (OrigTy != NewTy) {
484 // The default mapping is not supposed to change the size of
485 // the storage. However, right now we don't necessarily bump all
486 // the types to storage size. For instance, we can consider
487 // s16 G_AND legal whereas the storage size is going to be 32.
488 assert(
490 "Types with difference size cannot be handled by the default "
491 "mapping");
492 LLVM_DEBUG(dbgs() << "\nChange type of new opd from " << NewTy << " to "
493 << OrigTy);
494 MRI.setType(NewReg, OrigTy);
495 }
496 LLVM_DEBUG(dbgs() << '\n');
497 }
498}
499
502 const TargetRegisterInfo &TRI) const {
503 if (Reg.isPhysical()) {
504 // The size is not directly available for physical registers.
505 // Instead, we need to access a register class that contains Reg and
506 // get the size of that register class.
507 // Because this is expensive, we'll cache the register class by calling
508 auto *RC = getMinimalPhysRegClass(Reg, TRI);
509 assert(RC && "Expecting Register class");
510 return TRI.getRegSizeInBits(*RC);
511 }
512 return TRI.getRegSizeInBits(Reg, MRI);
513}
514
515//------------------------------------------------------------------------------
516// Helper classes implementation.
517//------------------------------------------------------------------------------
518#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
520 print(dbgs());
521 dbgs() << '\n';
522}
523#endif
524
526 const RegisterBankInfo &RBI) const {
527 assert(RegBank && "Register bank not set");
528 assert(Length && "Empty mapping");
529 assert((StartIdx <= getHighBitIdx()) && "Overflow, switch to APInt?");
530 // Check if the minimum width fits into RegBank.
531 assert(RBI.getMaximumSize(RegBank->getID()) >= Length &&
532 "Register bank too small for Mask");
533 return true;
534}
535
537 OS << "[" << StartIdx << ", " << getHighBitIdx() << "], RegBank = ";
538 if (RegBank)
539 OS << *RegBank;
540 else
541 OS << "nullptr";
542}
543
545 if (NumBreakDowns < 2)
546 return true;
547
548 const PartialMapping *First = begin();
549 for (const PartialMapping *Part = First + 1; Part != end(); ++Part) {
550 if (Part->Length != First->Length || Part->RegBank != First->RegBank)
551 return false;
552 }
553
554 return true;
555}
556
558 TypeSize MeaningfulBitWidth) const {
559 assert(NumBreakDowns && "Value mapped nowhere?!");
560 unsigned OrigValueBitWidth = 0;
561 for (const RegisterBankInfo::PartialMapping &PartMap : *this) {
562 // Check that each register bank is big enough to hold the partial value:
563 // this check is done by PartialMapping::verify
564 assert(PartMap.verify(RBI) && "Partial mapping is invalid");
565 // The original value should completely be mapped.
566 // Thus the maximum accessed index + 1 is the size of the original value.
567 OrigValueBitWidth =
568 std::max(OrigValueBitWidth, PartMap.getHighBitIdx() + 1);
569 }
570 assert((MeaningfulBitWidth.isScalable() ||
571 OrigValueBitWidth >= MeaningfulBitWidth) &&
572 "Meaningful bits not covered by the mapping");
573 APInt ValueMask(OrigValueBitWidth, 0);
574 for (const RegisterBankInfo::PartialMapping &PartMap : *this) {
575 // Check that the union of the partial mappings covers the whole value,
576 // without overlaps.
577 // The high bit is exclusive in the APInt API, thus getHighBitIdx + 1.
578 APInt PartMapMask = APInt::getBitsSet(OrigValueBitWidth, PartMap.StartIdx,
579 PartMap.getHighBitIdx() + 1);
580 ValueMask ^= PartMapMask;
581 assert((ValueMask & PartMapMask) == PartMapMask &&
582 "Some partial mappings overlap");
583 }
584 assert(ValueMask.isAllOnes() && "Value is not fully mapped");
585 return true;
586}
587
588#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
590 print(dbgs());
591 dbgs() << '\n';
592}
593#endif
594
596 OS << "#BreakDown: " << NumBreakDowns << " ";
597 bool IsFirst = true;
598 for (const PartialMapping &PartMap : *this) {
599 if (!IsFirst)
600 OS << ", ";
601 OS << '[' << PartMap << ']';
602 IsFirst = false;
603 }
604}
605
607 const MachineInstr &MI) const {
608 // Check that all the register operands are properly mapped.
609 // Check the constructor invariant.
610 // For PHI, we only care about mapping the definition.
611 assert(NumOperands == (isCopyLike(MI) ? 1 : MI.getNumOperands()) &&
612 "NumOperands must match, see constructor");
613 assert(MI.getParent() && MI.getMF() &&
614 "MI must be connected to a MachineFunction");
615 const MachineFunction &MF = *MI.getMF();
616 const RegisterBankInfo *RBI = MF.getSubtarget().getRegBankInfo();
617 (void)RBI;
618 const MachineRegisterInfo &MRI = MF.getRegInfo();
619
620 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
621 const MachineOperand &MO = MI.getOperand(Idx);
622 if (!MO.isReg()) {
623 assert(!getOperandMapping(Idx).isValid() &&
624 "We should not care about non-reg mapping");
625 continue;
626 }
627 Register Reg = MO.getReg();
628 if (!Reg)
629 continue;
630 LLT Ty = MRI.getType(Reg);
631 if (!Ty.isValid())
632 continue;
633 assert(getOperandMapping(Idx).isValid() &&
634 "We must have a mapping for reg operands");
635 const RegisterBankInfo::ValueMapping &MOMapping = getOperandMapping(Idx);
636 (void)MOMapping;
637 // Register size in bits.
638 // This size must match what the mapping expects.
639 assert(MOMapping.verify(*RBI, RBI->getSizeInBits(
640 Reg, MF.getRegInfo(),
641 *MF.getSubtarget().getRegisterInfo())) &&
642 "Value mapping is invalid");
643 }
644 return true;
645}
646
647#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
649 print(dbgs());
650 dbgs() << '\n';
651}
652#endif
653
655 OS << "ID: " << getID() << " Cost: " << getCost() << " Mapping: ";
656
657 for (unsigned OpIdx = 0; OpIdx != NumOperands; ++OpIdx) {
658 const ValueMapping &ValMapping = getOperandMapping(OpIdx);
659 if (OpIdx)
660 OS << ", ";
661 OS << "{ Idx: " << OpIdx << " Map: " << ValMapping << '}';
662 }
663}
664
665const int RegisterBankInfo::OperandsMapper::DontKnowIdx = -1;
666
668 MachineInstr &MI, const InstructionMapping &InstrMapping,
670 : MRI(MRI), MI(MI), InstrMapping(InstrMapping) {
671 unsigned NumOpds = InstrMapping.getNumOperands();
672 OpToNewVRegIdx.resize(NumOpds, OperandsMapper::DontKnowIdx);
673 assert(InstrMapping.verify(MI) && "Invalid mapping for MI");
674}
675
677RegisterBankInfo::OperandsMapper::getVRegsMem(unsigned OpIdx) {
678 assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
679 unsigned NumPartialVal =
680 getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns;
681 int StartIdx = OpToNewVRegIdx[OpIdx];
682
683 if (StartIdx == OperandsMapper::DontKnowIdx) {
684 // This is the first time we try to access OpIdx.
685 // Create the cells that will hold all the partial values at the
686 // end of the list of NewVReg.
687 StartIdx = NewVRegs.size();
688 OpToNewVRegIdx[OpIdx] = StartIdx;
689 for (unsigned i = 0; i < NumPartialVal; ++i)
690 NewVRegs.push_back(0);
691 }
693 getNewVRegsEnd(StartIdx, NumPartialVal);
694
695 return make_range(&NewVRegs[StartIdx], End);
696}
697
699RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx,
700 unsigned NumVal) const {
701 return const_cast<OperandsMapper *>(this)->getNewVRegsEnd(StartIdx, NumVal);
702}
704RegisterBankInfo::OperandsMapper::getNewVRegsEnd(unsigned StartIdx,
705 unsigned NumVal) {
706 assert((NewVRegs.size() == StartIdx + NumVal ||
707 NewVRegs.size() > StartIdx + NumVal) &&
708 "NewVRegs too small to contain all the partial mapping");
709 return NewVRegs.size() <= StartIdx + NumVal ? NewVRegs.end()
710 : &NewVRegs[StartIdx + NumVal];
711}
712
714 assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
716 getVRegsMem(OpIdx);
717 const ValueMapping &ValMapping = getInstrMapping().getOperandMapping(OpIdx);
718 const PartialMapping *PartMap = ValMapping.begin();
719 for (Register &NewVReg : NewVRegsForOpIdx) {
720 assert(PartMap != ValMapping.end() && "Out-of-bound access");
721 assert(NewVReg == 0 && "Register has already been created");
722 // The new registers are always bound to scalar with the right size.
723 // The actual type has to be set when the target does the mapping
724 // of the instruction.
725 // The rationale is that this generic code cannot guess how the
726 // target plans to split the input type.
727 NewVReg = MRI.createGenericVirtualRegister(LLT::scalar(PartMap->Length));
728 MRI.setRegBank(NewVReg, *PartMap->RegBank);
729 ++PartMap;
730 }
731}
732
734 unsigned PartialMapIdx,
735 Register NewVReg) {
736 assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
737 assert(getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns >
738 PartialMapIdx &&
739 "Out-of-bound access for partial mapping");
740 // Make sure the memory is initialized for that operand.
741 (void)getVRegsMem(OpIdx);
742 assert(NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] == 0 &&
743 "This value is already set");
744 NewVRegs[OpToNewVRegIdx[OpIdx] + PartialMapIdx] = NewVReg;
745}
746
749 bool ForDebug) const {
750 (void)ForDebug;
751 assert(OpIdx < getInstrMapping().getNumOperands() && "Out-of-bound access");
752 int StartIdx = OpToNewVRegIdx[OpIdx];
753
754 if (StartIdx == OperandsMapper::DontKnowIdx)
755 return make_range(NewVRegs.end(), NewVRegs.end());
756
757 unsigned PartMapSize =
758 getInstrMapping().getOperandMapping(OpIdx).NumBreakDowns;
760 getNewVRegsEnd(StartIdx, PartMapSize);
762 make_range(&NewVRegs[StartIdx], End);
763#ifndef NDEBUG
764 for (Register VReg : Res)
765 assert((VReg || ForDebug) && "Some registers are uninitialized");
766#endif
767 return Res;
768}
769
770#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
772 print(dbgs(), true);
773 dbgs() << '\n';
774}
775#endif
776
778 bool ForDebug) const {
779 unsigned NumOpds = getInstrMapping().getNumOperands();
780 if (ForDebug) {
781 OS << "Mapping for " << getMI() << "\nwith " << getInstrMapping() << '\n';
782 // Print out the internal state of the index table.
783 OS << "Populated indices (CellNumber, IndexInNewVRegs): ";
784 bool IsFirst = true;
785 for (unsigned Idx = 0; Idx != NumOpds; ++Idx) {
786 if (OpToNewVRegIdx[Idx] != DontKnowIdx) {
787 if (!IsFirst)
788 OS << ", ";
789 OS << '(' << Idx << ", " << OpToNewVRegIdx[Idx] << ')';
790 IsFirst = false;
791 }
792 }
793 OS << '\n';
794 } else
795 OS << "Mapping ID: " << getInstrMapping().getID() << ' ';
796
797 OS << "Operand Mapping: ";
798 // If we have a function, we can pretty print the name of the registers.
799 // Otherwise we will print the raw numbers.
800 const TargetRegisterInfo *TRI =
801 getMI().getParent() && getMI().getMF()
802 ? getMI().getMF()->getSubtarget().getRegisterInfo()
803 : nullptr;
804 bool IsFirst = true;
805 for (unsigned Idx = 0; Idx != NumOpds; ++Idx) {
806 if (OpToNewVRegIdx[Idx] == DontKnowIdx)
807 continue;
808 if (!IsFirst)
809 OS << ", ";
810 IsFirst = false;
811 OS << '(' << printReg(getMI().getOperand(Idx).getReg(), TRI) << ", [";
812 bool IsFirstNewVReg = true;
813 for (Register VReg : getVRegs(Idx)) {
814 if (!IsFirstNewVReg)
815 OS << ", ";
816 IsFirstNewVReg = false;
817 OS << printReg(VReg, TRI);
818 }
819 OS << "])";
820 }
821}
unsigned const MachineRegisterInfo * MRI
This file implements a class to represent arbitrary precision integral constant values and operations...
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:537
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:240
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static hash_code hashPartialMapping(unsigned StartIdx, unsigned Length, const RegisterBank *RegBank)
Hashing function for PartialMapping.
static bool isCopyLike(const MachineInstr &MI)
Check whether or not MI should be treated like a copy for the mappings.
static hash_code hashValueMapping(const RegisterBankInfo::PartialMapping *BreakDown, unsigned NumBreakDowns)
static hash_code hashInstructionMapping(unsigned ID, unsigned Cost, const RegisterBankInfo::ValueMapping *OperandsMapping, unsigned NumOperands)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
Class for arbitrary precision integers.
Definition: APInt.h:78
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
Definition: APInt.h:351
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
Definition: APInt.h:238
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
constexpr bool isValid() const
Definition: LowLevelType.h:145
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:193
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Helper class that represents how the value of an instruction may be mapped and what is the related co...
unsigned getNumOperands() const
Get the number of operands.
bool verify(const MachineInstr &MI) const
Verifiy that this mapping makes sense for MI.
void dump() const
Print this on dbgs() stream.
void print(raw_ostream &OS) const
Print this on OS;.
bool isValid() const
Check whether this object is valid.
Helper class used to get/create the virtual registers that will be used to replace the MachineOperand...
const InstructionMapping & getInstrMapping() const
The final mapping of the instruction.
void setVRegs(unsigned OpIdx, unsigned PartialMapIdx, Register NewVReg)
Set the virtual register of the PartialMapIdx-th partial mapping of the OpIdx-th operand to NewVReg.
void print(raw_ostream &OS, bool ForDebug=false) const
Print this operands mapper on OS stream.
void createVRegs(unsigned OpIdx)
Create as many new virtual registers as needed for the mapping of the OpIdx-th operand.
MachineRegisterInfo & getMRI() const
The MachineRegisterInfo we used to realize the mapping.
OperandsMapper(MachineInstr &MI, const InstructionMapping &InstrMapping, MachineRegisterInfo &MRI)
Create an OperandsMapper that will hold the information to apply InstrMapping to MI.
void dump() const
Print this operands mapper on dbgs() stream.
iterator_range< SmallVectorImpl< Register >::const_iterator > getVRegs(unsigned OpIdx, bool ForDebug=false) const
Get all the virtual registers required to map the OpIdx-th operand of the instruction.
Holds all the information related to register banks.
const PartialMapping & getPartialMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const
Get the uniquely generated PartialMapping for the given arguments.
virtual InstructionMappings getInstrAlternativeMappings(const MachineInstr &MI) const
Get the alternative mappings for MI.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
DenseMap< hash_code, std::unique_ptr< const InstructionMapping > > MapOfInstructionMappings
Keep dynamically allocated InstructionMapping in a separate map.
const RegisterBank ** RegBanks
Hold the set of supported register banks.
RegisterBankInfo()
This constructor is meaningless.
DenseMap< hash_code, std::unique_ptr< const PartialMapping > > MapOfPartialMappings
Keep dynamically allocated PartialMapping in a separate map.
virtual const InstructionMapping & getInstrMapping(const MachineInstr &MI) const
Get the mapping of the different operands of MI on the register bank.
const InstructionMapping & getInstructionMapping(unsigned ID, unsigned Cost, const ValueMapping *OperandsMapping, unsigned NumOperands) const
Method to get a uniquely generated InstructionMapping.
static void applyDefaultMapping(const OperandsMapper &OpdMapper)
Helper method to apply something that is like the default mapping.
DenseMap< hash_code, std::unique_ptr< const ValueMapping > > MapOfValueMappings
Keep dynamically allocated ValueMapping in a separate map.
const TargetRegisterClass * getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const
Get the MinimalPhysRegClass for Reg.
const ValueMapping & getValueMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const
The most common ValueMapping consists of a single PartialMapping.
const InstructionMapping & getInvalidInstructionMapping() const
Method to get a uniquely generated invalid InstructionMapping.
DenseMap< hash_code, std::unique_ptr< ValueMapping[]> > MapOfOperandsMappings
Keep dynamically allocated array of ValueMapping in a separate map.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
bool cannotCopy(const RegisterBank &Dst, const RegisterBank &Src, TypeSize Size) const
unsigned getMaximumSize(unsigned RegBankID) const
Get the maximum size in bits that fits in the given register bank.
unsigned getNumRegBanks() const
Get the total number of register banks.
const RegisterBank * getRegBankFromConstraints(const MachineInstr &MI, unsigned OpIdx, const TargetInstrInfo &TII, const MachineRegisterInfo &MRI) const
Get the register bank for the OpIdx-th operand of MI form the encoding constraints,...
TypeSize getSizeInBits(Register Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const
Get a register bank that covers RC.
InstructionMappings getInstrPossibleMappings(const MachineInstr &MI) const
Get the possible mapping for MI.
DenseMap< unsigned, const TargetRegisterClass * > PhysRegMinimalRCs
Getting the minimal register class of a physreg is expensive.
static const unsigned InvalidMappingID
Identifier used when the related instruction mapping instance is generated by the default constructor...
const ValueMapping * getOperandsMapping(Iterator Begin, Iterator End) const
Get the uniquely generated array of ValueMapping for the elements of between Begin and End.
static const unsigned DefaultMappingID
Identifier used when the related instruction mapping instance is generated by target independent code...
SmallVector< const InstructionMapping *, 4 > InstructionMappings
Convenient type to represent the alternatives for mapping an instruction.
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
const InstructionMapping & getInstrMappingImpl(const MachineInstr &MI) const
Try to get the mapping of MI.
This class implements the register bank concept.
Definition: RegisterBank.h:28
bool verify(const RegisterBankInfo &RBI, const TargetRegisterInfo &TRI) const
Check if this register bank is valid.
bool covers(const TargetRegisterClass &RC) const
Check whether this register bank covers RC.
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:45
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:587
typename SuperClass::const_iterator const_iterator
Definition: SmallVector.h:592
typename SuperClass::iterator iterator
Definition: SmallVector.h:591
void resize(size_type N)
Definition: SmallVector.h:652
void push_back(const T &Elt)
Definition: SmallVector.h:427
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1210
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition: TypeSize.h:232
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
An opaque object representing a hash code.
Definition: Hashing.h:75
A range adaptor for a pair of iterators.
IteratorT begin() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:480
hash_code hash_value(const FixedPointSemantics &Val)
Definition: APFixedPoint.h:128
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2073
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:593
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:471
Helper struct that represents how a value is partially mapped into a register.
void print(raw_ostream &OS) const
Print this partial mapping on OS;.
unsigned StartIdx
Number of bits at which this partial mapping starts in the original value.
bool verify(const RegisterBankInfo &RBI) const
Check that the Mask is compatible with the RegBank.
void dump() const
Print this partial mapping on dbgs() stream.
const RegisterBank * RegBank
Register bank where the partial value lives.
unsigned Length
Length of this mapping in bits.
Helper struct that represents how a value is mapped through different register banks.
const PartialMapping * begin() const
Iterators through the PartialMappings.
const PartialMapping * end() const
void print(raw_ostream &OS) const
Print this on OS;.
bool verify(const RegisterBankInfo &RBI, TypeSize MeaningfulBitWidth) const
Verify that this mapping makes sense for a value of MeaningfulBitWidth.
unsigned NumBreakDowns
Number of partial mapping to break down this value.
void dump() const
Print this on dbgs() stream.