87 std::unique_ptr<MCStreamer> &&
Streamer) {
104 AMDGPUAsmPrinter *Asm;
107 AMDGPUAsmPrinterHandler(AMDGPUAsmPrinter *
A) : Asm(
A) {}
111 void endFunction(
const MachineFunction *MF)
override { Asm->endFunction(MF); }
113 void endModule()
override {}
118 std::unique_ptr<MCStreamer>
Streamer)
126 if (
auto *ResourceUsageW =
128 return &ResourceUsageW->getResourceInfo();
134 return "AMDGPU Assembly Printer";
138 return &
TM.getMCSubtargetInfo();
151void AMDGPUAsmPrinter::initTargetStreamer(
Module &M) {
157 initializeTargetID(M);
159 const Triple &TT = M.getTargetTriple();
178 initTargetStreamer(M);
180 const Triple &TT = M.getTargetTriple();
187 HSAMetadataStream->end();
202 STM.getCPU() +
" is only available on code object version 6 or better");
208 initializeTargetID(*
F.getParent());
213 if (STM.isMesaKernel(
F) &&
217 getAmdKernelCode(KernelCode, CurrentProgramInfo, *
MF);
222 if (STM.isAmdHsaOS())
223 HSAMetadataStream->emitKernel(*
MF, CurrentProgramInfo);
249 getAmdhsaKernelDescriptor(*
MF, CurrentProgramInfo);
262 const MCExpr *InstPrefSize =
269 auto &Context =
Streamer.getContext();
270 auto &ObjectFileInfo = *Context.getObjectFileInfo();
271 auto &ReadOnlySection = *ObjectFileInfo.getReadOnlySection();
274 Streamer.switchSection(&ReadOnlySection);
279 ReadOnlySection.ensureMinAlignment(
Align(64));
284 STM, KernelName, KD, CurrentProgramInfo.NumVGPRsForWavesPerEU,
286 CurrentProgramInfo.NumSGPRsForWavesPerEU,
288 CurrentProgramInfo.VCCUsed, CurrentProgramInfo.FlatUsed,
291 CurrentProgramInfo.VCCUsed, CurrentProgramInfo.FlatUsed);
301 OS <<
"implicit-def: "
302 <<
printReg(RegNo,
MF->getSubtarget().getRegisterInfo());
305 OS <<
" : SGPR spill to VGPR lane";
325 if (DumpCodeInstEmitter) {
352 ": unsupported initializer for address space");
365 "LDS definitions should have been externalized when object "
366 "linking is enabled");
374 "' is already defined");
383 TS->emitAMDGPULDS(GVSym,
Size, Alignment);
391 const Triple &TT = M.getTargetTriple();
399 "codegen with no subarch in the target triple is deprecated and will "
400 "become an error; use the target triple '" +
401 Fixed.str() +
"' instead",
405 "codegen with no subarch in the target triple is deprecated and will "
414 switch (CodeObjectVersion) {
416 HSAMetadataStream = std::make_unique<HSAMD::MetadataStreamerMsgPackV4>();
419 HSAMetadataStream = std::make_unique<HSAMD::MetadataStreamerMsgPackV5>();
422 HSAMetadataStream = std::make_unique<HSAMD::MetadataStreamerMsgPackV6>();
441 unsigned DynamicVGPRBlockSize,
455 auto CreateExpr = [&Ctx](
unsigned Value) {
465 {CreateExpr(MaxWaves), CreateExpr(Granule),
466 CreateExpr(TargetTotalNumVGPRs),
467 CreateExpr(InitOcc), CreateExpr(SGPRTotal),
468 CreateExpr(SGPRGranule),
469 CreateExpr(SGPRTrapReserve), SGPRArg, NumVGPRs},
473void AMDGPUAsmPrinter::validateMCResourceInfo(
Function &
F) {
478 const GCNSubtarget &STM =
TM.getSubtarget<GCNSubtarget>(
F);
481 auto TryGetMCExprValue = [](
const MCExpr *
Value,
uint64_t &Res) ->
bool {
483 if (
Value->evaluateAsAbsolute(Val)) {
490 const uint64_t MaxScratchPerWorkitem =
493 RI.getSymbol(FnSym->getName(), RIK::RIK_PrivateSegSize,
OutContext);
497 ScratchSize > MaxScratchPerWorkitem) {
498 DiagnosticInfoStackSize DiagStackSize(
F, ScratchSize, MaxScratchPerWorkitem,
500 F.getContext().diagnose(DiagStackSize);
506 RI.getSymbol(FnSym->getName(), RIK::RIK_NumSGPR,
OutContext);
508 !STM.hasSGPRInitBug()) {
513 NumSgpr > MaxAddressableNumSGPRs) {
514 F.getContext().diagnose(DiagnosticInfoResourceLimit(
515 F,
"addressable scalar registers", NumSgpr, MaxAddressableNumSGPRs,
522 RI.getSymbol(FnSym->getName(), RIK::RIK_UsesVCC,
OutContext);
524 RI.getSymbol(FnSym->getName(), RIK::RIK_UsesFlatScratch,
OutContext);
525 uint64_t VCCUsed, FlatUsed, NumSgpr;
536 STM, VCCUsed, FlatUsed,
539 STM.hasSGPRInitBug()) {
541 if (NumSgpr > MaxAddressableNumSGPRs) {
542 F.getContext().diagnose(DiagnosticInfoResourceLimit(
543 F,
"scalar registers", NumSgpr, MaxAddressableNumSGPRs,
DS_Error,
550 RI.getSymbol(FnSym->getName(), RIK::RIK_NumVGPR,
OutContext);
552 RI.getSymbol(FnSym->getName(), RIK::RIK_NumAGPR,
OutContext);
560 const SIMachineFunctionInfo &MFI = *
MF->getInfo<SIMachineFunctionInfo>();
565 std::max({TotalNumVgpr, (
uint64_t)1,
568 uint64_t NumSGPRsForWavesPerEU = std::max(
578 F,
"amdgpu-waves-per-eu", {0, 0},
true);
580 if (TryGetMCExprValue(OccupancyExpr, Occupancy) && Occupancy < MinWEU) {
581 DiagnosticInfoOptimizationFailure Diag(
582 F,
F.getSubprogram(),
583 "failed to meet occupancy target given by 'amdgpu-waves-per-eu' in "
585 F.getName() +
"': desired occupancy was " + Twine(MinWEU) +
586 ", final occupancy is " + Twine(Occupancy));
587 F.getContext().diagnose(Diag);
596 if (Ty->isVoidTy()) {
600 unsigned Bits =
DL.getTypeSizeInBits(Ty);
621 for (
Type *ParamTy : FTy->params())
629 const SIInstrInfo *
TII =
MF->getSubtarget<GCNSubtarget>().getInstrInfo();
630 const MachineOperand *
Callee =
631 TII->getNamedOperand(
MI, AMDGPU::OpName::callee);
632 if (!Callee || !
Callee->isGlobal())
634 DirectCallEdges.insert(
638void AMDGPUAsmPrinter::emitAMDGPUInfo(
Module &M) {
642 const NamedMDNode *LDSMD =
M.getNamedMetadata(
"amdgpu.lds.uses");
645 const NamedMDNode *BarMD =
M.getNamedMetadata(
"amdgpu.named_barrier.uses");
649 DenseMap<const Function *, std::string> AddrTakenTypeIds;
650 using IndirectCallInfo = std::pair<const Function *, std::string>;
656 if (!IsKernel &&
F.hasAddressTaken(
nullptr,
660 AddrTakenTypeIds[&
F] =
664 if (
F.isDeclaration())
667 StringSet<> SeenTypeIds;
668 for (
const BasicBlock &BB :
F) {
669 for (
const Instruction &
I : BB) {
671 if (!CB || !CB->isIndirectCall())
675 if (SeenTypeIds.
insert(TId).second)
676 IndirectCalls.
push_back({&
F, std::move(TId)});
681 if (FunctionInfos.empty() && DirectCallEdges.empty() && !HasLDSUses &&
682 !HasNamedBarriers && AddrTakenTypeIds.
empty() && IndirectCalls.
empty())
685 AMDGPU::InfoSectionData
Data;
686 Data.Funcs = std::move(FunctionInfos);
688 for (
auto &[
F, TypeId] : AddrTakenTypeIds) {
690 Data.TypeIds.push_back({Sym, TypeId});
693 for (
auto &[CallerSym, CalleeSym] : DirectCallEdges)
694 Data.Calls.push_back({CallerSym, CalleeSym});
695 DirectCallEdges.clear();
698 for (
const MDNode *
N : LDSMD->
operands()) {
705 if (HasNamedBarriers) {
706 for (
const MDNode *
N : BarMD->
operands()) {
709 for (
unsigned I = 1,
E =
N->getNumOperands();
I <
E; ++
I) {
716 for (
auto &[Caller, Enc] : IndirectCalls) {
718 Data.IndirectCalls.push_back({CallerSym, Enc});
725 const Triple &TT = M.getTargetTriple();
766 validateMCResourceInfo(
F);
778 auto &Context =
Streamer.getContext();
785void AMDGPUAsmPrinter::emitCommonFunctionComments(
790 OutStreamer->emitRawComment(
" TotalNumSgprs: " + getMCExprStr(NumSGPR),
792 OutStreamer->emitRawComment(
" NumVgprs: " + getMCExprStr(NumVGPR),
false);
793 if (NumAGPR && TotalNumVGPR) {
794 OutStreamer->emitRawComment(
" NumAgprs: " + getMCExprStr(NumAGPR),
false);
795 OutStreamer->emitRawComment(
" TotalNumVgprs: " + getMCExprStr(TotalNumVGPR),
798 OutStreamer->emitRawComment(
" ScratchSize: " + getMCExprStr(ScratchSize),
804const MCExpr *AMDGPUAsmPrinter::getAmdhsaKernelCodeProperties(
806 const SIMachineFunctionInfo &MFI = *
MF.getInfo<SIMachineFunctionInfo>();
807 MCContext &Ctx =
MF.getContext();
808 uint16_t KernelCodeProperties = 0;
812 KernelCodeProperties |=
813 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER;
816 KernelCodeProperties |=
817 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR;
820 KernelCodeProperties |= amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR;
823 KernelCodeProperties |=
824 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR;
827 KernelCodeProperties |=
828 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID;
831 KernelCodeProperties |=
832 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT;
835 KernelCodeProperties |=
836 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE;
838 const GCNSubtarget &STM =
MF.getSubtarget<GCNSubtarget>();
840 STM.getFeatureBits().test(AMDGPU::FeatureSupportsWave32) &&
841 STM.getFeatureBits().test(AMDGPU::FeatureSupportsWave64)) {
842 KernelCodeProperties |=
843 amdhsa::KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32;
850 const MCExpr *KernelCodePropExpr =
853 amdhsa::KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK_SHIFT, Ctx);
858 return KernelCodePropExpr;
864 const GCNSubtarget &STM =
MF.getSubtarget<GCNSubtarget>();
866 const SIMachineFunctionInfo *
Info =
MF.getInfo<SIMachineFunctionInfo>();
867 MCContext &Ctx =
MF.getContext();
869 MCKernelDescriptor KernelDescriptor;
875 Align MaxKernArgAlign;
883 int64_t PGM_Rsrc3 = 1;
884 bool EvaluatableRsrc3 =
885 CurrentProgramInfo.ComputePGMRSrc3->evaluateAsAbsolute(PGM_Rsrc3);
887 (void)EvaluatableRsrc3;
889 STM.hasGFX90AInsts() || STM.hasGFX1250Insts() || !EvaluatableRsrc3 ||
890 static_cast<uint64_t>(PGM_Rsrc3) == 0);
897 return KernelDescriptor;
904 initTargetStreamer(*
MF.getFunction().getParent());
907 CurrentProgramInfo.reset(
MF);
933 FunctionInfos.push_back(
945 getSIProgramInfo(CurrentProgramInfo,
MF);
950 EmitPALMetadata(
MF, CurrentProgramInfo);
952 emitPALFunctionMetadata(
MF);
954 EmitProgramInfoSI(
MF, CurrentProgramInfo);
957 DumpCodeInstEmitter =
nullptr;
958 if (STM.dumpCode()) {
981 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_NumNamedBarrier,
983 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_PrivateSegSize,
986 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_UsesFlatScratch,
988 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_HasDynSizedStack,
990 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_HasRecursion,
992 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_HasIndirectCall,
1006 OutStreamer->emitRawComment(
" Function info:",
false);
1008 emitCommonFunctionComments(
1010 ->getVariableValue(),
1011 STM.hasMAIInsts() ? RI.getSymbol(
CurrentFnSym->getName(),
1013 ->getVariableValue()
1015 RI.createTotalNumVGPRs(
MF, Ctx),
1016 RI.createTotalNumSGPRs(
1020 RI.getSymbol(
CurrentFnSym->getName(), RIK::RIK_PrivateSegSize,
1022 ->getVariableValue(),
1023 CurrentProgramInfo.getFunctionCodeSize(
MF), MFI);
1027 OutStreamer->emitRawComment(
" Kernel info:",
false);
1028 emitCommonFunctionComments(
1029 CurrentProgramInfo.NumArchVGPR,
1030 STM.hasMAIInsts() ? CurrentProgramInfo.NumAccVGPR :
nullptr,
1031 CurrentProgramInfo.NumVGPR, CurrentProgramInfo.NumSGPR,
1032 CurrentProgramInfo.ScratchSize,
1033 CurrentProgramInfo.getFunctionCodeSize(
MF), MFI);
1036 " FloatMode: " +
Twine(CurrentProgramInfo.FloatMode),
false);
1038 " IeeeMode: " +
Twine(CurrentProgramInfo.IEEEMode),
false);
1040 " LDSByteSize: " +
Twine(CurrentProgramInfo.LDSSize) +
1041 " bytes/workgroup (compile time only)",
1045 " SGPRBlocks: " + getMCExprStr(CurrentProgramInfo.SGPRBlocks),
false);
1048 " VGPRBlocks: " + getMCExprStr(CurrentProgramInfo.VGPRBlocks),
false);
1051 " NumSGPRsForWavesPerEU: " +
1052 getMCExprStr(CurrentProgramInfo.NumSGPRsForWavesPerEU),
1055 " NumVGPRsForWavesPerEU: " +
1056 getMCExprStr(CurrentProgramInfo.NumVGPRsForWavesPerEU),
1059 if (STM.hasGFX90AInsts()) {
1065 " AccumOffset: " + getMCExprStr(AdjustedAccum),
false);
1068 if (STM.hasGFX1250Insts())
1070 " NamedBarCnt: " + getMCExprStr(CurrentProgramInfo.NamedBarCnt),
1074 " Occupancy: " + getMCExprStr(CurrentProgramInfo.Occupancy),
false);
1080 " COMPUTE_PGM_RSRC2:SCRATCH_EN: " +
1081 getMCExprStr(CurrentProgramInfo.ScratchEnable),
1083 OutStreamer->emitRawComment(
" COMPUTE_PGM_RSRC2:USER_SGPR: " +
1084 Twine(CurrentProgramInfo.UserSGPR),
1086 OutStreamer->emitRawComment(
" COMPUTE_PGM_RSRC2:TRAP_HANDLER: " +
1087 Twine(CurrentProgramInfo.TrapHandlerEnable),
1089 OutStreamer->emitRawComment(
" COMPUTE_PGM_RSRC2:TGID_X_EN: " +
1090 Twine(CurrentProgramInfo.TGIdXEnable),
1092 OutStreamer->emitRawComment(
" COMPUTE_PGM_RSRC2:TGID_Y_EN: " +
1093 Twine(CurrentProgramInfo.TGIdYEnable),
1095 OutStreamer->emitRawComment(
" COMPUTE_PGM_RSRC2:TGID_Z_EN: " +
1096 Twine(CurrentProgramInfo.TGIdZEnable),
1098 OutStreamer->emitRawComment(
" COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " +
1099 Twine(CurrentProgramInfo.TIdIGCompCount),
1102 [[maybe_unused]] int64_t PGMRSrc3;
1104 STM.hasGFX90AInsts() || STM.hasGFX1250Insts() ||
1105 (CurrentProgramInfo.ComputePGMRSrc3->evaluateAsAbsolute(PGMRSrc3) &&
1106 static_cast<uint64_t
>(PGMRSrc3) == 0));
1107 if (STM.hasGFX90AInsts()) {
1109 " COMPUTE_PGM_RSRC3_GFX90A:ACCUM_OFFSET: " +
1111 CurrentProgramInfo.ComputePGMRSrc3,
1112 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
1113 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET, Ctx)),
1116 " COMPUTE_PGM_RSRC3_GFX90A:TG_SPLIT: " +
1118 CurrentProgramInfo.ComputePGMRSrc3,
1119 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT_SHIFT,
1120 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT, Ctx)),
1125 if (DumpCodeInstEmitter) {
1131 std::string Comment =
"\n";
1134 Comment +=
" ; " +
HexLines[i] +
"\n";
1159 const MCExpr *EncodedBlocks;
1162 NumVGPRs,
nullptr) &&
1163 NumVGPRs.isAbsolute()) {
1167 unsigned NumBlocks =
1172 {},
"DVGPR block count " +
Twine(NumBlocks) +
1173 " exceeds maximum of " +
1175 " for __dvgpr$ symbol for '" +
1179 unsigned EncodedNumBlocks = (NumBlocks - 1) << 3;
1187 {CurrentProgramInfo.NumVGPRsForWavesPerEU, One}, Ctx);
1190 BlockSizeConst, Ctx);
1201 OutStreamer->emitAssignment(DVgprFuncSym, DVgprFuncVal);
1208void AMDGPUAsmPrinter::initializeTargetID(
const Module &M) {
1216 if (FeatureString.
contains(
"xnack")) {
1217 M.getContext().diagnose(DiagnosticInfoGeneric(
1218 "xnack/sramecc should be specified via module flags. "
1219 "Use module flag 'amdgpu.xnack' instead of subtarget feature",
1222 if (FeatureString.
contains(
"sramecc")) {
1223 M.getContext().diagnose(DiagnosticInfoGeneric(
1224 "xnack/sramecc should be specified via module flags. "
1225 "Use module flag 'amdgpu.sramecc' instead of subtarget feature",
1230 if (
getGlobalSTI()->getFeatureBits().
test(AMDGPU::FeatureXNACKOnOffModes)) {
1233 if (Setting != AMDGPU::TargetIDSetting::Any)
1234 TSTargetID->setXnackSetting(Setting);
1237 if (
getGlobalSTI()->getFeatureBits().
test(AMDGPU::FeatureSRAMECCOnOffModes)) {
1240 if (Setting != AMDGPU::TargetIDSetting::Any)
1241 TSTargetID->setSramEccSetting(Setting);
1252 const MCExpr *MaximumTaken =
1268 return Granule ? Granule : 256;
1271void AMDGPUAsmPrinter::getSIProgramInfo(
SIProgramInfo &ProgInfo,
1273 const GCNSubtarget &STM =
MF.getSubtarget<GCNSubtarget>();
1274 MCContext &Ctx =
MF.getContext();
1276 auto CreateExpr = [&Ctx](int64_t
Value) {
1280 auto TryGetMCExprValue = [](
const MCExpr *
Value,
uint64_t &Res) ->
bool {
1282 if (
Value->evaluateAsAbsolute(Val)) {
1289 auto GetSymRefExpr =
1296 ProgInfo.
NumArchVGPR = GetSymRefExpr(RIK::RIK_NumVGPR);
1297 ProgInfo.
NumAccVGPR = GetSymRefExpr(RIK::RIK_NumAGPR);
1304 ProgInfo.
NumSGPR = GetSymRefExpr(RIK::RIK_NumSGPR);
1305 ProgInfo.
ScratchSize = GetSymRefExpr(RIK::RIK_PrivateSegSize);
1306 ProgInfo.
VCCUsed = GetSymRefExpr(RIK::RIK_UsesVCC);
1307 ProgInfo.
FlatUsed = GetSymRefExpr(RIK::RIK_UsesFlatScratch);
1310 GetSymRefExpr(RIK::RIK_HasRecursion), Ctx);
1314 GetSymRefExpr(RIK::RIK_NumNamedBarrier), BarBlkConst, Ctx);
1317 const SIMachineFunctionInfo *MFI =
MF.getInfo<SIMachineFunctionInfo>();
1328 !STM.hasSGPRInitBug()) {
1331 if (TryGetMCExprValue(ProgInfo.
NumSGPR, NumSgpr) &&
1332 NumSgpr > MaxAddressableNumSGPRs) {
1334 LLVMContext &Ctx =
MF.getFunction().getContext();
1335 Ctx.
diagnose(DiagnosticInfoResourceLimit(
1336 MF.getFunction(),
"addressable scalar registers", NumSgpr,
1338 ProgInfo.
NumSGPR = CreateExpr(MaxAddressableNumSGPRs - 1);
1352 if (WaveDispatchNumSGPR) {
1360 if (WaveDispatchNumVGPR) {
1362 {ProgInfo.
NumArchVGPR, CreateExpr(WaveDispatchNumVGPR)}, Ctx);
1382 STM.hasSGPRInitBug()) {
1385 if (TryGetMCExprValue(ProgInfo.
NumSGPR, NumSgpr) &&
1386 NumSgpr > MaxAddressableNumSGPRs) {
1389 LLVMContext &Ctx =
MF.getFunction().getContext();
1390 Ctx.
diagnose(DiagnosticInfoResourceLimit(
1391 MF.getFunction(),
"scalar registers", NumSgpr, MaxAddressableNumSGPRs,
1393 ProgInfo.
NumSGPR = CreateExpr(MaxAddressableNumSGPRs);
1398 if (STM.hasSGPRInitBug()) {
1406 LLVMContext &Ctx =
MF.getFunction().getContext();
1407 Ctx.
diagnose(DiagnosticInfoResourceLimit(
1413 LLVMContext &Ctx =
MF.getFunction().getContext();
1414 Ctx.
diagnose(DiagnosticInfoResourceLimit(
1429 LLVMContext &Ctx =
F.getContext();
1430 Ctx.
diagnose(DiagnosticInfoResourceLimit(
1431 F,
"dynamic VGPR entry point vector registers", NumVgpr,
BlockSize,
1438 auto GetNumGPRBlocks = [&CreateExpr, &Ctx](
const MCExpr *NumGPR,
1440 const MCExpr *OneConst = CreateExpr(1ul);
1441 const MCExpr *GranuleConst = CreateExpr(Granule);
1443 const MCExpr *AlignToGPR =
1445 const MCExpr *DivGPR =
1460 const SIModeRegisterDefaults
Mode = MFI->
getMode();
1477 alignTo(ProgInfo.
LDSSize, LDSGranularityBytes) / LDSGranularityBytes;
1480 auto DivideCeil = [&Ctx](
const MCExpr *Numerator,
const MCExpr *Denominator) {
1481 const MCExpr *Ceil =
1487 unsigned ScratchAlignShift =
1495 CreateExpr(1ULL << ScratchAlignShift));
1497 if (STM.hasSupportsWGP()) {
1503 ProgInfo.
FwdProgress = !
F.hasFnAttribute(
"amdgpu-no-fwd-progress");
1507 unsigned TIDIGCompCnt = 0;
1536 if (STM.hasGFX90AInsts()) {
1539 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
1540 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT, Ctx);
1543 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT,
1544 amdhsa::COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT_SHIFT, Ctx);
1547 if (STM.hasGFX1250Insts())
1550 amdhsa::COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
1551 amdhsa::COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT, Ctx);
1558 const auto [MinWEU, MaxWEU] =
1561 if (TryGetMCExprValue(ProgInfo.
Occupancy, Occupancy) && Occupancy < MinWEU) {
1562 DiagnosticInfoOptimizationFailure Diag(
1563 F,
F.getSubprogram(),
1564 "failed to meet occupancy target given by 'amdgpu-waves-per-eu' in "
1566 F.getName() +
"': desired occupancy was " + Twine(MinWEU) +
1567 ", final occupancy is " + Twine(Occupancy));
1568 F.getContext().diagnose(Diag);
1593void AMDGPUAsmPrinter::EmitProgramInfoSI(
1595 const SIMachineFunctionInfo *MFI =
MF.getInfo<SIMachineFunctionInfo>();
1596 const GCNSubtarget &STM =
MF.getSubtarget<GCNSubtarget>();
1597 unsigned RsrcReg =
getRsrcReg(
MF.getFunction().getCallingConv());
1598 MCContext &Ctx =
MF.getContext();
1601 auto SetBits = [&Ctx](
const MCExpr *
Value, uint32_t
Mask, uint32_t Shift) {
1608 auto EmitResolvedOrExpr = [
this](
const MCExpr *
Value,
unsigned Size) {
1610 if (
Value->evaluateAsAbsolute(Val))
1619 EmitResolvedOrExpr(CurrentProgramInfo.getComputePGMRSrc1(STM, Ctx),
1623 EmitResolvedOrExpr(CurrentProgramInfo.getComputePGMRSrc2(STM, Ctx),
1631 EmitResolvedOrExpr(SetBits(CurrentProgramInfo.ScratchBlocks,
1635 EmitResolvedOrExpr(SetBits(CurrentProgramInfo.ScratchBlocks,
1639 EmitResolvedOrExpr(SetBits(CurrentProgramInfo.ScratchBlocks,
1650 SetBits(CurrentProgramInfo.VGPRBlocks, 0x3F, 0),
1651 SetBits(CurrentProgramInfo.SGPRBlocks, 0x0F, 6),
1653 EmitResolvedOrExpr(GPRBlocks, 4);
1659 EmitResolvedOrExpr(SetBits(CurrentProgramInfo.ScratchBlocks,
1663 EmitResolvedOrExpr(SetBits(CurrentProgramInfo.ScratchBlocks,
1667 EmitResolvedOrExpr(SetBits(CurrentProgramInfo.ScratchBlocks,
1676 ?
divideCeil(CurrentProgramInfo.LDSBlocks, 2)
1677 : CurrentProgramInfo.LDSBlocks;
1695 unsigned DynamicVGPRBlockSize) {
1696 if (ST.hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
1708 if (DynamicVGPRBlockSize != 0)
1722void AMDGPUAsmPrinter::EmitPALMetadata(
1724 const SIMachineFunctionInfo *MFI =
MF.getInfo<SIMachineFunctionInfo>();
1725 auto CC =
MF.getFunction().getCallingConv();
1727 auto &Ctx =
MF.getContext();
1729 MD->setEntryPoint(
CC,
MF.getFunction().getName());
1730 MD->setNumUsedVgprs(
CC, CurrentProgramInfo.NumVGPRsForWavesPerEU, Ctx);
1734 const GCNSubtarget &STM =
MF.getSubtarget<GCNSubtarget>();
1737 MD->setHwStage(
CC,
".dynamic_vgpr_saved_count",
1741 if (STM.hasMAIInsts()) {
1742 MD->setNumUsedAgprs(
CC, CurrentProgramInfo.NumAccVGPR);
1745 MD->setNumUsedSgprs(
CC, CurrentProgramInfo.NumSGPRsForWavesPerEU, Ctx);
1746 if (MD->getPALMajorVersion() < 3) {
1747 MD->setRsrc1(
CC, CurrentProgramInfo.getPGMRSrc1(
CC, STM, Ctx), Ctx);
1749 MD->setRsrc2(
CC, CurrentProgramInfo.getComputePGMRSrc2(STM, Ctx), Ctx);
1751 const MCExpr *HasScratchBlocks =
1755 MD->setRsrc2(
CC,
maskShiftSet(HasScratchBlocks, Mask, Shift, Ctx), Ctx);
1758 MD->setHwStage(
CC,
".debug_mode", (
bool)CurrentProgramInfo.DebugMode);
1760 CurrentProgramInfo.ScratchEnable);
1774 ?
divideCeil(CurrentProgramInfo.LDSBlocks, 2)
1775 : CurrentProgramInfo.LDSBlocks;
1776 if (MD->getPALMajorVersion() < 3) {
1785 const unsigned ExtraLdsDwGranularity =
1787 MD->setGraphicsRegisters(
1788 ".ps_extra_lds_size",
1789 (
unsigned)(ExtraLDSSize * ExtraLdsDwGranularity *
sizeof(uint32_t)));
1792 static StringLiteral
const PsInputFields[] = {
1793 ".persp_sample_ena",
".persp_center_ena",
1794 ".persp_centroid_ena",
".persp_pull_model_ena",
1795 ".linear_sample_ena",
".linear_center_ena",
1796 ".linear_centroid_ena",
".line_stipple_tex_ena",
1797 ".pos_x_float_ena",
".pos_y_float_ena",
1798 ".pos_z_float_ena",
".pos_w_float_ena",
1799 ".front_face_ena",
".ancillary_ena",
1800 ".sample_coverage_ena",
".pos_fixed_pt_ena"};
1804 MD->setGraphicsRegisters(
".spi_ps_input_ena",
Field,
1805 (
bool)((PSInputEna >>
Idx) & 1));
1806 MD->setGraphicsRegisters(
".spi_ps_input_addr",
Field,
1807 (
bool)((PSInputAddr >>
Idx) & 1));
1813 if (MD->getPALMajorVersion() < 3 && STM.
isWave32())
1814 MD->setWave32(
MF.getFunction().getCallingConv());
1817void AMDGPUAsmPrinter::emitPALFunctionMetadata(
const MachineFunction &MF) {
1819 const MachineFrameInfo &MFI =
MF.getFrameInfo();
1820 StringRef FnName =
MF.getFunction().getName();
1821 MD->setFunctionScratchSize(FnName, MFI.
getStackSize());
1822 const GCNSubtarget &
ST =
MF.getSubtarget<GCNSubtarget>();
1823 MCContext &Ctx =
MF.getContext();
1825 if (MD->getPALMajorVersion() < 3) {
1831 CurrentProgramInfo.getComputePGMRSrc2(ST, Ctx), Ctx);
1835 MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize());
1839 MD->setFunctionLdsSize(FnName, CurrentProgramInfo.LDSSize);
1840 MD->setFunctionNumUsedVgprs(FnName, CurrentProgramInfo.NumVGPRsForWavesPerEU);
1841 MD->setFunctionNumUsedSgprs(FnName, CurrentProgramInfo.NumSGPRsForWavesPerEU);
1858void AMDGPUAsmPrinter::getAmdKernelCode(AMDGPUMCKernelCodeT &Out,
1865 const SIMachineFunctionInfo *MFI =
MF.getInfo<SIMachineFunctionInfo>();
1866 const GCNSubtarget &STM =
MF.getSubtarget<GCNSubtarget>();
1867 MCContext &Ctx =
MF.getContext();
1869 Out.initDefault(STM, Ctx,
false);
1871 Out.compute_pgm_resource1_registers =
1872 CurrentProgramInfo.getComputePGMRSrc1(STM, Ctx);
1873 Out.compute_pgm_resource2_registers =
1874 CurrentProgramInfo.getComputePGMRSrc2(STM, Ctx);
1877 Out.is_dynamic_callstack = CurrentProgramInfo.DynamicCallStack;
1905 if (STM.isXNACKEnabled())
1908 Align MaxKernArgAlign;
1909 Out.kernarg_segment_byte_size = STM.getKernArgSegmentSize(
F, MaxKernArgAlign);
1910 Out.wavefront_sgpr_count = CurrentProgramInfo.NumSGPR;
1911 Out.workitem_vgpr_count = CurrentProgramInfo.NumVGPR;
1912 Out.workitem_private_segment_byte_size = CurrentProgramInfo.ScratchSize;
1913 Out.workgroup_group_segment_byte_size = CurrentProgramInfo.LDSSize;
1918 Out.kernarg_segment_alignment =
Log2(std::max(
Align(16), MaxKernArgAlign));
1927 if (ExtraCode && ExtraCode[0]) {
1928 if (ExtraCode[1] != 0)
1931 switch (ExtraCode[0]) {
1943 *
MF->getSubtarget().getRegisterInfo());
1947 int64_t Val = MO.
getImm();
1951 O <<
format(
"0x%" PRIx16,
static_cast<uint16_t
>(Val));
1955 O <<
format(
"0x%" PRIx64,
static_cast<uint64_t
>(Val));
1970void AMDGPUAsmPrinter::emitResourceUsageRemarks(
1976 const char *Name =
"kernel-resource-usage";
1977 const char *Indent =
" ";
1981 if (!Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(Name))
1988 auto EmitResourceUsageRemark = [&](
StringRef RemarkName,
1993 std::string LabelStr = RemarkLabel.str() +
": ";
1994 if (RemarkName !=
"FunctionName")
1995 LabelStr = Indent + LabelStr;
2010 EmitResourceUsageRemark(
"FunctionName",
"Function Name",
2011 MF.getFunction().getName());
2012 EmitResourceUsageRemark(
"NumSGPR",
"TotalSGPRs",
2013 getMCExprStr(CurrentProgramInfo.NumSGPR));
2014 EmitResourceUsageRemark(
"NumVGPR",
"VGPRs",
2015 getMCExprStr(CurrentProgramInfo.NumArchVGPR));
2017 EmitResourceUsageRemark(
"NumAGPR",
"AGPRs",
2018 getMCExprStr(CurrentProgramInfo.NumAccVGPR));
2020 EmitResourceUsageRemark(
"ScratchSize",
"ScratchSize [bytes/lane]",
2021 getMCExprStr(CurrentProgramInfo.ScratchSize));
2023 bool DynStackEvaluatable =
2024 CurrentProgramInfo.DynamicCallStack->evaluateAsAbsolute(DynStack);
2025 StringRef DynamicStackStr =
2026 DynStackEvaluatable && DynStack ?
"True" :
"False";
2027 EmitResourceUsageRemark(
"DynamicStack",
"Dynamic Stack", DynamicStackStr);
2028 EmitResourceUsageRemark(
"Occupancy",
"Occupancy [waves/SIMD]",
2029 getMCExprStr(CurrentProgramInfo.Occupancy));
2030 EmitResourceUsageRemark(
"SGPRSpill",
"SGPRs Spill",
2031 CurrentProgramInfo.SGPRSpill);
2032 EmitResourceUsageRemark(
"VGPRSpill",
"VGPRs Spill",
2033 CurrentProgramInfo.VGPRSpill);
2034 if (isModuleEntryFunction)
2035 EmitResourceUsageRemark(
"BytesLDS",
"LDS Size [bytes/block]",
2036 CurrentProgramInfo.LDSSize);
2077 "AMDGPU Assembly Printer",
false,
false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void EmitPALMetadataCommon(AMDGPUPALMetadata *MD, const SIProgramInfo &CurrentProgramInfo, CallingConv::ID CC, const GCNSubtarget &ST, unsigned DynamicVGPRBlockSize)
const AMDGPUMCExpr * createOccupancy(unsigned InitOcc, const MCExpr *NumSGPRs, const MCExpr *NumVGPRs, unsigned DynamicVGPRBlockSize, const GCNSubtarget &STM, MCContext &Ctx)
Mimics GCNSubtarget::computeOccupancy for MCExpr.
static unsigned getRsrcReg(CallingConv::ID CallConv)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmPrinter()
static amd_element_byte_size_t getElementByteSizeValue(unsigned Size)
static const MCExpr * setBits(const MCExpr *Dst, const MCExpr *Value, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
Set bits in a kernel descriptor MCExpr field: return ((Dst & ~Mask) | (Value << Shift))
static uint32_t getFPMode(SIModeRegisterDefaults Mode)
static std::string computeTypeId(const FunctionType *FTy, const DataLayout &DL)
static const MCExpr * computeAccumOffset(const MCExpr *NumVGPR, MCContext &Ctx)
static void appendTypeEncoding(std::string &Enc, Type *Ty, const DataLayout &DL, bool IsReturnType)
static AsmPrinter * createAMDGPUAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
AMDGPU Assembly printer class.
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
MC infrastructure to propagate the function level resource usage info.
Analyzes how many registers and other resources are used by functions.
The AMDGPU TargetMachine interface definition for hw codegen targets.
AMDHSA kernel descriptor definitions.
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
amd_element_byte_size_t
The values used to define the number of bytes to use for the swizzle element size.
#define AMD_HSA_BITS_SET(dst, mask, val)
@ AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID
@ AMD_CODE_PROPERTY_PRIVATE_ELEMENT_SIZE
@ AMD_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR
@ AMD_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR
@ AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE
@ AMD_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER
@ AMD_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR
@ AMD_CODE_PROPERTY_IS_XNACK_SUPPORTED
@ AMD_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT
@ AMD_CODE_PROPERTY_IS_PTR64
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_EXTERNAL_VISIBILITY
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
OptimizedStructLayoutField Field
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
R600 Assembly printer class.
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
#define R_00B028_SPI_SHADER_PGM_RSRC1_PS
#define R_0286E8_SPI_TMPRING_SIZE
#define FP_ROUND_MODE_DP(x)
#define C_00B84C_SCRATCH_EN
#define FP_ROUND_ROUND_TO_NEAREST
#define R_0286D0_SPI_PS_INPUT_ADDR
#define R_00B860_COMPUTE_TMPRING_SIZE
#define R_00B428_SPI_SHADER_PGM_RSRC1_HS
#define R_00B328_SPI_SHADER_PGM_RSRC1_ES
#define R_00B528_SPI_SHADER_PGM_RSRC1_LS
#define R_0286CC_SPI_PS_INPUT_ENA
#define R_00B128_SPI_SHADER_PGM_RSRC1_VS
#define FP_DENORM_MODE_DP(x)
#define R_00B848_COMPUTE_PGM_RSRC1
#define FP_ROUND_MODE_SP(x)
#define FP_DENORM_MODE_SP(x)
#define R_00B228_SPI_SHADER_PGM_RSRC1_GS
#define S_00B02C_EXTRA_LDS_SIZE(x)
#define R_00B84C_COMPUTE_PGM_RSRC2
#define R_00B02C_SPI_SHADER_PGM_RSRC2_PS
std::unique_ptr< MCStreamer > && Streamer
static const int BlockSize
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
const MCSubtargetInfo * getGlobalSTI() const
void emitImplicitDef(const MachineInstr *MI) const override
Targets can override this to customize the output of IMPLICIT_DEF instructions in verbose mode.
std::vector< std::string > DisasmLines
std::function< const AMDGPUResourceUsageAnalysisImpl::SIFunctionResourceInfo *(MachineFunction &)> GetResourceUsage
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
void endFunction(const MachineFunction *MF)
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
std::vector< std::string > HexLines
bool IsTargetStreamerInitialized
void emitGlobalVariable(const GlobalVariable *GV) override
Emit the specified global variable to the .s file.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
AMDGPUAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
void emitFunctionBodyStart() override
Targets can override this to emit stuff before the first basic block in the function.
void emitBasicBlockStart(const MachineBasicBlock &MBB) override
Targets can override this to emit stuff at the start of a basic block.
AMDGPUTargetStreamer * getTargetStreamer() const
static void printRegOperand(MCRegister Reg, raw_ostream &O, const MCRegisterInfo &MRI)
AMDGPU target specific MCExpr operations.
static const AMDGPUMCExpr * createInstPrefSize(const MCExpr *CodeSizeBytes, MCContext &Ctx)
Create an expression for instruction prefetch size computation: min(divideCeil(CodeSizeBytes,...
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createTotalNumVGPR(const MCExpr *NumAGPR, const MCExpr *NumVGPR, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
bool isMemoryBound() const
bool isModuleEntryFunction() const
bool needsWaveLimiter() const
uint32_t getLDSSize() const
bool isEntryFunction() const
std::pair< unsigned, unsigned > getOccupancyWithWorkGroupSizes(uint32_t LDSBytes, const Function &F) const
Subtarget's minimum/maximum occupancy, in number of waves per EU, that can be achieved when the only ...
unsigned getAddressableLocalMemorySize() const
Return the maximum number of bytes of LDS that can be allocated to a single workgroup.
unsigned getKernArgSegmentSize(const Function &F, Align &MaxAlign) const
unsigned getWavefrontSize() const
static bool EnableObjectLinking
virtual void EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName, const AMDGPU::MCKernelDescriptor &KernelDescriptor, const MCExpr *NextVGPR, const MCExpr *NextSGPR, const MCExpr *ReserveVCC, const MCExpr *ReserveFlatScr)
virtual void emitAMDGPUInfo(const AMDGPU::InfoSectionData &Data)
AMDGPUPALMetadata * getPALMetadata()
void initializeTargetID(const MCSubtargetInfo &STI, bool ApplyFeatureString=false)
virtual void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV)
virtual bool EmitISAVersion()
virtual void EmitMCResourceInfo(const MCSymbol *NumVGPR, const MCSymbol *NumAGPR, const MCSymbol *NumExplicitSGPR, const MCSymbol *NumNamedBarrier, const MCSymbol *PrivateSegmentSize, const MCSymbol *UsesVCC, const MCSymbol *UsesFlatScratch, const MCSymbol *HasDynamicallySizedStack, const MCSymbol *HasRecursion, const MCSymbol *HasIndirectCall)
virtual bool EmitCodeEnd(const MCSubtargetInfo &STI)
virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type)
const std::optional< AMDGPU::TargetID > & getTargetID() const
void emitDirectiveAMDGCNTargetOnce()
Emit the .amdgcn_target directive unless it has already been emitted to this streamer.
virtual void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header)
virtual void EmitMCResourceMaximums(const MCSymbol *MaxVGPR, const MCSymbol *MaxAGPR, const MCSymbol *MaxSGPR, const MCSymbol *MaxNamedBarrier)
GPUKind getGPUKind() const
bool isXnackOnOrAny() const
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents an incoming formal argument to a Function.
Collects and handles AsmPrinter objects required to build debug or EH information.
This class is intended to be used as a driving class for all asm writers.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbol(const GlobalValue *GV) const
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
dwarf::Attribute TypeAddressSpaceAttribute
The attribute used for a pointer type's DWARF address space.
TargetMachine & TM
Target machine description.
MachineFunction * MF
The current machine function.
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const
Return true if the basic block has exactly one predecessor and the control transfer mechanism between...
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
MachineOptimizationRemarkEmitter * ORE
Optimization remark emitter.
AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)
MCSymbol * CurrentFnSym
The symbol for the current function.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
MCContext & OutContext
This is the context for the output file that we are streaming.
bool doFinalization(Module &M) override
Shut down the asmprinter.
virtual void emitBasicBlockStart(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the start of a basic block.
void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const
This emits visibility information about symbol, if this is supported by the target.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const MCAsmInfo & MAI
Target Asm Printer information.
std::function< MachineModuleInfo *()> GetMMI
bool isVerbose() const
Return true if assembly output should contain comments.
MCSymbol * getFunctionEnd() const
void getNameWithPrefix(SmallVectorImpl< char > &Name, const GlobalValue *GV) const
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void addAsmPrinterHandler(std::unique_ptr< AsmPrinterHandler > Handler)
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
A parsed version of the target data layout string in and methods for querying it.
DISubprogram * getSubprogram() const
Get the attached subprogram.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
unsigned getMinNumSGPRs(unsigned WavesPerEU) const
unsigned getTotalNumVGPRs() const
unsigned getMinNumVGPRs(unsigned WavesPerEU, unsigned DynamicVGPRBlockSize) const
bool hasInstPrefSize() const
bool isCuModeEnabled() const
const AMDGPU::TargetID & getTargetID() const
void getInstPrefSizeArgs(uint32_t &Mask, uint32_t &Shift, uint32_t &Width, uint32_t &CacheLineSize) const
unsigned getMaxNumUserSGPRs() const
unsigned getMaxWavesPerEU() const
Generation getGeneration() const
unsigned getAddressableNumSGPRs() const
unsigned getMaxWaveScratchSize() const
static AMDGPU::TargetIDSetting getTargetIDSettingFromModuleFlag(const Module &M, StringRef FlagName)
Get xnack/sramecc setting from module flag or cl::opt (for testing).
bool hasKernargSegmentPtr() const
bool hasDispatchID() const
bool hasPrivateSegmentBuffer() const
bool hasPrivateSegmentSize() const
bool hasDispatchPtr() const
bool hasFlatScratchInit() const
VisibilityTypes getVisibility() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
unsigned getAddressSpace() const
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
This is an important class for using LLVM in a threaded context.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
MCCodeEmitter * getEmitterPtr() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createLOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createMul(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createGT(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createShl(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
MCSection * getTextSection() const
MCContext & getContext() const
This represents a section on linux, lots of unix variants and some bare metal systems.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
bool hasInstructions() const
Generic base class for all target subtargets.
StringRef getFeatureString() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
void redefineIfPossible()
Prepare this symbol to be redefined.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCStreamer & getStreamer()
static const MCUnaryExpr * createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
MCContext & getContext() const
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
A Module instance is used to store all the information related to an LLVM module.
LLVM_ABI unsigned getNumOperands() const
iterator_range< op_iterator > operands()
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
unsigned getNumWaveDispatchVGPRs() const
unsigned getNumSpilledVGPRs() const
unsigned getNumWaveDispatchSGPRs() const
unsigned getNumSpilledSGPRs() const
GCNUserSGPRUsageInfo & getUserSGPRInfo()
unsigned getDynamicVGPRBlockSize() const
unsigned getMaxWavesPerEU() const
bool hasWorkGroupIDZ() const
bool hasWorkGroupIDY() const
SIModeRegisterDefaults getMode() const
bool hasWorkGroupInfo() const
bool hasWorkItemIDY() const
bool hasWorkGroupIDX() const
unsigned getNumUserSGPRs() const
unsigned getScratchReservedForDynamicVGPRs() const
bool isDynamicVGPREnabled() const
unsigned getPSInputAddr() const
bool hasWorkItemIDZ() const
unsigned getPSInputEnable() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
std::pair< typename Base::iterator, bool > insert(StringRef key)
Primary interface to the complete machine description for the target machine.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ LOCAL_ADDRESS
Address space for local memory.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
bool isSGPROccupancyLimited(const MCSubtargetInfo &STI)
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
static constexpr unsigned MaxDynamicVGPRBlocks
Maximum number of VGPR blocks that can be allocated in dynamic VGPR mode.
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
unsigned getNumExtraSGPRs(const MCSubtargetInfo &STI, bool VCCUsed, bool FlatScrUsed, bool XNACKUsed)
unsigned getVGPRAllocGranule(const MCSubtargetInfo &STI, unsigned DynamicVGPRBlockSize, std::optional< bool > EnableWavefrontSize32)
LLVM_ABI unsigned getLDSEncodingGranule(GPUKind AK)
void printAMDGPUMCExpr(const MCExpr *Expr, raw_ostream &OS, const MCAsmInfo *MAI)
LLVM_READNONE constexpr bool isModuleEntryFunctionCC(CallingConv::ID CC)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
LLVM_ABI unsigned getTotalNumSGPRs(GPUKind AK)
const MCExpr * maskShiftSet(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
Provided with the MCExpr * Val, uint32 Mask and Shift, will return the masked and left shifted,...
unsigned getAMDHSACodeObjectVersion(const Module &M)
bool isTgSplitEnabled(const Function &F)
GPUKind
GPU kinds supported by the AMDGPU target.
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READNONE constexpr bool isKernel(CallingConv::ID CC)
LLVM_ABI unsigned getSGPRAllocGranule(GPUKind AK)
LLVM_READNONE constexpr bool isEntryFunctionCC(CallingConv::ID CC)
LLVM_READNONE constexpr bool isCompute(CallingConv::ID CC)
bool hasMAIInsts(const MCSubtargetInfo &STI)
LLVM_ABI Triple::SubArchType getSubArch(GPUKind AK)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU)
const MCExpr * foldAMDGPUMCExpr(const MCExpr *Expr, MCContext &Ctx)
bool isGFX10Plus(const MCSubtargetInfo &STI)
constexpr std::pair< unsigned, unsigned > getShiftMask(unsigned Value)
Deduce the least significant bit aligned shift and mask values for a binary Complement Value (as they...
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
std::pair< unsigned, unsigned > getIntegerPairAttribute(const Function &F, StringRef Name, std::pair< unsigned, unsigned > Default, bool OnlyFirstRequired)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Target & getTheR600Target()
The target for R600 GPUs.
AsmPrinter * createR600AsmPrinterPass(TargetMachine &TM, std::unique_ptr< MCStreamer > &&Streamer)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM, AsmPrinter &AsmPrinter)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Target & getTheGCNTarget()
The target for GCN GPUs.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM, MachineFunction &MF, AsmPrinter &AsmPrinter)
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
unsigned Log2(Align A)
Returns the log2 of the alignment.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
bool HasDynamicallySizedStack
uint64_t PrivateSegmentSize
AMDGPUResourceUsageAnalysisImpl::SIFunctionResourceInfo FunctionResourceInfo
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
static const MCExpr * bits_get(const MCExpr *Src, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * compute_pgm_rsrc1
const MCExpr * group_segment_fixed_size
const MCExpr * kernel_code_properties
This struct is a compact representation of a valid (non-zero power of two) alignment.
Track resource usage for kernels / entry functions.
const MCExpr * NumArchVGPR
const MCExpr * VGPRBlocks
const MCExpr * ScratchBlocks
const MCExpr * ComputePGMRSrc3
const MCExpr * getComputePGMRSrc1(const GCNSubtarget &ST, MCContext &Ctx) const
Compute the value of the ComputePGMRsrc1 register.
uint32_t TrapHandlerEnable
const MCExpr * NamedBarCnt
const MCExpr * ScratchEnable
const MCExpr * AccumOffset
const MCExpr * NumAccVGPR
const MCExpr * DynamicCallStack
const MCExpr * SGPRBlocks
const MCExpr * NumVGPRsForWavesPerEU
const MCExpr * ScratchSize
const MCExpr * NumSGPRsForWavesPerEU
const MCExpr * getComputePGMRSrc2(const GCNSubtarget &ST, MCContext &Ctx) const
Compute the value of the ComputePGMRsrc2 register.
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn)
RegisterAsmPrinter - Register an AsmPrinter implementation for the given target.