llvm.org GIT mirror llvm / ce22b10
[RegisterBankInfo] Uniquely allocate instruction mapping. This is a step toward having statically allocated instruciton mapping. We are going to tablegen them eventually, so let us reflect that in the API. NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302316 91177308-0d34-0410-b5e6-96231b3b80d8 Quentin Colombet 3 years ago
12 changed file(s) with 223 addition(s) and 144 deletion(s). Raw diff Collapse all Expand all
560560
561561 /// Find the best mapping for \p MI from \p PossibleMappings.
562562 /// \return a reference on the best mapping in \p PossibleMappings.
563 RegisterBankInfo::InstructionMapping &
563 const RegisterBankInfo::InstructionMapping &
564564 findBestMapping(MachineInstr &MI,
565565 RegisterBankInfo::InstructionMappings &PossibleMappings,
566566 SmallVectorImpl &RepairPts);
263263 /// Convenient type to represent the alternatives for mapping an
264264 /// instruction.
265265 /// \todo When we move to TableGen this should be an array ref.
266 typedef SmallVector<InstructionMapping, 4> InstructionMappings;
266 typedef SmallVector<const InstructionMapping *, 4> InstructionMappings;
267267
268268 /// Helper class used to get/create the virtual registers that will be used
269269 /// to replace the MachineOperand when applying a mapping.
390390 mutable DenseMap>
391391 MapOfOperandsMappings;
392392
393 /// Keep dynamically allocated InstructionMapping in a separate map.
394 /// This shouldn't be needed when everything gets TableGen'ed.
395 mutable DenseMap>
396 MapOfInstructionMappings;
397
393398 /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
394399 /// RegisterBank instances.
395400 RegisterBankInfo(RegisterBank **RegBanks, unsigned NumRegBanks);
427432 /// register, a register class, or a register bank.
428433 /// In other words, this method will likely fail to find a mapping for
429434 /// any generic opcode that has not been lowered by target specific code.
430 InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const;
435 const InstructionMapping &getInstrMappingImpl(const MachineInstr &MI) const;
431436
432437 /// Get the uniquely generated PartialMapping for the
433438 /// given arguments.
478483 /// ValueMapping (ValueMapping::isValid == false).
479484 const ValueMapping *getOperandsMapping(
480485 std::initializer_list OpdsMapping) const;
486 /// @}
487
488 /// \name Methods to get a uniquely generated InstructionMapping.
489 /// @{
490
491 private:
492 /// Method to get a uniquely generated InstructionMapping.
493 const InstructionMapping &
494 getInstructionMappingImpl(bool IsInvalid, unsigned ID = InvalidMappingID,
495 unsigned Cost = 0,
496 const ValueMapping *OperandsMapping = nullptr,
497 unsigned NumOperands = 0) const;
498
499 public:
500 /// Method to get a uniquely generated InstructionMapping.
501 const InstructionMapping &
502 getInstructionMapping(unsigned ID, unsigned Cost,
503 const ValueMapping *OperandsMapping,
504 unsigned NumOperands) const {
505 return getInstructionMappingImpl(/*IsInvalid*/ false, ID, Cost,
506 OperandsMapping, NumOperands);
507 }
508
509 /// Method to get a uniquely generated invalid InstructionMapping.
510 const InstructionMapping &getInvalidInstructionMapping() const {
511 return getInstructionMappingImpl(/*IsInvalid*/ true);
512 }
481513 /// @}
482514
483515 /// Get the register bank for the \p OpIdx-th operand of \p MI form
605637 ///
606638 /// \note If returnedVal does not verify MI, this would probably mean
607639 /// that the target does not support that instruction.
608 virtual InstructionMapping getInstrMapping(const MachineInstr &MI) const;
640 virtual const InstructionMapping &
641 getInstrMapping(const MachineInstr &MI) const;
609642
610643 /// Get the alternative mappings for \p MI.
611644 /// Alternative in the sense different from getInstrMapping.
212212 return UINT_MAX;
213213 }
214214
215 RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping(
215 const RegisterBankInfo::InstructionMapping &RegBankSelect::findBestMapping(
216216 MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings,
217217 SmallVectorImpl &RepairPts) {
218218 assert(!PossibleMappings.empty() &&
219219 "Do not know how to map this instruction");
220220
221 RegisterBankInfo::InstructionMapping *BestMapping = nullptr;
221 const RegisterBankInfo::InstructionMapping *BestMapping = nullptr;
222222 MappingCost Cost = MappingCost::ImpossibleCost();
223223 SmallVector LocalRepairPts;
224 for (RegisterBankInfo::InstructionMapping &CurMapping : PossibleMappings) {
225 MappingCost CurCost = computeMapping(MI, CurMapping, LocalRepairPts, &Cost);
224 for (const RegisterBankInfo::InstructionMapping *CurMapping :
225 PossibleMappings) {
226 MappingCost CurCost =
227 computeMapping(MI, *CurMapping, LocalRepairPts, &Cost);
226228 if (CurCost < Cost) {
227229 DEBUG(dbgs() << "New best: " << CurCost << '\n');
228230 Cost = CurCost;
229 BestMapping = &CurMapping;
231 BestMapping = CurMapping;
230232 RepairPts.clear();
231233 for (RepairingPlacement &RepairPt : LocalRepairPts)
232234 RepairPts.emplace_back(std::move(RepairPt));
236238 // If none of the mapping worked that means they are all impossible.
237239 // Thus, pick the first one and set an impossible repairing point.
238240 // It will trigger the failed isel mode.
239 BestMapping = &(*PossibleMappings.begin());
241 BestMapping = *PossibleMappings.begin();
240242 RepairPts.emplace_back(
241243 RepairingPlacement(MI, 0, *TRI, *this, RepairingPlacement::Impossible));
242244 } else
542544 // Remember the repairing placement for all the operands.
543545 SmallVector RepairPts;
544546
545 RegisterBankInfo::InstructionMapping BestMapping;
547 const RegisterBankInfo::InstructionMapping *BestMapping;
546548 if (OptMode == RegBankSelect::Mode::Fast) {
547 BestMapping = RBI->getInstrMapping(MI);
548 MappingCost DefaultCost = computeMapping(MI, BestMapping, RepairPts);
549 BestMapping = &RBI->getInstrMapping(MI);
550 MappingCost DefaultCost = computeMapping(MI, *BestMapping, RepairPts);
549551 (void)DefaultCost;
550552 if (DefaultCost == MappingCost::ImpossibleCost())
551553 return false;
554556 RBI->getInstrPossibleMappings(MI);
555557 if (PossibleMappings.empty())
556558 return false;
557 BestMapping = std::move(findBestMapping(MI, PossibleMappings, RepairPts));
559 BestMapping = &findBestMapping(MI, PossibleMappings, RepairPts);
558560 }
559561 // Make sure the mapping is valid for MI.
560 assert(BestMapping.verify(MI) && "Invalid instruction mapping");
561
562 DEBUG(dbgs() << "Best Mapping: " << BestMapping << '\n');
562 assert(BestMapping->verify(MI) && "Invalid instruction mapping");
563
564 DEBUG(dbgs() << "Best Mapping: " << *BestMapping << '\n');
563565
564566 // After this call, MI may not be valid anymore.
565567 // Do not use it.
566 return applyMapping(MI, BestMapping, RepairPts);
568 return applyMapping(MI, *BestMapping, RepairPts);
567569 }
568570
569571 bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) {
4444 "Number of operands mappings dynamically created");
4545 STATISTIC(NumOperandsMappingsAccessed,
4646 "Number of operands mappings dynamically accessed");
47 STATISTIC(NumInstructionMappingsCreated,
48 "Number of instruction mappings dynamically created");
49 STATISTIC(NumInstructionMappingsAccessed,
50 "Number of instruction mappings dynamically accessed");
4751
4852 const unsigned RegisterBankInfo::DefaultMappingID = UINT_MAX;
4953 const unsigned RegisterBankInfo::InvalidMappingID = UINT_MAX - 1;
136140 MI.getOpcode() == TargetOpcode::REG_SEQUENCE;
137141 }
138142
139 RegisterBankInfo::InstructionMapping
143 const RegisterBankInfo::InstructionMapping &
140144 RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
141145 // For copies we want to walk over the operands and try to find one
142146 // that has a register bank since the instruction itself will not get
146150 // is important. The rest is not constrained.
147151 unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands();
148152
149 RegisterBankInfo::InstructionMapping Mapping(DefaultMappingID, /*Cost*/ 1,
150 /*OperandsMapping*/ nullptr,
151 NumOperandsForMapping);
152153 const MachineFunction &MF = *MI.getParent()->getParent();
153154 const TargetSubtargetInfo &STI = MF.getSubtarget();
154155 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
189190
190191 if (!IsCopyLike)
191192 // MI does not carry enough information to guess the mapping.
192 return InstructionMapping();
193 return getInvalidInstructionMapping();
193194 continue;
194195 }
195196 }
205206
206207 if (IsCopyLike && !CompleteMapping)
207208 // No way to deduce the type from what we have.
208 return InstructionMapping();
209 return getInvalidInstructionMapping();
209210
210211 assert(CompleteMapping && "Setting an uncomplete mapping");
211 Mapping.setOperandsMapping(getOperandsMapping(OperandsMapping));
212 return Mapping;
212 return getInstructionMapping(
213 DefaultMappingID, /*Cost*/ 1,
214 /*OperandsMapping*/ getOperandsMapping(OperandsMapping),
215 NumOperandsForMapping);
213216 }
214217
215218 /// Hashing function for PartialMapping.
319322 return getOperandsMapping(OpdsMapping.begin(), OpdsMapping.end());
320323 }
321324
322 RegisterBankInfo::InstructionMapping
325 static hash_code
326 hashInstructionMapping(unsigned ID, unsigned Cost,
327 const RegisterBankInfo::ValueMapping *OperandsMapping,
328 unsigned NumOperands) {
329 return hash_combine(ID, Cost, OperandsMapping, NumOperands);
330 }
331
332 const RegisterBankInfo::InstructionMapping &
333 RegisterBankInfo::getInstructionMappingImpl(
334 bool IsInvalid, unsigned ID, unsigned Cost,
335 const RegisterBankInfo::ValueMapping *OperandsMapping,
336 unsigned NumOperands) const {
337 assert(((IsInvalid && ID == InvalidMappingID && Cost == 0 &&
338 OperandsMapping == nullptr && NumOperands == 0) ||
339 !IsInvalid) &&
340 "Mismatch argument for invalid input");
341 ++NumInstructionMappingsAccessed;
342
343 hash_code Hash =
344 hashInstructionMapping(ID, Cost, OperandsMapping, NumOperands);
345 const auto &It = MapOfInstructionMappings.find(Hash);
346 if (It != MapOfInstructionMappings.end())
347 return *It->second;
348
349 ++NumInstructionMappingsCreated;
350
351 auto &InstrMapping = MapOfInstructionMappings[Hash];
352 if (IsInvalid)
353 InstrMapping = llvm::make_unique();
354 else
355 InstrMapping = llvm::make_unique(
356 ID, Cost, OperandsMapping, NumOperands);
357 return *InstrMapping;
358 }
359
360 const RegisterBankInfo::InstructionMapping &
323361 RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
324 RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
362 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
325363 if (Mapping.isValid())
326364 return Mapping;
327365 llvm_unreachable("The target must implement this");
331369 RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const {
332370 InstructionMappings PossibleMappings;
333371 // Put the default mapping first.
334 PossibleMappings.push_back(getInstrMapping(MI));
372 PossibleMappings.push_back(&getInstrMapping(MI));
335373 // Then the alternative mapping, if any.
336374 InstructionMappings AltMappings = getInstrAlternativeMappings(MI);
337 for (InstructionMapping &AltMapping : AltMappings)
338 PossibleMappings.emplace_back(std::move(AltMapping));
375 for (const InstructionMapping *AltMapping : AltMappings)
376 PossibleMappings.push_back(AltMapping);
339377 #ifndef NDEBUG
340 for (const InstructionMapping &Mapping : PossibleMappings)
341 assert(Mapping.verify(MI) && "Mapping is invalid");
378 for (const InstructionMapping *Mapping : PossibleMappings)
379 assert(Mapping->verify(MI) && "Mapping is invalid");
342380 #endif
343381 return PossibleMappings;
344382 }
259259 if (MI.getNumOperands() != 3)
260260 break;
261261 InstructionMappings AltMappings;
262 InstructionMapping GPRMapping(
262 const InstructionMapping &GPRMapping = getInstructionMapping(
263263 /*ID*/ 1, /*Cost*/ 1, getValueMapping(PMI_FirstGPR, Size),
264264 /*NumOperands*/ 3);
265 InstructionMapping FPRMapping(
265 const InstructionMapping &FPRMapping = getInstructionMapping(
266266 /*ID*/ 2, /*Cost*/ 1, getValueMapping(PMI_FirstFPR, Size),
267267 /*NumOperands*/ 3);
268268
269 AltMappings.emplace_back(std::move(GPRMapping));
270 AltMappings.emplace_back(std::move(FPRMapping));
269 AltMappings.push_back(&GPRMapping);
270 AltMappings.push_back(&FPRMapping);
271271 return AltMappings;
272272 }
273273 case TargetOpcode::G_BITCAST: {
281281 break;
282282
283283 InstructionMappings AltMappings;
284 InstructionMapping GPRMapping(
284 const InstructionMapping &GPRMapping = getInstructionMapping(
285285 /*ID*/ 1, /*Cost*/ 1,
286286 getCopyMapping(AArch64::GPRRegBankID, AArch64::GPRRegBankID, Size),
287287 /*NumOperands*/ 2);
288 InstructionMapping FPRMapping(
288 const InstructionMapping &FPRMapping = getInstructionMapping(
289289 /*ID*/ 2, /*Cost*/ 1,
290290 getCopyMapping(AArch64::FPRRegBankID, AArch64::FPRRegBankID, Size),
291291 /*NumOperands*/ 2);
292 InstructionMapping GPRToFPRMapping(
292 const InstructionMapping &GPRToFPRMapping = getInstructionMapping(
293293 /*ID*/ 3,
294294 /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
295295 getCopyMapping(AArch64::FPRRegBankID, AArch64::GPRRegBankID, Size),
296296 /*NumOperands*/ 2);
297 InstructionMapping FPRToGPRMapping(
297 const InstructionMapping &FPRToGPRMapping = getInstructionMapping(
298298 /*ID*/ 3,
299299 /*Cost*/ copyCost(AArch64::GPRRegBank, AArch64::FPRRegBank, Size),
300300 getCopyMapping(AArch64::GPRRegBankID, AArch64::FPRRegBankID, Size),
301301 /*NumOperands*/ 2);
302302
303 AltMappings.emplace_back(std::move(GPRMapping));
304 AltMappings.emplace_back(std::move(FPRMapping));
305 AltMappings.emplace_back(std::move(GPRToFPRMapping));
306 AltMappings.emplace_back(std::move(FPRToGPRMapping));
303 AltMappings.push_back(&GPRMapping);
304 AltMappings.push_back(&FPRMapping);
305 AltMappings.push_back(&GPRToFPRMapping);
306 AltMappings.push_back(&FPRToGPRMapping);
307307 return AltMappings;
308308 }
309309 case TargetOpcode::G_LOAD: {
317317 break;
318318
319319 InstructionMappings AltMappings;
320 InstructionMapping GPRMapping(
320 const InstructionMapping &GPRMapping = getInstructionMapping(
321321 /*ID*/ 1, /*Cost*/ 1,
322322 getOperandsMapping({getValueMapping(PMI_FirstGPR, Size),
323323 // Addresses are GPR 64-bit.
324324 getValueMapping(PMI_FirstGPR, 64)}),
325325 /*NumOperands*/ 2);
326 InstructionMapping FPRMapping(
326 const InstructionMapping &FPRMapping = getInstructionMapping(
327327 /*ID*/ 2, /*Cost*/ 1,
328328 getOperandsMapping({getValueMapping(PMI_FirstFPR, Size),
329329 // Addresses are GPR 64-bit.
330330 getValueMapping(PMI_FirstGPR, 64)}),
331331 /*NumOperands*/ 2);
332332
333 AltMappings.emplace_back(std::move(GPRMapping));
334 AltMappings.emplace_back(std::move(FPRMapping));
333 AltMappings.push_back(&GPRMapping);
334 AltMappings.push_back(&FPRMapping);
335335 return AltMappings;
336336 }
337337 default:
372372 return false;
373373 }
374374
375 RegisterBankInfo::InstructionMapping
376 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(const MachineInstr &MI) {
375 const RegisterBankInfo::InstructionMapping &
376 AArch64RegisterBankInfo::getSameKindOfOperandsMapping(
377 const MachineInstr &MI) const {
377378 const unsigned Opc = MI.getOpcode();
378379 const MachineFunction &MF = *MI.getParent()->getParent();
379380 const MachineRegisterInfo &MRI = MF.getRegInfo();
410411 }
411412 #endif // End NDEBUG.
412413
413 return InstructionMapping{DefaultMappingID, 1, getValueMapping(RBIdx, Size),
414 NumOperands};
415 }
416
417 RegisterBankInfo::InstructionMapping
414 return getInstructionMapping(DefaultMappingID, 1,
415 getValueMapping(RBIdx, Size), NumOperands);
416 }
417
418 const RegisterBankInfo::InstructionMapping &
418419 AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
419420 const unsigned Opc = MI.getOpcode();
420421 const MachineFunction &MF = *MI.getParent()->getParent();
423424 // Try the default logic for non-generic instructions that are either copies
424425 // or already have some operands assigned to banks.
425426 if (!isPreISelGenericOpcode(Opc)) {
426 RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
427 const RegisterBankInfo::InstructionMapping &Mapping =
428 getInstrMappingImpl(MI);
427429 if (Mapping.isValid())
428430 return Mapping;
429431 }
461463 DstIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
462464 const RegisterBank &SrcRB =
463465 SrcIsGPR ? AArch64::GPRRegBank : AArch64::FPRRegBank;
464 return InstructionMapping{
466 return getInstructionMapping(
465467 DefaultMappingID, copyCost(DstRB, SrcRB, Size),
466468 getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
467 /*NumOperands*/ 2};
469 /*NumOperands*/ 2);
468470 }
469471 case TargetOpcode::G_SEQUENCE:
470472 // FIXME: support this, but the generic code is really not going to do
471473 // anything sane.
472 return InstructionMapping();
474 return getInvalidInstructionMapping();
473475 default:
474476 break;
475477 }
532534 }
533535
534536 // Finally construct the computed mapping.
535 RegisterBankInfo::InstructionMapping Mapping =
536 InstructionMapping{DefaultMappingID, Cost, nullptr, NumOperands};
537537 SmallVector OpdsMapping(NumOperands);
538538 for (unsigned Idx = 0; Idx < NumOperands; ++Idx) {
539539 if (MI.getOperand(Idx).isReg() && MI.getOperand(Idx).getReg()) {
540540 auto Mapping = getValueMapping(OpRegBankIdx[Idx], OpSize[Idx]);
541541 if (!Mapping->isValid())
542 return InstructionMapping();
542 return getInvalidInstructionMapping();
543543
544544 OpdsMapping[Idx] = Mapping;
545545 }
546546 }
547547
548 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
549 return Mapping;
550 }
548 return getInstructionMapping(DefaultMappingID, Cost,
549 getOperandsMapping(OpdsMapping), NumOperands);
550 }
9797 ///
9898 /// \return An InstructionMappings with a statically allocated
9999 /// OperandsMapping.
100 static InstructionMapping
101 getSameKindOfOperandsMapping(const MachineInstr &MI);
100 const InstructionMapping &
101 getSameKindOfOperandsMapping(const MachineInstr &MI) const;
102102
103103 public:
104104 AArch64RegisterBankInfo(const TargetRegisterInfo &TRI);
112112 InstructionMappings
113113 getInstrAlternativeMappings(const MachineInstr &MI) const override;
114114
115 InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
115 const InstructionMapping &
116 getInstrMapping(const MachineInstr &MI) const override;
116117 };
117118 } // End llvm namespace.
118119 #endif
8181 switch (MI.getOpcode()) {
8282 case TargetOpcode::G_LOAD: {
8383 // FIXME: Should we be hard coding the size for these mappings?
84 InstructionMapping SSMapping(1, 1,
85 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
86 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
87 2); // Num Operands
88 AltMappings.emplace_back(std::move(SSMapping));
89
90 InstructionMapping VVMapping(2, 1,
91 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
92 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
93 2); // Num Operands
94 AltMappings.emplace_back(std::move(VVMapping));
84 const InstructionMapping &SSMapping = getInstructionMapping(
85 1, 1, getOperandsMapping(
86 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size),
87 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
88 2); // Num Operands
89 AltMappings.push_back(&SSMapping);
90
91 const InstructionMapping &VVMapping = getInstructionMapping(
92 2, 1, getOperandsMapping(
93 {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
94 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 64)}),
95 2); // Num Operands
96 AltMappings.push_back(&VVMapping);
9597
9698 // FIXME: Should this be the pointer-size (64-bits) or the size of the
9799 // register that will hold the bufffer resourc (128-bits).
98 InstructionMapping VSMapping(3, 1,
99 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
100 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
101 2); // Num Operands
102 AltMappings.emplace_back(std::move(VSMapping));
100 const InstructionMapping &VSMapping = getInstructionMapping(
101 3, 1, getOperandsMapping(
102 {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size),
103 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 64)}),
104 2); // Num Operands
105 AltMappings.push_back(&VSMapping);
103106
104107 return AltMappings;
105108
123126 return AMDGPU::isUniformMMO(MMO);
124127 }
125128
126 RegisterBankInfo::InstructionMapping
129 const RegisterBankInfo::InstructionMapping &
127130 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const {
128131
129132 const MachineFunction &MF = *MI.getParent()->getParent();
130133 const MachineRegisterInfo &MRI = MF.getRegInfo();
131 RegisterBankInfo::InstructionMapping Mapping =
132 InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
133134 SmallVector OpdsMapping(MI.getNumOperands());
134135 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI);
135136 unsigned PtrSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI);
149150
150151 OpdsMapping[0] = ValMapping;
151152 OpdsMapping[1] = PtrMapping;
152 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
153 const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
154 1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands());
153155 return Mapping;
154156
155157 // FIXME: Do we want to add a mapping for FLAT load, or should we just
156158 // handle that during instruction selection?
157159 }
158160
159 RegisterBankInfo::InstructionMapping
161 const RegisterBankInfo::InstructionMapping &
160162 AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
161 RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI);
163 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI);
162164
163165 if (Mapping.isValid())
164166 return Mapping;
165167
166168 const MachineFunction &MF = *MI.getParent()->getParent();
167169 const MachineRegisterInfo &MRI = MF.getRegInfo();
168 Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
169170 SmallVector OpdsMapping(MI.getNumOperands());
170171
172 bool IsComplete = true;
171173 switch (MI.getOpcode()) {
172 default: break;
174 default:
175 IsComplete = false;
176 break;
173177 case AMDGPU::G_CONSTANT: {
174178 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
175179 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
176 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
177 return Mapping;
180 break;
178181 }
179182 case AMDGPU::G_GEP: {
180183 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
184187 unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits();
185188 OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size);
186189 }
187 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
188 return Mapping;
190 break;
189191 }
190192 case AMDGPU::G_STORE: {
191193 assert(MI.getOperand(0).isReg());
202204
203205 OpdsMapping[0] = ValMapping;
204206 OpdsMapping[1] = PtrMapping;
205 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
206 return Mapping;
207 break;
207208 }
208209
209210 case AMDGPU::G_LOAD:
210211 return getInstrMappingForLoad(MI);
211212 }
212213
213 unsigned BankID = AMDGPU::SGPRRegBankID;
214
215 Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};
216 unsigned Size = 0;
217 for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
218 // If the operand is not a register default to the size of the previous
219 // operand.
220 // FIXME: Can't we pull the types from the MachineInstr rather than the
221 // operands.
222 if (MI.getOperand(Idx).isReg())
223 Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
224 OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
225 }
226 Mapping.setOperandsMapping(getOperandsMapping(OpdsMapping));
227
228 return Mapping;
229 }
214 if (!IsComplete) {
215 unsigned BankID = AMDGPU::SGPRRegBankID;
216
217 unsigned Size = 0;
218 for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {
219 // If the operand is not a register default to the size of the previous
220 // operand.
221 // FIXME: Can't we pull the types from the MachineInstr rather than the
222 // operands.
223 if (MI.getOperand(Idx).isReg())
224 Size = getSizeInBits(MI.getOperand(Idx).getReg(), MRI, *TRI);
225 OpdsMapping.push_back(AMDGPU::getValueMapping(BankID, Size));
226 }
227 }
228 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping),
229 MI.getNumOperands());
230 }
4343 /// See RegisterBankInfo::applyMapping.
4444 void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
4545
46 RegisterBankInfo::InstructionMapping
46 const RegisterBankInfo::InstructionMapping &
4747 getInstrMappingForLoad(const MachineInstr &MI) const;
4848
4949 public:
5858 InstructionMappings
5959 getInstrAlternativeMappings(const MachineInstr &MI) const override;
6060
61 InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
61 const InstructionMapping &
62 getInstrMapping(const MachineInstr &MI) const override;
6263 };
6364 } // End llvm namespace.
6465 #endif
195195 llvm_unreachable("Switch should handle all register classes");
196196 }
197197
198 RegisterBankInfo::InstructionMapping
198 const RegisterBankInfo::InstructionMapping &
199199 ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
200200 auto Opc = MI.getOpcode();
201201
202202 // Try the default logic for non-generic instructions that are either copies
203203 // or already have some operands assigned to banks.
204204 if (!isPreISelGenericOpcode(Opc)) {
205 InstructionMapping Mapping = getInstrMappingImpl(MI);
205 const InstructionMapping &Mapping = getInstrMappingImpl(MI);
206206 if (Mapping.isValid())
207207 return Mapping;
208208 }
257257 LLT Ty2 = MRI.getType(MI.getOperand(3).getReg());
258258 if (Ty.getSizeInBits() != 64 || Ty1.getSizeInBits() != 32 ||
259259 Ty2.getSizeInBits() != 32)
260 return InstructionMapping{};
260 return getInvalidInstructionMapping();
261261 OperandsMapping =
262262 getOperandsMapping({&ARM::ValueMappings[ARM::DPR3OpsIdx],
263263 &ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr,
270270 LLT Ty1 = MRI.getType(MI.getOperand(1).getReg());
271271 if (Ty.getSizeInBits() != 32 || Ty1.getSizeInBits() != 64 ||
272272 MI.getOperand(2).getImm() % 32 != 0)
273 return InstructionMapping{};
273 return getInvalidInstructionMapping();
274274 OperandsMapping = getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx],
275275 &ARM::ValueMappings[ARM::DPR3OpsIdx],
276276 nullptr, nullptr});
277277 break;
278278 }
279279 default:
280 return InstructionMapping{};
280 return getInvalidInstructionMapping();
281281 }
282282
283283 #ifndef NDEBUG
291291 }
292292 #endif
293293
294 return InstructionMapping{DefaultMappingID, /*Cost=*/1, OperandsMapping,
295 NumOperands};
296 }
294 return getInstructionMapping(DefaultMappingID, /*Cost=*/1, OperandsMapping,
295 NumOperands);
296 }
3535 const RegisterBank &
3636 getRegBankFromRegClass(const TargetRegisterClass &RC) const override;
3737
38 InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
38 const InstructionMapping &
39 getInstrMapping(const MachineInstr &MI) const override;
3940 };
4041 } // End llvm namespace.
4142 #endif
138138 return true;
139139 }
140140
141 RegisterBankInfo::InstructionMapping
142 X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI, bool isFP) {
141 const RegisterBankInfo::InstructionMapping &
142 X86RegisterBankInfo::getSameOperandsMapping(const MachineInstr &MI,
143 bool isFP) const {
143144 const MachineFunction &MF = *MI.getParent()->getParent();
144145 const MachineRegisterInfo &MRI = MF.getRegInfo();
145146
151152 llvm_unreachable("Unsupported operand mapping yet.");
152153
153154 auto Mapping = getValueMapping(getPartialMappingIdx(Ty, isFP), 3);
154 return InstructionMapping{DefaultMappingID, 1, Mapping, NumOperands};
155 }
156
157 RegisterBankInfo::InstructionMapping
155 return getInstructionMapping(DefaultMappingID, 1, Mapping, NumOperands);
156 }
157
158 const RegisterBankInfo::InstructionMapping &
158159 X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
159160 const MachineFunction &MF = *MI.getParent()->getParent();
160161 const MachineRegisterInfo &MRI = MF.getRegInfo();
163164 // Try the default logic for non-generic instructions that are either copies
164165 // or already have some operands assigned to banks.
165166 if (!isPreISelGenericOpcode(Opc)) {
166 InstructionMapping Mapping = getInstrMappingImpl(MI);
167 const InstructionMapping &Mapping = getInstrMappingImpl(MI);
167168 if (Mapping.isValid())
168169 return Mapping;
169170 }
192193 // Finally construct the computed mapping.
193194 SmallVector OpdsMapping(NumOperands);
194195 if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
195 return InstructionMapping();
196
197 return InstructionMapping{DefaultMappingID, /* Cost */ 1,
198 getOperandsMapping(OpdsMapping), NumOperands};
196 return getInvalidInstructionMapping();
197
198 return getInstructionMapping(DefaultMappingID, /* Cost */ 1,
199 getOperandsMapping(OpdsMapping), NumOperands);
199200 }
200201
201202 void X86RegisterBankInfo::applyMappingImpl(
230231 if (!getInstrValueMapping(MI, OpRegBankIdx, OpdsMapping))
231232 break;
232233
233 RegisterBankInfo::InstructionMapping Mapping = InstructionMapping{
234 /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands};
234 const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping(
235 /*ID*/ 1, /*Cost*/ 1, getOperandsMapping(OpdsMapping), NumOperands);
235236 InstructionMappings AltMappings;
236 AltMappings.emplace_back(std::move(Mapping));
237 AltMappings.push_back(&Mapping);
237238 return AltMappings;
238239 }
239240 default:
4545 /// Get an instruction mapping.
4646 /// \return An InstructionMappings with a statically allocated
4747 /// OperandsMapping.
48 static InstructionMapping getSameOperandsMapping(const MachineInstr &MI,
49 bool isFP);
48 const InstructionMapping &getSameOperandsMapping(const MachineInstr &MI,
49 bool isFP) const;
5050
5151 /// Track the bank of each instruction operand(register)
5252 static void
7373 /// See RegisterBankInfo::applyMapping.
7474 void applyMappingImpl(const OperandsMapper &OpdMapper) const override;
7575
76 InstructionMapping getInstrMapping(const MachineInstr &MI) const override;
76 const InstructionMapping &
77 getInstrMapping(const MachineInstr &MI) const override;
7778 };
7879
7980 } // namespace llvm