Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.h +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.h @@ -0,0 +1,35 @@ +//===-- AMDGPUHSATargetObjectFile.h - AMDGPU HSA Object Info ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file declares the AMDGPU-specific subclass of +/// TargetLoweringObjectFile use for targeting the HSA-runtime. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUHSATARGETOBJECTFILE_H +#define LLVM_LIB_TARGET_AMDGPU_AMDGPUHSATARGETOBJECTFILE_H + +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +class AMDGPUHSATargetObjectFile final : public TargetLoweringObjectFileELF { +public: + void Initialize(MCContext &Ctx, const TargetMachine &TM); + + MCSection *SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler &Mang, + const TargetMachine &TM) const override; +}; + +} // end namespace llvm + +#endif Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.cpp +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.cpp @@ -0,0 +1,35 @@ +//===-- AMDGPUHSATargetObjectFile.cpp - AMDGPU Object Files ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AMDGPUHSATargetObjectFile.h" +#include "Utils/AMDGPUBaseInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/Support/ELF.h" + +using namespace llvm; + +void AMDGPUHSATargetObjectFile::Initialize(MCContext &Ctx, + const TargetMachine &TM){ + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); + + TextSection = AMDGPU::getHSATextSection(Ctx); + +} + +MCSection *AMDGPUHSATargetObjectFile::SelectSectionForGlobal( + const GlobalValue *GV, SectionKind Kind, + Mangler &Mang, + const TargetMachine &TM) const { + if (Kind.isText() && !GV->hasComdat()) + return getTextSection(); + + return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang, TM); +} Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.h +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.h @@ -32,7 +32,7 @@ private: protected: - TargetLoweringObjectFile *TLOF; + std::unique_ptr TLOF; AMDGPUSubtarget Subtarget; AMDGPUIntrinsicInfo IntrinsicInfo; @@ -52,7 +52,7 @@ TargetIRAnalysis getTargetIRAnalysis() override; TargetLoweringObjectFile *getObjFileLowering() const override { - return TLOF; + return TLOF.get(); } }; Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "AMDGPUTargetMachine.h" +#include "AMDGPUHSATargetObjectFile.h" #include "AMDGPU.h" #include "AMDGPUTargetTransformInfo.h" #include "R600ISelLowering.h" @@ -43,6 +44,13 @@ RegisterTargetMachine Y(TheGCNTarget); } +static std::unique_ptr createTLOF(const Triple &TT) { + if (TT.getOS() == Triple::AMDHSA) + return make_unique(); + + return make_unique(); +} + static ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) { return new ScheduleDAGMILive(C, make_unique()); } @@ -72,15 +80,13 @@ CodeGenOpt::Level OptLevel) : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, RM, CM, OptLevel), - TLOF(new TargetLoweringObjectFileELF()), Subtarget(TT, CPU, FS, *this), + TLOF(createTLOF(getTargetTriple())), Subtarget(TT, CPU, FS, *this), IntrinsicInfo() { setRequiresStructuredCFG(true); initAsmInfo(); } -AMDGPUTargetMachine::~AMDGPUTargetMachine() { - delete TLOF; -} +AMDGPUTargetMachine::~AMDGPUTargetMachine() { } //===----------------------------------------------------------------------===// // R600 Target Machine (R600 -> Cayman) Index: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -344,6 +344,7 @@ bool ParseDirectiveHSACodeObjectISA(); bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header); bool ParseDirectiveAMDKernelCodeT(); + bool ParseSectionDirectiveHSAText(); public: AMDGPUAsmParser(MCSubtargetInfo &STI, MCAsmParser &_Parser, @@ -903,6 +904,12 @@ return false; } +bool AMDGPUAsmParser::ParseSectionDirectiveHSAText() { + getParser().getStreamer().SwitchSection( + AMDGPU::getHSATextSection(getContext())); + return false; +} + bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) { StringRef IDVal = DirectiveID.getString(); @@ -915,6 +922,9 @@ if (IDVal == ".amd_kernel_code_t") return ParseDirectiveAMDKernelCodeT(); + if (IDVal == ".hsatext" || IDVal == ".text") + return ParseSectionDirectiveHSAText(); + return true; } Index: llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt +++ llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt @@ -17,6 +17,7 @@ AMDGPUAlwaysInlinePass.cpp AMDGPUAsmPrinter.cpp AMDGPUFrameLowering.cpp + AMDGPUHSATargetObjectFile.cpp AMDGPUIntrinsicInfo.cpp AMDGPUISelDAGToDAG.cpp AMDGPUMCInstLower.cpp Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h @@ -0,0 +1,40 @@ +//===-------- AMDGPUELFStreamer.h - ELF Object Output ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a custom MCELFStreamer which allows us to insert some hooks before +// emitting data into an actual object file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUELFSTREAMER_H +#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUELFSTREAMER_H + +#include "llvm/MC/MCELFStreamer.h" + +namespace llvm { +class MCAsmBackend; +class MCCodeEmitter; +class MCContext; +class MCSubtargetInfo; + +class AMDGPUELFStreamer : public MCELFStreamer { +public: + AMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter) + : MCELFStreamer(Context, MAB, OS, Emitter) { } + + virtual void InitSections(bool NoExecStac) override; +}; + +MCELFStreamer *createAMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll); +} // namespace llvm. + +#endif Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp @@ -0,0 +1,26 @@ +//===-------- AMDGPUELFStreamer.cpp - ELF Object Output -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AMDGPUELFStreamer.h" +#include "Utils/AMDGPUBaseInfo.h" + +using namespace llvm; + +void AMDGPUELFStreamer::InitSections(bool NoExecStack) { + // Start with the .hsatext section by default. + SwitchSection(AMDGPU::getHSATextSection(getContext())); +} + +MCELFStreamer *llvm::createAMDGPUELFStreamer(MCContext &Context, + MCAsmBackend &MAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll) { + return new AMDGPUELFStreamer(Context, MAB, OS, Emitter); +} Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.h +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.h @@ -27,6 +27,7 @@ class AMDGPUMCAsmInfo : public MCAsmInfoELF { public: explicit AMDGPUMCAsmInfo(const Triple &TT); + bool shouldOmitSectionDirective(StringRef SectionName) const override; }; } // namespace llvm #endif Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp @@ -41,3 +41,8 @@ //===--- Dwarf Emission Directives -----------------------------------===// SupportsDebugInformation = true; } + +bool AMDGPUMCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const { + return SectionName == ".hsatext" || + MCAsmInfo::shouldOmitSectionDirective(SectionName); +} Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "AMDGPUMCTargetDesc.h" +#include "AMDGPUELFStreamer.h" #include "AMDGPUMCAsmInfo.h" #include "AMDGPUTargetStreamer.h" #include "InstPrinter/AMDGPUInstPrinter.h" @@ -85,6 +86,15 @@ return new AMDGPUTargetELFStreamer(S); } +static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, + MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll) { + if (T.getOS() == Triple::AMDHSA) + return createAMDGPUELFStreamer(Context, MAB, OS, Emitter, RelaxAll); + + return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll); +} + extern "C" void LLVMInitializeAMDGPUTargetMC() { for (Target *T : {&TheAMDGPUTarget, &TheGCNTarget}) { RegisterMCAsmInfo X(*T); @@ -95,6 +105,7 @@ TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo); TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter); TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend); + TargetRegistry::RegisterELFStreamer(*T, createMCStreamer); } // R600 specific registration Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp @@ -13,6 +13,7 @@ #include "AMDGPUTargetStreamer.h" #include "SIDefines.h" +#include "Utils/AMDGPUBaseInfo.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFStreamer.h" @@ -291,7 +292,10 @@ MCStreamer &OS = getStreamer(); OS.PushSection(); - OS.SwitchSection(OS.getContext().getObjectFileInfo()->getTextSection()); + // The MCObjectFileInfo that is available to the assembler is a generic + // implementation and not AMDGPUHSATargetObjectFile, so we can't use + // MCObjectFileInfo::getTextSection() here for fetching the HSATextSection. + OS.SwitchSection(AMDGPU::getHSATextSection(OS.getContext())); OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header))); OS.PopSection(); } Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt @@ -2,6 +2,7 @@ add_llvm_library(LLVMAMDGPUDesc AMDGPUAsmBackend.cpp AMDGPUELFObjectWriter.cpp + AMDGPUELFStreamer.cpp AMDGPUMCCodeEmitter.cpp AMDGPUMCTargetDesc.cpp AMDGPUMCAsmInfo.cpp Index: llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/LLVMBuild.txt =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/LLVMBuild.txt +++ llvm/trunk/lib/Target/AMDGPU/MCTargetDesc/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = AMDGPUDesc parent = AMDGPU -required_libraries = MC AMDGPUAsmPrinter AMDGPUInfo Support +required_libraries = MC AMDGPUAsmPrinter AMDGPUInfo AMDGPUUtils Support add_to_library_groups = AMDGPU Index: llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -15,6 +15,8 @@ namespace llvm { class FeatureBitset; +class MCContext; +class MCSection; namespace AMDGPU { @@ -27,6 +29,7 @@ IsaVersion getIsaVersion(const FeatureBitset &Features); void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const FeatureBitset &Features); +MCSection *getHSATextSection(MCContext &Ctx); } // end namespace AMDGPU } // end namespace llvm Index: llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// #include "AMDGPUBaseInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/SubtargetFeature.h" #define GET_SUBTARGETINFO_ENUM @@ -56,5 +58,13 @@ Header.private_segment_alignment = 4; } +MCSection *getHSATextSection(MCContext &Ctx) { + return Ctx.getELFSection(".hsatext", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE | + ELF::SHF_EXECINSTR | + ELF::SHF_AMDGPU_HSA_AGENT | + ELF::SHF_AMDGPU_HSA_CODE); +} + } // End namespace AMDGPU } // End namespace llvm Index: llvm/trunk/lib/Target/AMDGPU/Utils/LLVMBuild.txt =================================================================== --- llvm/trunk/lib/Target/AMDGPU/Utils/LLVMBuild.txt +++ llvm/trunk/lib/Target/AMDGPU/Utils/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = AMDGPUUtils parent = AMDGPU -required_libraries = Support +required_libraries = MC Support add_to_library_groups = AMDGPU Index: llvm/trunk/test/CodeGen/AMDGPU/hsa.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/hsa.ll +++ llvm/trunk/test/CodeGen/AMDGPU/hsa.ll @@ -6,6 +6,17 @@ ; The SHT_NOTE section contains the output from the .hsa_code_object_* ; directives. +; ELF: Section { +; ELF: Name: .hsatext +; ELF: Type: SHT_PROGBITS (0x1) +; ELF: Flags [ (0xC00007) +; ELF: SHF_ALLOC (0x2) +; ELF: SHF_AMDGPU_HSA_AGENT (0x800000) +; ELF: SHF_AMDGPU_HSA_CODE (0x400000) +; ELF: SHF_EXECINSTR (0x4) +; ELF: SHF_WRITE (0x1) +; ELF: } + ; ELF: SHT_NOTE ; ELF: 0000: 04000000 08000000 01000000 414D4400 ; ELF: 0010: 01000000 00000000 04000000 1B000000 @@ -17,6 +28,8 @@ ; HSA-CI: .hsa_code_object_isa 7,0,0,"AMD","AMDGPU" ; HSA-VI: .hsa_code_object_isa 8,0,1,"AMD","AMDGPU" +; HSA: .hsatext + ; HSA: {{^}}simple: ; HSA: .amd_kernel_code_t ; HSA: .end_amd_kernel_code_t Index: llvm/trunk/test/MC/AMDGPU/hsa-text.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/hsa-text.s +++ llvm/trunk/test/MC/AMDGPU/hsa-text.s @@ -0,0 +1,34 @@ +// RUN: llvm-mc -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | FileCheck %s --check-prefix=ASM +// RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | llvm-readobj -s -sd | FileCheck %s --check-prefix=ELF + +// For compatibility reasons we treat convert .text sections to .hsatext + +// ELF: Section { + +// We want to avoid emitting an empty .text section. +// ELF-NOT: Name: .text + +// ELF: Name: .hsatext +// ELF: Type: SHT_PROGBITS (0x1) +// ELF: Flags [ (0xC00007) +// ELF: SHF_ALLOC (0x2) +// ELF: SHF_AMDGPU_HSA_AGENT (0x800000) +// ELF: SHF_AMDGPU_HSA_CODE (0x400000) +// ELF: SHF_EXECINSTR (0x4) +// ELF: SHF_WRITE (0x1) +// ELF: Size: 260 +// ELF: } + +.hsa_code_object_version 1,0 +// ASM: .hsa_code_object_version 1,0 + +.hsa_code_object_isa 7,0,0,"AMD","AMDGPU" +// ASM: .hsa_code_object_isa 7,0,0,"AMD","AMDGPU" + +.text +// ASM: .hsatext + +.amd_kernel_code_t +.end_amd_kernel_code_t + +s_endpgm Index: llvm/trunk/test/MC/AMDGPU/hsa.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/hsa.s +++ llvm/trunk/test/MC/AMDGPU/hsa.s @@ -1,6 +1,17 @@ // RUN: llvm-mc -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | FileCheck %s --check-prefix=ASM // RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | llvm-readobj -s -sd | FileCheck %s --check-prefix=ELF +// ELF: Section { +// ELF: Name: .hsatext +// ELF: Type: SHT_PROGBITS (0x1) +// ELF: Flags [ (0xC00007) +// ELF: SHF_ALLOC (0x2) +// ELF: SHF_AMDGPU_HSA_AGENT (0x800000) +// ELF: SHF_AMDGPU_HSA_CODE (0x400000) +// ELF: SHF_EXECINSTR (0x4) +// ELF: SHF_WRITE (0x1) +// ELF: } + // ELF: SHT_NOTE // ELF: 0000: 04000000 08000000 01000000 414D4400 // ELF: 0010: 01000000 00000000 04000000 1B000000 @@ -14,7 +25,9 @@ .hsa_code_object_isa 7,0,0,"AMD","AMDGPU" // ASM: .hsa_code_object_isa 7,0,0,"AMD","AMDGPU" -.text +.hsatext +// ASM: .hsatext + amd_kernel_code_t_test_all: ; Test all amd_kernel_code_t members with non-default values. .amd_kernel_code_t