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