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