AMDGPU: Add support for isa version note

- Emit NT_AMD_AMDGPU_ISA
  - Add assembler parsing for isa version directive
    - If isa version directive does not match command line arguments, then return error

Differential Revision: https://reviews.llvm.org/D38748

llvm-svn: 315808
This commit is contained in:
Konstantin Zhuravlyov 2017-10-14 15:40:33 +00:00
parent f367c27d2d
commit 9c05b2bc3b
10 changed files with 163 additions and 10 deletions

View File

@ -132,6 +132,22 @@ void AMDGPUAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) {
if (TM.getTargetTriple().getArch() != Triple::amdgcn)
return;
// Emit ISA Version (NT_AMD_AMDGPU_ISA).
std::string ISAVersionString;
raw_string_ostream ISAVersionStream(ISAVersionString);
IsaInfo::streamIsaVersion(getSTI(), ISAVersionStream);
getTargetStreamer().EmitISAVersion(ISAVersionStream.str());
// Emit HSA Metadata (NT_AMD_AMDGPU_HSA_METADATA).
if (TM.getTargetTriple().getOS() == Triple::AMDHSA) {
HSAMetadataStream.end();
getTargetStreamer().EmitHSAMetadata(HSAMetadataStream.getHSAMetadata());
}
// Emit PAL Metadata (NT_AMD_AMDGPU_PAL_METADATA).
if (TM.getTargetTriple().getOS() == Triple::AMDPAL) {
// Copy the PAL metadata from the map where we collected it into a vector,
// then write it as a .note.
@ -142,12 +158,6 @@ void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) {
}
getTargetStreamer().EmitPALMetadata(PALMetadataVector);
}
if (TM.getTargetTriple().getOS() != Triple::AMDHSA)
return;
HSAMetadataStream.end();
getTargetStreamer().EmitHSAMetadata(HSAMetadataStream.getHSAMetadata());
}
bool AMDGPUAsmPrinter::isBlockOnlyReachableByFallthrough(

View File

@ -832,6 +832,7 @@ private:
bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const;
bool ParseDirectiveAMDGPUHsaKernel();
bool ParseDirectiveISAVersion();
bool ParseDirectiveHSAMetadata();
bool ParseDirectivePALMetadata();
@ -2452,6 +2453,25 @@ bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
return false;
}
bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
auto ISAVersionStringFromASM = getLexer().getTok().getStringContents();
std::string ISAVersionStringFromSTI;
raw_string_ostream ISAVersionStreamFromSTI(ISAVersionStringFromSTI);
IsaInfo::streamIsaVersion(&getSTI(), ISAVersionStreamFromSTI);
if (ISAVersionStringFromASM != ISAVersionStreamFromSTI.str()) {
return Error(getParser().getTok().getLoc(),
".amd_amdgpu_isa directive does not match triple and/or mcpu "
"arguments specified through the command line");
}
getTargetStreamer().EmitISAVersion(ISAVersionStreamFromSTI.str());
Lex();
return false;
}
bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
std::string HSAMetadataString;
raw_string_ostream YamlStream(HSAMetadataString);
@ -2527,6 +2547,9 @@ bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
if (IDVal == ".amdgpu_hsa_kernel")
return ParseDirectiveAMDGPUHsaKernel();
if (IDVal == ".amd_amdgpu_isa")
return ParseDirectiveISAVersion();
if (IDVal == AMDGPU::HSAMD::AssemblerDirectiveBegin)
return ParseDirectiveHSAMetadata();

View File

@ -39,9 +39,6 @@ using namespace llvm::AMDGPU;
// AMDGPUTargetStreamer
//===----------------------------------------------------------------------===//
AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S)
: MCTargetStreamer(S) {}
bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) {
HSAMD::Metadata HSAMetadata;
if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
@ -94,6 +91,11 @@ void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
}
}
bool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) {
OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n";
return true;
}
bool AMDGPUTargetAsmStreamer::EmitHSAMetadata(
const AMDGPU::HSAMD::Metadata &HSAMetadata) {
std::string HSAMetadataString;
@ -208,6 +210,28 @@ void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
}
bool AMDGPUTargetELFStreamer::EmitISAVersion(StringRef IsaVersionString) {
// Create two labels to mark the beginning and end of the desc field
// and a MCExpr to calculate the size of the desc field.
auto &Context = getContext();
auto *DescBegin = Context.createTempSymbol();
auto *DescEnd = Context.createTempSymbol();
auto *DescSZ = MCBinaryExpr::createSub(
MCSymbolRefExpr::create(DescEnd, Context),
MCSymbolRefExpr::create(DescBegin, Context), Context);
EmitAMDGPUNote(
DescSZ,
ELF::NT_AMD_AMDGPU_ISA,
[&](MCELFStreamer &OS) {
OS.EmitLabel(DescBegin);
OS.EmitBytes(IsaVersionString);
OS.EmitLabel(DescEnd);
}
);
return true;
}
bool AMDGPUTargetELFStreamer::EmitHSAMetadata(
const AMDGPU::HSAMD::Metadata &HSAMetadata) {
std::string HSAMetadataString;

View File

@ -12,6 +12,7 @@
#include "AMDKernelCodeT.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/AMDGPUMetadata.h"
namespace llvm {
@ -30,7 +31,8 @@ protected:
MCContext &getContext() const { return Streamer.getContext(); }
public:
AMDGPUTargetStreamer(MCStreamer &S);
AMDGPUTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
virtual void EmitDirectiveHSACodeObjectVersion(uint32_t Major,
uint32_t Minor) = 0;
@ -43,6 +45,9 @@ public:
virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) = 0;
/// \returns True on success, false on failure.
virtual bool EmitISAVersion(StringRef IsaVersionString) = 0;
/// \returns True on success, false on failure.
virtual bool EmitHSAMetadata(StringRef HSAMetadataString);
@ -68,6 +73,9 @@ public:
void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
/// \returns True on success, false on failure.
bool EmitISAVersion(StringRef IsaVersionString) override;
/// \returns True on success, false on failure.
bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) override;
@ -97,6 +105,9 @@ public:
void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
/// \returns True on success, false on failure.
bool EmitISAVersion(StringRef IsaVersionString) override;
/// \returns True on success, false on failure.
bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) override;

View File

@ -147,6 +147,21 @@ IsaVersion getIsaVersion(const FeatureBitset &Features) {
return {7, 0, 0};
}
void streamIsaVersion(const MCSubtargetInfo *STI, raw_ostream &Stream) {
auto TargetTriple = STI->getTargetTriple();
auto ISAVersion = IsaInfo::getIsaVersion(STI->getFeatureBits());
Stream << TargetTriple.getArchName() << '-'
<< TargetTriple.getVendorName() << '-'
<< TargetTriple.getOSName() << '-'
<< TargetTriple.getEnvironmentName() << '-'
<< "gfx"
<< ISAVersion.Major
<< ISAVersion.Minor
<< ISAVersion.Stepping;
Stream.flush();
}
unsigned getWavefrontSize(const FeatureBitset &Features) {
if (Features.test(FeatureWavefrontSize16))
return 16;

View File

@ -19,6 +19,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstdint>
#include <string>
#include <utility>
namespace llvm {
@ -54,6 +55,9 @@ struct IsaVersion {
/// \returns Isa version for given subtarget \p Features.
IsaVersion getIsaVersion(const FeatureBitset &Features);
/// \brief Streams isa version string for given subtarget \p STI into \p Stream.
void streamIsaVersion(const MCSubtargetInfo *STI, raw_ostream &Stream);
/// \returns Wavefront size for given subtarget \p Features.
unsigned getWavefrontSize(const FeatureBitset &Features);

View File

@ -0,0 +1,25 @@
; RUN: llc -mtriple=amdgcn-amd-unknown -mcpu=gfx800 < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s
; RUN: llc -mtriple=amdgcn-amd-unknown -mcpu=iceland < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx800 < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=iceland < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s
; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx800 < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s
; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=iceland < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s
; RUN: llc -march=r600 < %s | FileCheck --check-prefix=R600 %s
; OSABI-UNK: .amd_amdgpu_isa "amdgcn-amd-unknown--gfx800"
; OSABI-UNK-NOT: .amd_amdgpu_hsa_metadata
; OSABI-UNK-NOT: .amd_amdgpu_pal_metadata
; OSABI-HSA: .amd_amdgpu_isa "amdgcn-amd-amdhsa--gfx800"
; OSABI-HSA: .amd_amdgpu_hsa_metadata
; OSABI-PAL: .amd_amdgpu_isa "amdgcn-amd-amdpal--gfx800"
; OSABI-PAL: .amd_amdgpu_pal_metadata
; R600-NOT: .amd_amdgpu_isa
; R600-NOT: .amd_amdgpu_hsa_metadata
; R600-NOT: .amd_amdgpu_hsa_metadata
define amdgpu_kernel void @elf_notes() {
ret void
}

View File

@ -0,0 +1,14 @@
// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s
// RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx800 %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s
// RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=iceland %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s
// OSABI-HSA: .amd_amdgpu_isa "amdgcn-amd-amdhsa--gfx800"
// OSABI-UNK-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
// OSABI-HSA-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
// OSABI-PAL-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
.amd_amdgpu_isa "amdgcn-amd-amdhsa--gfx800"

View File

@ -0,0 +1,13 @@
// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s
// RUN: llvm-mc -triple amdgcn-amd-amdpal -mcpu=gfx800 %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s
// RUN: llvm-mc -triple amdgcn-amd-amdpal -mcpu=iceland %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx803 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s
// OSABI-PAL: .amd_amdgpu_isa "amdgcn-amd-amdpal--gfx800"
// OSABI-UNK-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
// OSABI-HSA-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
// OSABI-PAL-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
.amd_amdgpu_isa "amdgcn-amd-amdpal--gfx800"

View File

@ -0,0 +1,14 @@
// RUN: llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx800 %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s
// RUN: llvm-mc -triple amdgcn-amd-unknown -mcpu=iceland %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx803 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s
// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s
// OSABI-UNK: .amd_amdgpu_isa "amdgcn-amd-unknown--gfx800"
// OSABI-UNK-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
// OSABI-HSA-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
// OSABI-PAL-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line
.amd_amdgpu_isa "amdgcn-amd-unknown--gfx800"