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