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