Line data Source code
1 : //=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU ------*- C++ -*-====//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //==-----------------------------------------------------------------------===//
9 : //
10 : /// \file
11 : /// AMDGPU specific subclass of TargetSubtarget.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
16 : #define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
17 :
18 : #include "AMDGPU.h"
19 : #include "AMDGPUCallLowering.h"
20 : #include "R600FrameLowering.h"
21 : #include "R600ISelLowering.h"
22 : #include "R600InstrInfo.h"
23 : #include "SIFrameLowering.h"
24 : #include "SIISelLowering.h"
25 : #include "SIInstrInfo.h"
26 : #include "Utils/AMDGPUBaseInfo.h"
27 : #include "llvm/ADT/Triple.h"
28 : #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
29 : #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
30 : #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
31 : #include "llvm/CodeGen/MachineFunction.h"
32 : #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
33 : #include "llvm/MC/MCInstrItineraries.h"
34 : #include "llvm/Support/MathExtras.h"
35 : #include <cassert>
36 : #include <cstdint>
37 : #include <memory>
38 : #include <utility>
39 :
40 : #define GET_SUBTARGETINFO_HEADER
41 : #include "AMDGPUGenSubtargetInfo.inc"
42 : #define GET_SUBTARGETINFO_HEADER
43 : #include "R600GenSubtargetInfo.inc"
44 :
45 : namespace llvm {
46 :
47 : class StringRef;
48 :
49 : class AMDGPUSubtarget {
50 : public:
51 : enum Generation {
52 : R600 = 0,
53 : R700 = 1,
54 : EVERGREEN = 2,
55 : NORTHERN_ISLANDS = 3,
56 : SOUTHERN_ISLANDS = 4,
57 : SEA_ISLANDS = 5,
58 : VOLCANIC_ISLANDS = 6,
59 : GFX9 = 7
60 : };
61 :
62 : private:
63 : Triple TargetTriple;
64 :
65 : protected:
66 : bool Has16BitInsts;
67 : bool HasMadMixInsts;
68 : bool FP32Denormals;
69 : bool FPExceptions;
70 : bool HasSDWA;
71 : bool HasVOP3PInsts;
72 : bool HasMulI24;
73 : bool HasMulU24;
74 : bool HasInv2PiInlineImm;
75 : bool HasFminFmaxLegacy;
76 : bool EnablePromoteAlloca;
77 : bool HasTrigReducedRange;
78 : int LocalMemorySize;
79 : unsigned WavefrontSize;
80 :
81 : public:
82 : AMDGPUSubtarget(const Triple &TT);
83 :
84 : static const AMDGPUSubtarget &get(const MachineFunction &MF);
85 : static const AMDGPUSubtarget &get(const TargetMachine &TM,
86 : const Function &F);
87 :
88 : /// \returns Default range flat work group size for a calling convention.
89 : std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const;
90 :
91 : /// \returns Subtarget's default pair of minimum/maximum flat work group sizes
92 : /// for function \p F, or minimum/maximum flat work group sizes explicitly
93 : /// requested using "amdgpu-flat-work-group-size" attribute attached to
94 : /// function \p F.
95 : ///
96 : /// \returns Subtarget's default values if explicitly requested values cannot
97 : /// be converted to integer, or violate subtarget's specifications.
98 : std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const;
99 :
100 : /// \returns Subtarget's default pair of minimum/maximum number of waves per
101 : /// execution unit for function \p F, or minimum/maximum number of waves per
102 : /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute
103 : /// attached to function \p F.
104 : ///
105 : /// \returns Subtarget's default values if explicitly requested values cannot
106 : /// be converted to integer, violate subtarget's specifications, or are not
107 : /// compatible with minimum/maximum number of waves limited by flat work group
108 : /// size, register usage, and/or lds usage.
109 : std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const;
110 :
111 : /// Return the amount of LDS that can be used that will not restrict the
112 : /// occupancy lower than WaveCount.
113 : unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
114 : const Function &) const;
115 :
116 : /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if
117 : /// the given LDS memory size is the only constraint.
118 : unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const;
119 :
120 : unsigned getOccupancyWithLocalMemSize(const MachineFunction &MF) const;
121 :
122 : bool isAmdHsaOS() const {
123 139357 : return TargetTriple.getOS() == Triple::AMDHSA;
124 : }
125 :
126 : bool isAmdPalOS() const {
127 22070 : return TargetTriple.getOS() == Triple::AMDPAL;
128 : }
129 :
130 : bool isMesa3DOS() const {
131 37358 : return TargetTriple.getOS() == Triple::Mesa3D;
132 : }
133 :
134 : bool isMesaKernel(const Function &F) const {
135 106455 : return isMesa3DOS() && !AMDGPU::isShader(F.getCallingConv());
136 : }
137 :
138 129139 : bool isAmdHsaOrMesa(const Function &F) const {
139 129139 : return isAmdHsaOS() || isMesaKernel(F);
140 : }
141 :
142 0 : bool has16BitInsts() const {
143 0 : return Has16BitInsts;
144 : }
145 :
146 0 : bool hasMadMixInsts() const {
147 0 : return HasMadMixInsts;
148 : }
149 :
150 0 : bool hasFP32Denormals() const {
151 0 : return FP32Denormals;
152 : }
153 :
154 0 : bool hasFPExceptions() const {
155 0 : return FPExceptions;
156 : }
157 :
158 0 : bool hasSDWA() const {
159 0 : return HasSDWA;
160 : }
161 :
162 0 : bool hasVOP3PInsts() const {
163 0 : return HasVOP3PInsts;
164 : }
165 :
166 0 : bool hasMulI24() const {
167 0 : return HasMulI24;
168 : }
169 :
170 0 : bool hasMulU24() const {
171 0 : return HasMulU24;
172 : }
173 :
174 0 : bool hasInv2PiInlineImm() const {
175 0 : return HasInv2PiInlineImm;
176 : }
177 :
178 0 : bool hasFminFmaxLegacy() const {
179 0 : return HasFminFmaxLegacy;
180 : }
181 :
182 0 : bool hasTrigReducedRange() const {
183 0 : return HasTrigReducedRange;
184 : }
185 :
186 0 : bool isPromoteAllocaEnabled() const {
187 0 : return EnablePromoteAlloca;
188 : }
189 :
190 0 : unsigned getWavefrontSize() const {
191 0 : return WavefrontSize;
192 : }
193 :
194 0 : int getLocalMemorySize() const {
195 0 : return LocalMemorySize;
196 : }
197 :
198 : unsigned getAlignmentForImplicitArgPtr() const {
199 964 : return isAmdHsaOS() ? 8 : 4;
200 : }
201 :
202 : /// Returns the offset in bytes from the start of the input buffer
203 : /// of the first explicit kernel argument.
204 : unsigned getExplicitKernelArgOffset(const Function &F) const {
205 53230 : return isAmdHsaOrMesa(F) ? 0 : 36;
206 : }
207 :
208 : /// \returns Maximum number of work groups per compute unit supported by the
209 : /// subtarget and limited by given \p FlatWorkGroupSize.
210 : virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const = 0;
211 :
212 : /// \returns Minimum flat work group size supported by the subtarget.
213 : virtual unsigned getMinFlatWorkGroupSize() const = 0;
214 :
215 : /// \returns Maximum flat work group size supported by the subtarget.
216 : virtual unsigned getMaxFlatWorkGroupSize() const = 0;
217 :
218 : /// \returns Maximum number of waves per execution unit supported by the
219 : /// subtarget and limited by given \p FlatWorkGroupSize.
220 : virtual unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const = 0;
221 :
222 : /// \returns Minimum number of waves per execution unit supported by the
223 : /// subtarget.
224 : virtual unsigned getMinWavesPerEU() const = 0;
225 :
226 0 : unsigned getMaxWavesPerEU() const { return 10; }
227 :
228 : /// Creates value range metadata on an workitemid.* inrinsic call or load.
229 : bool makeLIDRangeMetadata(Instruction *I) const;
230 :
231 : /// \returns Number of bytes of arguments that are passed to a shader or
232 : /// kernel in addition to the explicit ones declared for the function.
233 19817 : unsigned getImplicitArgNumBytes(const Function &F) const {
234 : if (isMesaKernel(F))
235 : return 16;
236 19651 : return AMDGPU::getIntegerAttribute(F, "amdgpu-implicitarg-num-bytes", 0);
237 : }
238 : uint64_t getExplicitKernArgSize(const Function &F,
239 : unsigned &MaxAlign) const;
240 : unsigned getKernArgSegmentSize(const Function &F,
241 : unsigned &MaxAlign) const;
242 :
243 4899 : virtual ~AMDGPUSubtarget() {}
244 : };
245 :
246 7443 : class GCNSubtarget : public AMDGPUGenSubtargetInfo,
247 : public AMDGPUSubtarget {
248 : public:
249 : enum {
250 : ISAVersion0_0_0,
251 : ISAVersion6_0_0,
252 : ISAVersion6_0_1,
253 : ISAVersion7_0_0,
254 : ISAVersion7_0_1,
255 : ISAVersion7_0_2,
256 : ISAVersion7_0_3,
257 : ISAVersion7_0_4,
258 : ISAVersion8_0_1,
259 : ISAVersion8_0_2,
260 : ISAVersion8_0_3,
261 : ISAVersion8_1_0,
262 : ISAVersion9_0_0,
263 : ISAVersion9_0_2,
264 : ISAVersion9_0_4,
265 : ISAVersion9_0_6,
266 : };
267 :
268 : enum TrapHandlerAbi {
269 : TrapHandlerAbiNone = 0,
270 : TrapHandlerAbiHsa = 1
271 : };
272 :
273 : enum TrapID {
274 : TrapIDHardwareReserved = 0,
275 : TrapIDHSADebugTrap = 1,
276 : TrapIDLLVMTrap = 2,
277 : TrapIDLLVMDebugTrap = 3,
278 : TrapIDDebugBreakpoint = 7,
279 : TrapIDDebugReserved8 = 8,
280 : TrapIDDebugReservedFE = 0xfe,
281 : TrapIDDebugReservedFF = 0xff
282 : };
283 :
284 : enum TrapRegValues {
285 : LLVMTrapHandlerRegValue = 1
286 : };
287 :
288 : private:
289 : /// GlobalISel related APIs.
290 : std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
291 : std::unique_ptr<InstructionSelector> InstSelector;
292 : std::unique_ptr<LegalizerInfo> Legalizer;
293 : std::unique_ptr<RegisterBankInfo> RegBankInfo;
294 :
295 : protected:
296 : // Basic subtarget description.
297 : Triple TargetTriple;
298 : unsigned Gen;
299 : unsigned IsaVersion;
300 : InstrItineraryData InstrItins;
301 : int LDSBankCount;
302 : unsigned MaxPrivateElementSize;
303 :
304 : // Possibly statically set by tablegen, but may want to be overridden.
305 : bool FastFMAF32;
306 : bool HalfRate64Ops;
307 :
308 : // Dynamially set bits that enable features.
309 : bool FP64FP16Denormals;
310 : bool DX10Clamp;
311 : bool FlatForGlobal;
312 : bool AutoWaitcntBeforeBarrier;
313 : bool CodeObjectV3;
314 : bool UnalignedScratchAccess;
315 : bool UnalignedBufferAccess;
316 : bool HasApertureRegs;
317 : bool EnableXNACK;
318 : bool TrapHandler;
319 : bool DebuggerInsertNops;
320 : bool DebuggerEmitPrologue;
321 :
322 : // Used as options.
323 : bool EnableHugePrivateBuffer;
324 : bool EnableVGPRSpilling;
325 : bool EnableLoadStoreOpt;
326 : bool EnableUnsafeDSOffsetFolding;
327 : bool EnableSIScheduler;
328 : bool EnableDS128;
329 : bool DumpCode;
330 :
331 : // Subtarget statically properties set by tablegen
332 : bool FP64;
333 : bool FMA;
334 : bool MIMG_R128;
335 : bool IsGCN;
336 : bool GCN3Encoding;
337 : bool CIInsts;
338 : bool VIInsts;
339 : bool GFX9Insts;
340 : bool SGPRInitBug;
341 : bool HasSMemRealTime;
342 : bool HasIntClamp;
343 : bool HasFmaMixInsts;
344 : bool HasMovrel;
345 : bool HasVGPRIndexMode;
346 : bool HasScalarStores;
347 : bool HasScalarAtomics;
348 : bool HasSDWAOmod;
349 : bool HasSDWAScalar;
350 : bool HasSDWASdst;
351 : bool HasSDWAMac;
352 : bool HasSDWAOutModsVOPC;
353 : bool HasDPP;
354 : bool HasR128A16;
355 : bool HasDLInsts;
356 : bool D16PreservesUnusedBits;
357 : bool FlatAddressSpace;
358 : bool FlatInstOffsets;
359 : bool FlatGlobalInsts;
360 : bool FlatScratchInsts;
361 : bool AddNoCarryInsts;
362 : bool HasUnpackedD16VMem;
363 : bool R600ALUInst;
364 : bool CaymanISA;
365 : bool CFALUBug;
366 : bool HasVertexCache;
367 : short TexVTXClauseSize;
368 : bool ScalarizeGlobal;
369 :
370 : // Dummy feature to use for assembler in tablegen.
371 : bool FeatureDisable;
372 :
373 : SelectionDAGTargetInfo TSInfo;
374 : private:
375 : SIInstrInfo InstrInfo;
376 : SITargetLowering TLInfo;
377 : SIFrameLowering FrameLowering;
378 :
379 : public:
380 : GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
381 : const GCNTargetMachine &TM);
382 : ~GCNSubtarget() override;
383 :
384 : GCNSubtarget &initializeSubtargetDependencies(const Triple &TT,
385 : StringRef GPU, StringRef FS);
386 :
387 5449312 : const SIInstrInfo *getInstrInfo() const override {
388 5449312 : return &InstrInfo;
389 : }
390 :
391 262679 : const SIFrameLowering *getFrameLowering() const override {
392 262679 : return &FrameLowering;
393 : }
394 :
395 1298529 : const SITargetLowering *getTargetLowering() const override {
396 1298529 : return &TLInfo;
397 : }
398 :
399 33229215 : const SIRegisterInfo *getRegisterInfo() const override {
400 33229215 : return &InstrInfo.getRegisterInfo();
401 : }
402 :
403 60 : const CallLowering *getCallLowering() const override {
404 60 : return CallLoweringInfo.get();
405 : }
406 :
407 43 : const InstructionSelector *getInstructionSelector() const override {
408 43 : return InstSelector.get();
409 : }
410 :
411 93 : const LegalizerInfo *getLegalizerInfo() const override {
412 93 : return Legalizer.get();
413 : }
414 :
415 458 : const RegisterBankInfo *getRegBankInfo() const override {
416 458 : return RegBankInfo.get();
417 : }
418 :
419 : // Nothing implemented, just prevent crashes on use.
420 24132 : const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
421 24132 : return &TSInfo;
422 : }
423 :
424 57749 : const InstrItineraryData *getInstrItineraryData() const override {
425 57749 : return &InstrItins;
426 : }
427 :
428 : void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
429 :
430 0 : Generation getGeneration() const {
431 0 : return (Generation)Gen;
432 : }
433 :
434 0 : unsigned getWavefrontSizeLog2() const {
435 0 : return Log2_32(WavefrontSize);
436 : }
437 :
438 0 : int getLDSBankCount() const {
439 0 : return LDSBankCount;
440 : }
441 :
442 0 : unsigned getMaxPrivateElementSize() const {
443 0 : return MaxPrivateElementSize;
444 : }
445 :
446 : bool hasIntClamp() const {
447 : return HasIntClamp;
448 : }
449 :
450 : bool hasFP64() const {
451 : return FP64;
452 : }
453 :
454 : bool hasMIMG_R128() const {
455 : return MIMG_R128;
456 : }
457 :
458 : bool hasHWFP64() const {
459 : return FP64;
460 : }
461 :
462 0 : bool hasFastFMAF32() const {
463 0 : return FastFMAF32;
464 : }
465 :
466 0 : bool hasHalfRate64Ops() const {
467 0 : return HalfRate64Ops;
468 : }
469 :
470 : bool hasAddr64() const {
471 92946 : return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS);
472 : }
473 :
474 0 : bool hasBFE() const {
475 0 : return true;
476 : }
477 :
478 0 : bool hasBFI() const {
479 0 : return true;
480 : }
481 :
482 : bool hasBFM() const {
483 : return hasBFE();
484 : }
485 :
486 0 : bool hasBCNT(unsigned Size) const {
487 0 : return true;
488 : }
489 :
490 0 : bool hasFFBL() const {
491 0 : return true;
492 : }
493 :
494 0 : bool hasFFBH() const {
495 0 : return true;
496 : }
497 :
498 : bool hasMed3_16() const {
499 9 : return getGeneration() >= AMDGPUSubtarget::GFX9;
500 : }
501 :
502 : bool hasMin3Max3_16() const {
503 356 : return getGeneration() >= AMDGPUSubtarget::GFX9;
504 : }
505 :
506 0 : bool hasFmaMixInsts() const {
507 0 : return HasFmaMixInsts;
508 : }
509 :
510 : bool hasCARRY() const {
511 : return true;
512 : }
513 :
514 : bool hasFMA() const {
515 : return FMA;
516 : }
517 :
518 : TrapHandlerAbi getTrapHandlerAbi() const {
519 36 : return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone;
520 : }
521 :
522 0 : bool enableHugePrivateBuffer() const {
523 0 : return EnableHugePrivateBuffer;
524 : }
525 :
526 0 : bool unsafeDSOffsetFoldingEnabled() const {
527 0 : return EnableUnsafeDSOffsetFolding;
528 : }
529 :
530 0 : bool dumpCode() const {
531 0 : return DumpCode;
532 : }
533 :
534 : /// Return the amount of LDS that can be used that will not restrict the
535 : /// occupancy lower than WaveCount.
536 : unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
537 : const Function &) const;
538 :
539 0 : bool hasFP16Denormals() const {
540 0 : return FP64FP16Denormals;
541 : }
542 :
543 0 : bool hasFP64Denormals() const {
544 0 : return FP64FP16Denormals;
545 : }
546 :
547 : bool supportsMinMaxDenormModes() const {
548 67 : return getGeneration() >= AMDGPUSubtarget::GFX9;
549 : }
550 :
551 0 : bool enableDX10Clamp() const {
552 0 : return DX10Clamp;
553 : }
554 :
555 0 : bool enableIEEEBit(const MachineFunction &MF) const {
556 114134 : return AMDGPU::isCompute(MF.getFunction().getCallingConv());
557 : }
558 :
559 0 : bool useFlatForGlobal() const {
560 0 : return FlatForGlobal;
561 : }
562 :
563 : /// \returns If target supports ds_read/write_b128 and user enables generation
564 : /// of ds_read/write_b128.
565 0 : bool useDS128() const {
566 51976 : return CIInsts && EnableDS128;
567 : }
568 :
569 : /// \returns If MUBUF instructions always perform range checking, even for
570 : /// buffer resources used for private memory access.
571 : bool privateMemoryResourceIsRangeChecked() const {
572 4874 : return getGeneration() < AMDGPUSubtarget::GFX9;
573 : }
574 :
575 0 : bool hasAutoWaitcntBeforeBarrier() const {
576 0 : return AutoWaitcntBeforeBarrier;
577 : }
578 :
579 0 : bool hasCodeObjectV3() const {
580 0 : return CodeObjectV3;
581 : }
582 :
583 0 : bool hasUnalignedBufferAccess() const {
584 0 : return UnalignedBufferAccess;
585 : }
586 :
587 0 : bool hasUnalignedScratchAccess() const {
588 0 : return UnalignedScratchAccess;
589 : }
590 :
591 0 : bool hasApertureRegs() const {
592 0 : return HasApertureRegs;
593 : }
594 :
595 0 : bool isTrapHandlerEnabled() const {
596 0 : return TrapHandler;
597 : }
598 :
599 0 : bool isXNACKEnabled() const {
600 0 : return EnableXNACK;
601 : }
602 :
603 0 : bool hasFlatAddressSpace() const {
604 0 : return FlatAddressSpace;
605 : }
606 :
607 0 : bool hasFlatInstOffsets() const {
608 0 : return FlatInstOffsets;
609 : }
610 :
611 0 : bool hasFlatGlobalInsts() const {
612 0 : return FlatGlobalInsts;
613 : }
614 :
615 : bool hasFlatScratchInsts() const {
616 : return FlatScratchInsts;
617 : }
618 :
619 : bool hasFlatLgkmVMemCountInOrder() const {
620 1262 : return getGeneration() > GFX9;
621 : }
622 :
623 : bool hasD16LoadStore() const {
624 : return getGeneration() >= GFX9;
625 : }
626 :
627 : /// Return if most LDS instructions have an m0 use that require m0 to be
628 : /// iniitalized.
629 : bool ldsRequiresM0Init() const {
630 29288 : return getGeneration() < GFX9;
631 : }
632 :
633 0 : bool hasAddNoCarry() const {
634 0 : return AddNoCarryInsts;
635 : }
636 :
637 0 : bool hasUnpackedD16VMem() const {
638 0 : return HasUnpackedD16VMem;
639 : }
640 :
641 : // Covers VS/PS/CS graphics shaders
642 : bool isMesaGfxShader(const Function &F) const {
643 18452 : return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv());
644 : }
645 :
646 : bool hasMad64_32() const {
647 1644 : return getGeneration() >= SEA_ISLANDS;
648 : }
649 :
650 0 : bool hasSDWAOmod() const {
651 0 : return HasSDWAOmod;
652 : }
653 :
654 0 : bool hasSDWAScalar() const {
655 0 : return HasSDWAScalar;
656 : }
657 :
658 0 : bool hasSDWASdst() const {
659 0 : return HasSDWASdst;
660 : }
661 :
662 0 : bool hasSDWAMac() const {
663 0 : return HasSDWAMac;
664 : }
665 :
666 0 : bool hasSDWAOutModsVOPC() const {
667 0 : return HasSDWAOutModsVOPC;
668 : }
669 :
670 : bool vmemWriteNeedsExpWaitcnt() const {
671 37949 : return getGeneration() < SEA_ISLANDS;
672 : }
673 :
674 0 : bool hasDLInsts() const {
675 0 : return HasDLInsts;
676 : }
677 :
678 0 : bool d16PreservesUnusedBits() const {
679 0 : return D16PreservesUnusedBits;
680 : }
681 :
682 : // Scratch is allocated in 256 dword per wave blocks for the entire
683 : // wavefront. When viewed from the perspecive of an arbitrary workitem, this
684 : // is 4-byte aligned.
685 : //
686 : // Only 4-byte alignment is really needed to access anything. Transformations
687 : // on the pointer value itself may rely on the alignment / known low bits of
688 : // the pointer. Set this to something above the minimum to avoid needing
689 : // dynamic realignment in common cases.
690 0 : unsigned getStackAlignment() const {
691 0 : return 16;
692 : }
693 :
694 60874 : bool enableMachineScheduler() const override {
695 60874 : return true;
696 : }
697 :
698 20673 : bool enableSubRegLiveness() const override {
699 20673 : return true;
700 : }
701 :
702 631056 : void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; }
703 0 : bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; }
704 :
705 : /// \returns Number of execution units per compute unit supported by the
706 : /// subtarget.
707 : unsigned getEUsPerCU() const {
708 : return AMDGPU::IsaInfo::getEUsPerCU(this);
709 : }
710 :
711 : /// \returns Maximum number of waves per compute unit supported by the
712 : /// subtarget without any kind of limitation.
713 : unsigned getMaxWavesPerCU() const {
714 : return AMDGPU::IsaInfo::getMaxWavesPerCU(this);
715 : }
716 :
717 : /// \returns Maximum number of waves per compute unit supported by the
718 : /// subtarget and limited by given \p FlatWorkGroupSize.
719 : unsigned getMaxWavesPerCU(unsigned FlatWorkGroupSize) const {
720 : return AMDGPU::IsaInfo::getMaxWavesPerCU(this, FlatWorkGroupSize);
721 : }
722 :
723 : /// \returns Maximum number of waves per execution unit supported by the
724 : /// subtarget without any kind of limitation.
725 : unsigned getMaxWavesPerEU() const {
726 : return AMDGPU::IsaInfo::getMaxWavesPerEU();
727 : }
728 :
729 : /// \returns Number of waves per work group supported by the subtarget and
730 : /// limited by given \p FlatWorkGroupSize.
731 : unsigned getWavesPerWorkGroup(unsigned FlatWorkGroupSize) const {
732 : return AMDGPU::IsaInfo::getWavesPerWorkGroup(this, FlatWorkGroupSize);
733 : }
734 :
735 : // static wrappers
736 : static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI);
737 :
738 : // XXX - Why is this here if it isn't in the default pass set?
739 22 : bool enableEarlyIfConversion() const override {
740 22 : return true;
741 : }
742 :
743 : void overrideSchedPolicy(MachineSchedPolicy &Policy,
744 : unsigned NumRegionInstrs) const override;
745 :
746 : bool isVGPRSpillingEnabled(const Function &F) const;
747 :
748 0 : unsigned getMaxNumUserSGPRs() const {
749 0 : return 16;
750 : }
751 :
752 : bool hasSMemRealTime() const {
753 : return HasSMemRealTime;
754 : }
755 :
756 0 : bool hasMovrel() const {
757 0 : return HasMovrel;
758 : }
759 :
760 0 : bool hasVGPRIndexMode() const {
761 0 : return HasVGPRIndexMode;
762 : }
763 :
764 : bool useVGPRIndexMode(bool UserEnable) const {
765 161 : return !hasMovrel() || (UserEnable && hasVGPRIndexMode());
766 : }
767 :
768 : bool hasScalarCompareEq64() const {
769 0 : return getGeneration() >= VOLCANIC_ISLANDS;
770 : }
771 :
772 0 : bool hasScalarStores() const {
773 0 : return HasScalarStores;
774 : }
775 :
776 : bool hasScalarAtomics() const {
777 : return HasScalarAtomics;
778 : }
779 :
780 :
781 0 : bool hasDPP() const {
782 0 : return HasDPP;
783 : }
784 :
785 : bool hasR128A16() const {
786 : return HasR128A16;
787 : }
788 :
789 0 : bool enableSIScheduler() const {
790 0 : return EnableSIScheduler;
791 : }
792 :
793 : bool debuggerSupported() const {
794 4960 : return debuggerInsertNops() && debuggerEmitPrologue();
795 : }
796 :
797 0 : bool debuggerInsertNops() const {
798 0 : return DebuggerInsertNops;
799 : }
800 :
801 0 : bool debuggerEmitPrologue() const {
802 0 : return DebuggerEmitPrologue;
803 : }
804 :
805 0 : bool loadStoreOptEnabled() const {
806 0 : return EnableLoadStoreOpt;
807 : }
808 :
809 0 : bool hasSGPRInitBug() const {
810 0 : return SGPRInitBug;
811 : }
812 :
813 : bool has12DWordStoreHazard() const {
814 347436 : return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS;
815 : }
816 :
817 : bool hasSMovFedHazard() const {
818 792816 : return getGeneration() >= AMDGPUSubtarget::GFX9;
819 : }
820 :
821 : bool hasReadM0MovRelInterpHazard() const {
822 742447 : return getGeneration() >= AMDGPUSubtarget::GFX9;
823 : }
824 :
825 : bool hasReadM0SendMsgHazard() const {
826 216573 : return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS;
827 : }
828 :
829 : /// Return the maximum number of waves per SIMD for kernels using \p SGPRs
830 : /// SGPRs
831 : unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
832 :
833 : /// Return the maximum number of waves per SIMD for kernels using \p VGPRs
834 : /// VGPRs
835 : unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const;
836 :
837 : /// \returns true if the flat_scratch register should be initialized with the
838 : /// pointer to the wave's scratch memory rather than a size and offset.
839 : bool flatScratchIsPointer() const {
840 381 : return getGeneration() >= AMDGPUSubtarget::GFX9;
841 : }
842 :
843 : /// \returns true if the machine has merged shaders in which s0-s7 are
844 : /// reserved by the hardware and user SGPRs start at s8
845 : bool hasMergedShaders() const {
846 4 : return getGeneration() >= GFX9;
847 : }
848 :
849 : /// \returns SGPR allocation granularity supported by the subtarget.
850 : unsigned getSGPRAllocGranule() const {
851 : return AMDGPU::IsaInfo::getSGPRAllocGranule(this);
852 : }
853 :
854 : /// \returns SGPR encoding granularity supported by the subtarget.
855 : unsigned getSGPREncodingGranule() const {
856 : return AMDGPU::IsaInfo::getSGPREncodingGranule(this);
857 : }
858 :
859 : /// \returns Total number of SGPRs supported by the subtarget.
860 : unsigned getTotalNumSGPRs() const {
861 : return AMDGPU::IsaInfo::getTotalNumSGPRs(this);
862 : }
863 :
864 : /// \returns Addressable number of SGPRs supported by the subtarget.
865 : unsigned getAddressableNumSGPRs() const {
866 37710 : return AMDGPU::IsaInfo::getAddressableNumSGPRs(this);
867 : }
868 :
869 : /// \returns Minimum number of SGPRs that meets the given number of waves per
870 : /// execution unit requirement supported by the subtarget.
871 : unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
872 18020 : return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU);
873 : }
874 :
875 : /// \returns Maximum number of SGPRs that meets the given number of waves per
876 : /// execution unit requirement supported by the subtarget.
877 : unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
878 203939 : return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable);
879 : }
880 :
881 : /// \returns Reserved number of SGPRs for given function \p MF.
882 : unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
883 :
884 : /// \returns Maximum number of SGPRs that meets number of waves per execution
885 : /// unit requirement for function \p MF, or number of SGPRs explicitly
886 : /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
887 : ///
888 : /// \returns Value that meets number of waves per execution unit requirement
889 : /// if explicitly requested value cannot be converted to integer, violates
890 : /// subtarget's specifications, or does not meet number of waves per execution
891 : /// unit requirement.
892 : unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
893 :
894 : /// \returns VGPR allocation granularity supported by the subtarget.
895 : unsigned getVGPRAllocGranule() const {
896 : return AMDGPU::IsaInfo::getVGPRAllocGranule(this);
897 : }
898 :
899 : /// \returns VGPR encoding granularity supported by the subtarget.
900 : unsigned getVGPREncodingGranule() const {
901 : return AMDGPU::IsaInfo::getVGPREncodingGranule(this);
902 : }
903 :
904 : /// \returns Total number of VGPRs supported by the subtarget.
905 : unsigned getTotalNumVGPRs() const {
906 : return AMDGPU::IsaInfo::getTotalNumVGPRs(this);
907 : }
908 :
909 : /// \returns Addressable number of VGPRs supported by the subtarget.
910 : unsigned getAddressableNumVGPRs() const {
911 19750 : return AMDGPU::IsaInfo::getAddressableNumVGPRs(this);
912 : }
913 :
914 : /// \returns Minimum number of VGPRs that meets given number of waves per
915 : /// execution unit requirement supported by the subtarget.
916 : unsigned getMinNumVGPRs(unsigned WavesPerEU) const {
917 17978 : return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU);
918 : }
919 :
920 : /// \returns Maximum number of VGPRs that meets given number of waves per
921 : /// execution unit requirement supported by the subtarget.
922 : unsigned getMaxNumVGPRs(unsigned WavesPerEU) const {
923 166144 : return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU);
924 : }
925 :
926 : /// \returns Maximum number of VGPRs that meets number of waves per execution
927 : /// unit requirement for function \p MF, or number of VGPRs explicitly
928 : /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF.
929 : ///
930 : /// \returns Value that meets number of waves per execution unit requirement
931 : /// if explicitly requested value cannot be converted to integer, violates
932 : /// subtarget's specifications, or does not meet number of waves per execution
933 : /// unit requirement.
934 : unsigned getMaxNumVGPRs(const MachineFunction &MF) const;
935 :
936 : void getPostRAMutations(
937 : std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
938 : const override;
939 :
940 : /// \returns Maximum number of work groups per compute unit supported by the
941 : /// subtarget and limited by given \p FlatWorkGroupSize.
942 198931 : unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
943 198931 : return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize);
944 : }
945 :
946 : /// \returns Minimum flat work group size supported by the subtarget.
947 261154 : unsigned getMinFlatWorkGroupSize() const override {
948 261154 : return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this);
949 : }
950 :
951 : /// \returns Maximum flat work group size supported by the subtarget.
952 261081 : unsigned getMaxFlatWorkGroupSize() const override {
953 261081 : return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this);
954 : }
955 :
956 : /// \returns Maximum number of waves per execution unit supported by the
957 : /// subtarget and limited by given \p FlatWorkGroupSize.
958 37603 : unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const override {
959 37603 : return AMDGPU::IsaInfo::getMaxWavesPerEU(this, FlatWorkGroupSize);
960 : }
961 :
962 : /// \returns Minimum number of waves per execution unit supported by the
963 : /// subtarget.
964 37603 : unsigned getMinWavesPerEU() const override {
965 37603 : return AMDGPU::IsaInfo::getMinWavesPerEU(this);
966 : }
967 : };
968 :
969 290 : class R600Subtarget final : public R600GenSubtargetInfo,
970 : public AMDGPUSubtarget {
971 : private:
972 : R600InstrInfo InstrInfo;
973 : R600FrameLowering FrameLowering;
974 : bool FMA;
975 : bool CaymanISA;
976 : bool CFALUBug;
977 : bool DX10Clamp;
978 : bool HasVertexCache;
979 : bool R600ALUInst;
980 : bool FP64;
981 : short TexVTXClauseSize;
982 : Generation Gen;
983 : R600TargetLowering TLInfo;
984 : InstrItineraryData InstrItins;
985 : SelectionDAGTargetInfo TSInfo;
986 :
987 : public:
988 : R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
989 : const TargetMachine &TM);
990 :
991 836239 : const R600InstrInfo *getInstrInfo() const override { return &InstrInfo; }
992 :
993 27979 : const R600FrameLowering *getFrameLowering() const override {
994 30395 : return &FrameLowering;
995 : }
996 :
997 90151 : const R600TargetLowering *getTargetLowering() const override {
998 128344 : return &TLInfo;
999 : }
1000 :
1001 1594975 : const R600RegisterInfo *getRegisterInfo() const override {
1002 1594975 : return &InstrInfo.getRegisterInfo();
1003 : }
1004 :
1005 7070 : const InstrItineraryData *getInstrItineraryData() const override {
1006 7070 : return &InstrItins;
1007 : }
1008 :
1009 : // Nothing implemented, just prevent crashes on use.
1010 4605 : const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
1011 4605 : return &TSInfo;
1012 : }
1013 :
1014 : void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
1015 :
1016 0 : Generation getGeneration() const {
1017 0 : return Gen;
1018 : }
1019 :
1020 0 : unsigned getStackAlignment() const {
1021 0 : return 4;
1022 : }
1023 :
1024 : R600Subtarget &initializeSubtargetDependencies(const Triple &TT,
1025 : StringRef GPU, StringRef FS);
1026 :
1027 : bool hasBFE() const {
1028 642 : return (getGeneration() >= EVERGREEN);
1029 : }
1030 :
1031 : bool hasBFI() const {
1032 291 : return (getGeneration() >= EVERGREEN);
1033 : }
1034 :
1035 : bool hasBCNT(unsigned Size) const {
1036 : if (Size == 32)
1037 291 : return (getGeneration() >= EVERGREEN);
1038 :
1039 : return false;
1040 : }
1041 :
1042 : bool hasBORROW() const {
1043 291 : return (getGeneration() >= EVERGREEN);
1044 : }
1045 :
1046 : bool hasCARRY() const {
1047 291 : return (getGeneration() >= EVERGREEN);
1048 : }
1049 :
1050 0 : bool hasCaymanISA() const {
1051 0 : return CaymanISA;
1052 : }
1053 :
1054 : bool hasFFBL() const {
1055 291 : return (getGeneration() >= EVERGREEN);
1056 : }
1057 :
1058 : bool hasFFBH() const {
1059 291 : return (getGeneration() >= EVERGREEN);
1060 : }
1061 :
1062 0 : bool hasFMA() const { return FMA; }
1063 :
1064 0 : bool hasCFAluBug() const { return CFALUBug; }
1065 :
1066 0 : bool hasVertexCache() const { return HasVertexCache; }
1067 :
1068 0 : short getTexVTXClauseSize() const { return TexVTXClauseSize; }
1069 :
1070 7070 : bool enableMachineScheduler() const override {
1071 7070 : return true;
1072 : }
1073 :
1074 2298 : bool enableSubRegLiveness() const override {
1075 2298 : return true;
1076 : }
1077 :
1078 : /// \returns Maximum number of work groups per compute unit supported by the
1079 : /// subtarget and limited by given \p FlatWorkGroupSize.
1080 4022 : unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
1081 4022 : return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize);
1082 : }
1083 :
1084 : /// \returns Minimum flat work group size supported by the subtarget.
1085 6567 : unsigned getMinFlatWorkGroupSize() const override {
1086 6567 : return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this);
1087 : }
1088 :
1089 : /// \returns Maximum flat work group size supported by the subtarget.
1090 6567 : unsigned getMaxFlatWorkGroupSize() const override {
1091 6567 : return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this);
1092 : }
1093 :
1094 : /// \returns Maximum number of waves per execution unit supported by the
1095 : /// subtarget and limited by given \p FlatWorkGroupSize.
1096 2011 : unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const override {
1097 2011 : return AMDGPU::IsaInfo::getMaxWavesPerEU(this, FlatWorkGroupSize);
1098 : }
1099 :
1100 : /// \returns Minimum number of waves per execution unit supported by the
1101 : /// subtarget.
1102 2011 : unsigned getMinWavesPerEU() const override {
1103 2011 : return AMDGPU::IsaInfo::getMinWavesPerEU(this);
1104 : }
1105 : };
1106 :
1107 : } // end namespace llvm
1108 :
1109 : #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
|