diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 162 |
1 files changed, 85 insertions, 77 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp index eef8fe2fc3b7..c655e5ec87b7 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp @@ -17,37 +17,27 @@ #include "AMDGPUAsmPrinter.h" #include "AMDGPU.h" -#include "AMDGPUSubtarget.h" -#include "AMDGPUTargetMachine.h" +#include "AMDGPUHSAMetadataStreamer.h" +#include "AMDKernelCodeT.h" +#include "GCNSubtarget.h" #include "MCTargetDesc/AMDGPUInstPrinter.h" -#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "MCTargetDesc/AMDGPUTargetStreamer.h" #include "R600AsmPrinter.h" -#include "R600Defines.h" -#include "R600MachineFunctionInfo.h" -#include "R600RegisterInfo.h" -#include "SIDefines.h" -#include "SIInstrInfo.h" #include "SIMachineFunctionInfo.h" -#include "SIRegisterInfo.h" #include "TargetInfo/AMDGPUTargetInfo.h" #include "Utils/AMDGPUBaseInfo.h" -#include "llvm/BinaryFormat/ELF.h" -#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/Support/AMDGPUMetadata.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/TargetParser.h" +#include "llvm/Support/AMDHSAKernelDescriptor.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; using namespace llvm::AMDGPU; -using namespace llvm::AMDGPU::HSAMD; // We need to tell the runtime some amount ahead of time if we don't know the // true stack size. Assume a smaller number if this is only due to dynamic / @@ -108,10 +98,13 @@ extern "C" void LLVM_EXTERNAL_VISIBILITY LLVMInitializeAMDGPUAsmPrinter() { AMDGPUAsmPrinter::AMDGPUAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) : AsmPrinter(TM, std::move(Streamer)) { - if (IsaInfo::hasCodeObjectV3(getGlobalSTI())) - HSAMetadataStream.reset(new MetadataStreamerV3()); - else - HSAMetadataStream.reset(new MetadataStreamerV2()); + if (TM.getTargetTriple().getOS() == Triple::AMDHSA) { + if (isHsaAbiVersion2(getGlobalSTI())) { + HSAMetadataStream.reset(new HSAMD::MetadataStreamerV2()); + } else { + HSAMetadataStream.reset(new HSAMD::MetadataStreamerV3()); + } + } } StringRef AMDGPUAsmPrinter::getPassName() const { @@ -129,7 +122,7 @@ AMDGPUTargetStreamer* AMDGPUAsmPrinter::getTargetStreamer() const { } void AMDGPUAsmPrinter::emitStartOfAsmFile(Module &M) { - if (IsaInfo::hasCodeObjectV3(getGlobalSTI())) { + if (isHsaAbiVersion3(getGlobalSTI())) { std::string ExpectedTarget; raw_string_ostream ExpectedTargetOS(ExpectedTarget); IsaInfo::streamIsaVersion(getGlobalSTI(), ExpectedTargetOS); @@ -147,7 +140,7 @@ void AMDGPUAsmPrinter::emitStartOfAsmFile(Module &M) { if (TM.getTargetTriple().getOS() == Triple::AMDPAL) getTargetStreamer()->getPALMetadata()->readFromIR(M); - if (IsaInfo::hasCodeObjectV3(getGlobalSTI())) + if (isHsaAbiVersion3(getGlobalSTI())) return; // HSA emits NT_AMDGPU_HSA_CODE_OBJECT_VERSION for code objects v2. @@ -165,7 +158,8 @@ void AMDGPUAsmPrinter::emitEndOfAsmFile(Module &M) { if (!getTargetStreamer()) return; - if (!IsaInfo::hasCodeObjectV3(getGlobalSTI())) { + if (TM.getTargetTriple().getOS() != Triple::AMDHSA || + isHsaAbiVersion2(getGlobalSTI())) { // Emit ISA Version (NT_AMD_AMDGPU_ISA). std::string ISAVersionString; raw_string_ostream ISAVersionStream(ISAVersionString); @@ -203,7 +197,7 @@ void AMDGPUAsmPrinter::emitFunctionBodyStart() { const GCNSubtarget &STM = MF->getSubtarget<GCNSubtarget>(); const Function &F = MF->getFunction(); - if (!STM.hasCodeObjectV3() && STM.isAmdHsaOrMesa(F) && + if ((STM.isMesaKernel(F) || isHsaAbiVersion2(getGlobalSTI())) && (F.getCallingConv() == CallingConv::AMDGPU_KERNEL || F.getCallingConv() == CallingConv::SPIR_KERNEL)) { amd_kernel_code_t KernelCode; @@ -220,8 +214,8 @@ void AMDGPUAsmPrinter::emitFunctionBodyEnd() { if (!MFI.isEntryFunction()) return; - if (!IsaInfo::hasCodeObjectV3(getGlobalSTI()) || - TM.getTargetTriple().getOS() != Triple::AMDHSA) + if (TM.getTargetTriple().getOS() != Triple::AMDHSA || + isHsaAbiVersion2(getGlobalSTI())) return; auto &Streamer = getTargetStreamer()->getStreamer(); @@ -256,8 +250,8 @@ void AMDGPUAsmPrinter::emitFunctionBodyEnd() { } void AMDGPUAsmPrinter::emitFunctionEntryLabel() { - if (IsaInfo::hasCodeObjectV3(getGlobalSTI()) && - TM.getTargetTriple().getOS() == Triple::AMDHSA) { + if (TM.getTargetTriple().getOS() == Triple::AMDHSA && + isHsaAbiVersion3(getGlobalSTI())) { AsmPrinter::emitFunctionEntryLabel(); return; } @@ -334,7 +328,7 @@ bool AMDGPUAsmPrinter::doFinalization(Module &M) { // causing stale data in caches. Arguably this should be done by the linker, // which is why this isn't done for Mesa. const MCSubtargetInfo &STI = *getGlobalSTI(); - if (AMDGPU::isGFX10(STI) && + if (AMDGPU::isGFX10Plus(STI) && (STI.getTargetTriple().getOS() == Triple::AMDHSA || STI.getTargetTriple().getOS() == Triple::AMDPAL)) { OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); @@ -410,12 +404,12 @@ amdhsa::kernel_descriptor_t AMDGPUAsmPrinter::getAmdhsaKernelDescriptor( memset(&KernelDescriptor, 0x0, sizeof(KernelDescriptor)); assert(isUInt<32>(PI.ScratchSize)); - assert(isUInt<32>(PI.ComputePGMRSrc1)); + assert(isUInt<32>(PI.getComputePGMRSrc1())); assert(isUInt<32>(PI.ComputePGMRSrc2)); KernelDescriptor.group_segment_fixed_size = PI.LDSSize; KernelDescriptor.private_segment_fixed_size = PI.ScratchSize; - KernelDescriptor.compute_pgm_rsrc1 = PI.ComputePGMRSrc1; + KernelDescriptor.compute_pgm_rsrc1 = PI.getComputePGMRSrc1(); KernelDescriptor.compute_pgm_rsrc2 = PI.ComputePGMRSrc2; KernelDescriptor.kernel_code_properties = getAmdhsaKernelCodeProperties(MF); @@ -442,7 +436,7 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { OutStreamer->SwitchSection(ConfigSection); } - if (MFI->isEntryFunction()) { + if (MFI->isModuleEntryFunction()) { getSIProgramInfo(CurrentProgramInfo, MF); } else { auto I = CallGraphResourceInfo.insert( @@ -452,9 +446,12 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { Info = analyzeResourceUsage(MF); } - if (STM.isAmdPalOS()) - EmitPALMetadata(MF, CurrentProgramInfo); - else if (!STM.isAmdHsaOS()) { + if (STM.isAmdPalOS()) { + if (MFI->isEntryFunction()) + EmitPALMetadata(MF, CurrentProgramInfo); + else if (MFI->isModuleEntryFunction()) + emitPALFunctionMetadata(MF); + } else if (!STM.isAmdHsaOS()) { EmitProgramInfoSI(MF, CurrentProgramInfo); } @@ -532,6 +529,9 @@ bool AMDGPUAsmPrinter::runOnMachineFunction(MachineFunction &MF) { " WaveLimiterHint : " + Twine(MFI->needsWaveLimiter()), false); OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:SCRATCH_EN: " + + Twine(G_00B84C_SCRATCH_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); + OutStreamer->emitRawComment( " COMPUTE_PGM_RSRC2:USER_SGPR: " + Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false); OutStreamer->emitRawComment( @@ -741,7 +741,7 @@ AMDGPUAsmPrinter::SIFunctionResourceInfo AMDGPUAsmPrinter::analyzeResourceUsage( llvm_unreachable("src_pops_exiting_wave_id should not be used"); case AMDGPU::NoRegister: - assert(MI.isDebugInstr()); + assert(MI.isDebugInstr() && "Instruction uses invalid noreg register"); continue; case AMDGPU::VCC: @@ -915,7 +915,22 @@ AMDGPUAsmPrinter::SIFunctionResourceInfo AMDGPUAsmPrinter::analyzeResourceUsage( = TII->getNamedOperand(MI, AMDGPU::OpName::callee); const Function *Callee = getCalleeFunction(*CalleeOp); - if (!Callee || Callee->isDeclaration()) { + DenseMap<const Function *, SIFunctionResourceInfo>::const_iterator I = + CallGraphResourceInfo.end(); + bool IsExternal = !Callee || Callee->isDeclaration(); + if (!IsExternal) + I = CallGraphResourceInfo.find(Callee); + + if (IsExternal || I == CallGraphResourceInfo.end()) { + // Avoid crashing on undefined behavior with an illegal call to a + // kernel. If a callsite's calling convention doesn't match the + // function's, it's undefined behavior. If the callsite calling + // convention does match, that would have errored earlier. + // FIXME: The verifier shouldn't allow this. + if (!IsExternal && + AMDGPU::isEntryFunctionCC(Callee->getCallingConv())) + report_fatal_error("invalid call to entry function"); + // If this is a call to an external function, we can't do much. Make // conservative guesses. @@ -936,19 +951,6 @@ AMDGPUAsmPrinter::SIFunctionResourceInfo AMDGPUAsmPrinter::analyzeResourceUsage( // We force CodeGen to run in SCC order, so the callee's register // usage etc. should be the cumulative usage of all callees. - auto I = CallGraphResourceInfo.find(Callee); - if (I == CallGraphResourceInfo.end()) { - // Avoid crashing on undefined behavior with an illegal call to a - // kernel. If a callsite's calling convention doesn't match the - // function's, it's undefined behavior. If the callsite calling - // convention does match, that would have errored earlier. - // FIXME: The verifier shouldn't allow this. - if (AMDGPU::isEntryFunctionCC(Callee->getCallingConv())) - report_fatal_error("invalid call to entry function"); - - llvm_unreachable("callee should have been handled before caller"); - } - MaxSGPR = std::max(I->second.NumExplicitSGPR - 1, MaxSGPR); MaxVGPR = std::max(I->second.NumVGPR - 1, MaxVGPR); MaxAGPR = std::max(I->second.NumAGPR - 1, MaxAGPR); @@ -989,7 +991,9 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, ProgInfo.FlatUsed = Info.UsesFlatScratch; ProgInfo.DynamicCallStack = Info.HasDynamicallySizedStack || Info.HasRecursion; - if (!isUInt<32>(ProgInfo.ScratchSize)) { + const uint64_t MaxScratchPerWorkitem = + GCNSubtarget::MaxWaveScratchSize / STM.getWavefrontSize(); + if (ProgInfo.ScratchSize > MaxScratchPerWorkitem) { DiagnosticInfoStackSize DiagStackSize(MF.getFunction(), ProgInfo.ScratchSize, DS_Error); MF.getFunction().getContext().diagnose(DiagStackSize); @@ -1023,18 +1027,26 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, // Account for extra SGPRs and VGPRs reserved for debugger use. ProgInfo.NumSGPR += ExtraSGPRs; + const Function &F = MF.getFunction(); + // Ensure there are enough SGPRs and VGPRs for wave dispatch, where wave // dispatch registers are function args. unsigned WaveDispatchNumSGPR = 0, WaveDispatchNumVGPR = 0; - for (auto &Arg : MF.getFunction().args()) { - unsigned NumRegs = (Arg.getType()->getPrimitiveSizeInBits() + 31) / 32; - if (Arg.hasAttribute(Attribute::InReg)) - WaveDispatchNumSGPR += NumRegs; - else - WaveDispatchNumVGPR += NumRegs; + + if (isShader(F.getCallingConv())) { + // FIXME: We should be using the number of registers determined during + // calling convention lowering to legalize the types. + const DataLayout &DL = F.getParent()->getDataLayout(); + for (auto &Arg : F.args()) { + unsigned NumRegs = (DL.getTypeSizeInBits(Arg.getType()) + 31) / 32; + if (Arg.hasAttribute(Attribute::InReg)) + WaveDispatchNumSGPR += NumRegs; + else + WaveDispatchNumVGPR += NumRegs; + } + ProgInfo.NumSGPR = std::max(ProgInfo.NumSGPR, WaveDispatchNumSGPR); + ProgInfo.NumVGPR = std::max(ProgInfo.NumVGPR, WaveDispatchNumVGPR); } - ProgInfo.NumSGPR = std::max(ProgInfo.NumSGPR, WaveDispatchNumSGPR); - ProgInfo.NumVGPR = std::max(ProgInfo.NumVGPR, WaveDispatchNumVGPR); // Adjust number of registers used to meet default/requested minimum/maximum // number of waves per execution unit request. @@ -1129,18 +1141,6 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo, ProgInfo.MemOrdered = 1; } - ProgInfo.ComputePGMRSrc1 = - S_00B848_VGPRS(ProgInfo.VGPRBlocks) | - S_00B848_SGPRS(ProgInfo.SGPRBlocks) | - S_00B848_PRIORITY(ProgInfo.Priority) | - S_00B848_FLOAT_MODE(ProgInfo.FloatMode) | - S_00B848_PRIV(ProgInfo.Priv) | - S_00B848_DX10_CLAMP(ProgInfo.DX10Clamp) | - S_00B848_DEBUG_MODE(ProgInfo.DebugMode) | - S_00B848_IEEE_MODE(ProgInfo.IEEEMode) | - S_00B848_WGP_MODE(ProgInfo.WgpMode) | - S_00B848_MEM_ORDERED(ProgInfo.MemOrdered); - // 0 = X, 1 = XY, 2 = XYZ unsigned TIDIGCompCnt = 0; if (MFI->hasWorkItemIDZ()) @@ -1189,7 +1189,7 @@ void AMDGPUAsmPrinter::EmitProgramInfoSI(const MachineFunction &MF, if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) { OutStreamer->emitInt32(R_00B848_COMPUTE_PGM_RSRC1); - OutStreamer->emitInt32(CurrentProgramInfo.ComputePGMRSrc1); + OutStreamer->emitInt32(CurrentProgramInfo.getComputePGMRSrc1()); OutStreamer->emitInt32(R_00B84C_COMPUTE_PGM_RSRC2); OutStreamer->emitInt32(CurrentProgramInfo.ComputePGMRSrc2); @@ -1238,12 +1238,10 @@ void AMDGPUAsmPrinter::EmitPALMetadata(const MachineFunction &MF, MD->setEntryPoint(CC, MF.getFunction().getName()); MD->setNumUsedVgprs(CC, CurrentProgramInfo.NumVGPRsForWavesPerEU); MD->setNumUsedSgprs(CC, CurrentProgramInfo.NumSGPRsForWavesPerEU); - if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) { - MD->setRsrc1(CC, CurrentProgramInfo.ComputePGMRSrc1); + MD->setRsrc1(CC, CurrentProgramInfo.getPGMRSrc1(CC)); + if (AMDGPU::isCompute(CC)) { MD->setRsrc2(CC, CurrentProgramInfo.ComputePGMRSrc2); } else { - MD->setRsrc1(CC, S_00B028_VGPRS(CurrentProgramInfo.VGPRBlocks) | - S_00B028_SGPRS(CurrentProgramInfo.SGPRBlocks)); if (CurrentProgramInfo.ScratchBlocks > 0) MD->setRsrc2(CC, S_00B84C_SCRATCH_EN(1)); } @@ -1260,6 +1258,16 @@ void AMDGPUAsmPrinter::EmitPALMetadata(const MachineFunction &MF, MD->setWave32(MF.getFunction().getCallingConv()); } +void AMDGPUAsmPrinter::emitPALFunctionMetadata(const MachineFunction &MF) { + auto *MD = getTargetStreamer()->getPALMetadata(); + const MachineFrameInfo &MFI = MF.getFrameInfo(); + MD->setFunctionScratchSize(MF, MFI.getStackSize()); + // Set compute registers + MD->setRsrc1(CallingConv::AMDGPU_CS, + CurrentProgramInfo.getPGMRSrc1(CallingConv::AMDGPU_CS)); + MD->setRsrc2(CallingConv::AMDGPU_CS, CurrentProgramInfo.ComputePGMRSrc2); +} + // This is supposed to be log2(Size) static amd_element_byte_size_t getElementByteSizeValue(unsigned Size) { switch (Size) { @@ -1287,7 +1295,7 @@ void AMDGPUAsmPrinter::getAmdKernelCode(amd_kernel_code_t &Out, AMDGPU::initDefaultAMDKernelCodeT(Out, &STM); Out.compute_pgm_resource_registers = - CurrentProgramInfo.ComputePGMRSrc1 | + CurrentProgramInfo.getComputePGMRSrc1() | (CurrentProgramInfo.ComputePGMRSrc2 << 32); Out.code_properties |= AMD_CODE_PROPERTY_IS_PTR64; @@ -1296,7 +1304,7 @@ void AMDGPUAsmPrinter::getAmdKernelCode(amd_kernel_code_t &Out, AMD_HSA_BITS_SET(Out.code_properties, AMD_CODE_PROPERTY_PRIVATE_ELEMENT_SIZE, - getElementByteSizeValue(STM.getMaxPrivateElementSize())); + getElementByteSizeValue(STM.getMaxPrivateElementSize(true))); if (MFI->hasPrivateSegmentBuffer()) { Out.code_properties |= |
