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