[llvm] 6c69427 - [SPIR-V](3/6) Add MC layer, object file support, and InstPrinter
Michal Paszkowski via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 19 16:28:09 PDT 2022
Author: Ilia Diachkov
Date: 2022-04-20T01:10:25+02:00
New Revision: 6c69427e880bf7bbcb711d24c65961f062256f2d
URL: https://github.com/llvm/llvm-project/commit/6c69427e880bf7bbcb711d24c65961f062256f2d
DIFF: https://github.com/llvm/llvm-project/commit/6c69427e880bf7bbcb711d24c65961f062256f2d.diff
LOG: [SPIR-V](3/6) Add MC layer, object file support, and InstPrinter
The patch adds SPIRV-specific MC layer implementation, SPIRV object
file support and SPIRVInstPrinter.
Differential Revision: https://reviews.llvm.org/D116462
Authors: Aleksandr Bezzubikov, Lewis Crawford, Ilia Diachkov,
Michal Paszkowski, Andrey Tretyakov, Konrad Trifunovic
Co-authored-by: Aleksandr Bezzubikov <zuban32s at gmail.com>
Co-authored-by: Ilia Diachkov <iliya.diyachkov at intel.com>
Co-authored-by: Michal Paszkowski <michal.paszkowski at outlook.com>
Co-authored-by: Andrey Tretyakov <andrey1.tretyakov at intel.com>
Co-authored-by: Konrad Trifunovic <konrad.trifunovic at intel.com>
Added:
llvm/include/llvm/MC/MCSPIRVObjectWriter.h
llvm/include/llvm/MC/MCSPIRVStreamer.h
llvm/include/llvm/MC/MCSectionSPIRV.h
llvm/lib/MC/MCSPIRVStreamer.cpp
llvm/lib/MC/SPIRVObjectWriter.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/CMakeLists.txt
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVAsmBackend.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.h
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCCodeEmitter.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.h
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVObjectTargetWriter.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.cpp
llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.h
Modified:
llvm/include/llvm/ADT/Triple.h
llvm/include/llvm/MC/MCContext.h
llvm/include/llvm/MC/MCObjectFileInfo.h
llvm/include/llvm/MC/MCSection.h
llvm/include/llvm/MC/TargetRegistry.h
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/MC/CMakeLists.txt
llvm/lib/MC/MCAsmBackend.cpp
llvm/lib/MC/MCContext.cpp
llvm/lib/MC/MCObjectFileInfo.cpp
llvm/lib/MC/MCParser/AsmParser.cpp
llvm/lib/Support/Triple.cpp
llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/lib/Target/SPIRV/CMakeLists.txt
llvm/lib/Target/SPIRV/TargetInfo/SPIRVTargetInfo.cpp
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
llvm/unittests/ADT/TripleTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h
index a42dbf853da0a..e140331b2b86f 100644
--- a/llvm/include/llvm/ADT/Triple.h
+++ b/llvm/include/llvm/ADT/Triple.h
@@ -266,6 +266,7 @@ class Triple {
ELF,
GOFF,
MachO,
+ SPIRV,
Wasm,
XCOFF,
};
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 861681551678d..b639473b2d8e7 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -52,6 +52,7 @@ class MCSectionCOFF;
class MCSectionELF;
class MCSectionGOFF;
class MCSectionMachO;
+class MCSectionSPIRV;
class MCSectionWasm;
class MCSectionXCOFF;
class MCStreamer;
@@ -81,6 +82,7 @@ class MCContext {
IsELF,
IsGOFF,
IsCOFF,
+ IsSPIRV,
IsWasm,
IsXCOFF,
IsDXContainer
@@ -129,6 +131,7 @@ class MCContext {
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
SpecificBumpPtrAllocator<MCSectionGOFF> GOFFAllocator;
+ SpecificBumpPtrAllocator<MCSectionSPIRV> SPIRVAllocator;
SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
@@ -630,6 +633,8 @@ class MCContext {
getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym,
unsigned UniqueID = GenericSectionID);
+ MCSectionSPIRV *getSPIRVSection();
+
MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K,
unsigned Flags = 0) {
return getWasmSection(Section, K, Flags, nullptr);
diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h
index 8c13bb91c63d5..a4cb21636b57b 100644
--- a/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -448,6 +448,7 @@ class MCObjectFileInfo {
void initELFMCObjectFileInfo(const Triple &T, bool Large);
void initGOFFMCObjectFileInfo(const Triple &T);
void initCOFFMCObjectFileInfo(const Triple &T);
+ void initSPIRVMCObjectFileInfo(const Triple &T);
void initWasmMCObjectFileInfo(const Triple &T);
void initXCOFFMCObjectFileInfo(const Triple &T);
MCSection *getDwarfComdatSection(const char *Name, uint64_t Hash) const;
diff --git a/llvm/include/llvm/MC/MCSPIRVObjectWriter.h b/llvm/include/llvm/MC/MCSPIRVObjectWriter.h
new file mode 100644
index 0000000000000..a8baf96b83842
--- /dev/null
+++ b/llvm/include/llvm/MC/MCSPIRVObjectWriter.h
@@ -0,0 +1,40 @@
+//===-- llvm/MC/MCSPIRVObjectWriter.h - SPIR-V Object Writer -----*- C++ *-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSPIRVOBJECTWRITER_H
+#define LLVM_MC_MCSPIRVOBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+namespace llvm {
+
+class MCSPIRVObjectTargetWriter : public MCObjectTargetWriter {
+protected:
+ explicit MCSPIRVObjectTargetWriter() {}
+
+public:
+ Triple::ObjectFormatType getFormat() const override { return Triple::SPIRV; }
+ static bool classof(const MCObjectTargetWriter *W) {
+ return W->getFormat() == Triple::SPIRV;
+ }
+};
+
+/// Construct a new SPIR-V writer instance.
+///
+/// \param MOTW - The target specific SPIR-V writer subclass.
+/// \param OS - The stream to write to.
+/// \returns The constructed object writer.
+std::unique_ptr<MCObjectWriter>
+createSPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS);
+
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/MC/MCSPIRVStreamer.h b/llvm/include/llvm/MC/MCSPIRVStreamer.h
new file mode 100644
index 0000000000000..7366e0a9d82c4
--- /dev/null
+++ b/llvm/include/llvm/MC/MCSPIRVStreamer.h
@@ -0,0 +1,50 @@
+//===- MCSPIRVStreamer.h - MCStreamer SPIR-V Object File Interface -*- C++ ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Overrides MCObjectStreamer to disable all unnecessary features with stubs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSPIRVSTREAMER_H
+#define LLVM_MC_MCSPIRVSTREAMER_H
+
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCObjectWriter.h"
+
+namespace llvm {
+class MCAssembler;
+class MCExpr;
+class MCInst;
+class raw_ostream;
+
+class MCSPIRVStreamer : public MCObjectStreamer {
+public:
+ MCSPIRVStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MCObjectStreamer(Context, std::move(TAB), std::move(OW),
+ std::move(Emitter)) {}
+
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
+ return false;
+ }
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) override {}
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ uint64_t Size = 0, unsigned ByteAlignment = 0,
+ SMLoc Loc = SMLoc()) override {}
+
+private:
+ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index ab038ab617bd9..46ccd9f85d9e0 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -46,7 +46,8 @@ class MCSection {
SV_GOFF,
SV_MachO,
SV_Wasm,
- SV_XCOFF
+ SV_XCOFF,
+ SV_SPIRV,
};
/// Express the state of bundle locked groups while emitting code.
diff --git a/llvm/include/llvm/MC/MCSectionSPIRV.h b/llvm/include/llvm/MC/MCSectionSPIRV.h
new file mode 100644
index 0000000000000..6534599d2091c
--- /dev/null
+++ b/llvm/include/llvm/MC/MCSectionSPIRV.h
@@ -0,0 +1,41 @@
+//===- MCSectionSPIRV.h - SPIR-V Machine Code Sections ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionSPIRV class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONSPIRV_H
+#define LLVM_MC_MCSECTIONSPIRV_H
+
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/SectionKind.h"
+
+namespace llvm {
+
+class MCSymbol;
+
+class MCSectionSPIRV final : public MCSection {
+ friend class MCContext;
+
+ MCSectionSPIRV(SectionKind K, MCSymbol *Begin)
+ : MCSection(SV_SPIRV, "", K, Begin) {}
+ // TODO: Add StringRef Name to MCSectionSPIRV.
+
+public:
+ ~MCSectionSPIRV() = default;
+ void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const override {}
+ bool useCodeAlign() const override { return false; }
+ bool isVirtualSection() const override { return false; }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_MC_MCSECTIONSPIRV_H
diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h
index e2d90b9169e0b..0b1a0fec667ff 100644
--- a/llvm/include/llvm/MC/TargetRegistry.h
+++ b/llvm/include/llvm/MC/TargetRegistry.h
@@ -109,6 +109,11 @@ MCStreamer *createXCOFFStreamer(MCContext &Ctx,
std::unique_ptr<MCObjectWriter> &&OW,
std::unique_ptr<MCCodeEmitter> &&CE,
bool RelaxAll);
+MCStreamer *createSPIRVStreamer(MCContext &Ctx,
+ std::unique_ptr<MCAsmBackend> &&TAB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&CE,
+ bool RelaxAll);
MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
@@ -201,6 +206,11 @@ class Target {
std::unique_ptr<MCAsmBackend> &&TAB,
std::unique_ptr<MCObjectWriter> &&OW,
std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
+ using SPIRVStreamerCtorTy =
+ MCStreamer *(*)(const Triple &T, MCContext &Ctx,
+ std::unique_ptr<MCAsmBackend> &&TAB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll);
using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S);
using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)(
@@ -302,6 +312,7 @@ class Target {
ELFStreamerCtorTy ELFStreamerCtorFn = nullptr;
WasmStreamerCtorTy WasmStreamerCtorFn = nullptr;
XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr;
+ SPIRVStreamerCtorTy SPIRVStreamerCtorFn = nullptr;
/// Construction function for this target's null TargetStreamer, if
/// registered (default = nullptr).
@@ -574,6 +585,14 @@ class Target {
S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW),
std::move(Emitter), RelaxAll);
break;
+ case Triple::SPIRV:
+ if (SPIRVStreamerCtorFn)
+ S = SPIRVStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW),
+ std::move(Emitter), RelaxAll);
+ else
+ S = createSPIRVStreamer(Ctx, std::move(TAB), std::move(OW),
+ std::move(Emitter), RelaxAll);
+ break;
}
if (ObjectTargetStreamerCtorFn)
ObjectTargetStreamerCtorFn(*S, STI);
@@ -954,6 +973,10 @@ struct TargetRegistry {
T.ELFStreamerCtorFn = Fn;
}
+ static void RegisterSPIRVStreamer(Target &T, Target::SPIRVStreamerCtorTy Fn) {
+ T.SPIRVStreamerCtorFn = Fn;
+ }
+
static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) {
T.WasmStreamerCtorFn = Fn;
}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 84f60f47ee53b..8131c1cfb6f86 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -4890,6 +4890,9 @@ static const char *getSectionNameForBitcode(const Triple &T) {
case Triple::GOFF:
llvm_unreachable("GOFF is not yet implemented");
break;
+ case Triple::SPIRV:
+ llvm_unreachable("SPIRV is not yet implemented");
+ break;
case Triple::XCOFF:
llvm_unreachable("XCOFF is not yet implemented");
break;
@@ -4912,6 +4915,9 @@ static const char *getSectionNameForCommandline(const Triple &T) {
case Triple::GOFF:
llvm_unreachable("GOFF is not yet implemented");
break;
+ case Triple::SPIRV:
+ llvm_unreachable("SPIRV is not yet implemented");
+ break;
case Triple::XCOFF:
llvm_unreachable("XCOFF is not yet implemented");
break;
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index ca376b340e160..bb245172fdc9a 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -43,6 +43,7 @@ add_llvm_component_library(LLVMMC
MCSectionWasm.cpp
MCSectionXCOFF.cpp
MCStreamer.cpp
+ MCSPIRVStreamer.cpp
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
@@ -58,6 +59,7 @@ add_llvm_component_library(LLVMMC
MCXCOFFObjectTargetWriter.cpp
MCXCOFFStreamer.cpp
MachObjectWriter.cpp
+ SPIRVObjectWriter.cpp
StringTableBuilder.cpp
SubtargetFeature.cpp
TargetRegistry.cpp
diff --git a/llvm/lib/MC/MCAsmBackend.cpp b/llvm/lib/MC/MCAsmBackend.cpp
index 7e2516758a05d..df07f06205401 100644
--- a/llvm/lib/MC/MCAsmBackend.cpp
+++ b/llvm/lib/MC/MCAsmBackend.cpp
@@ -13,6 +13,7 @@
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSPIRVObjectWriter.h"
#include "llvm/MC/MCWasmObjectWriter.h"
#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/MC/MCXCOFFObjectWriter.h"
@@ -39,6 +40,9 @@ MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
case Triple::COFF:
return createWinCOFFObjectWriter(
cast<MCWinCOFFObjectTargetWriter>(std::move(TW)), OS);
+ case Triple::SPIRV:
+ return createSPIRVObjectWriter(
+ cast<MCSPIRVObjectTargetWriter>(std::move(TW)), OS);
case Triple::Wasm:
return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)),
OS);
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 1ebd80d86f3fc..827fe691fc44f 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -29,6 +29,7 @@
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionSPIRV.h"
#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCStreamer.h"
@@ -110,6 +111,9 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
case Triple::DXContainer:
Env = IsDXContainer;
break;
+ case Triple::SPIRV:
+ Env = IsSPIRV;
+ break;
case Triple::UnknownObjectFormat:
report_fatal_error("Cannot initialize MC for unknown object file format.");
break;
@@ -147,6 +151,7 @@ void MCContext::reset() {
WasmAllocator.DestroyAll();
XCOFFAllocator.DestroyAll();
MCInstAllocator.DestroyAll();
+ SPIRVAllocator.DestroyAll();
MCSubtargetAllocator.DestroyAll();
InlineAsmUsedLabelNames.clear();
@@ -253,6 +258,9 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
return createXCOFFSymbolImpl(Name, IsTemporary);
case MCContext::IsDXContainer:
break;
+ case MCContext::IsSPIRV:
+ return new (Name, *this)
+ MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
}
return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
IsTemporary);
@@ -812,6 +820,21 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
return Result;
}
+MCSectionSPIRV *MCContext::getSPIRVSection() {
+ MCSymbol *Begin = nullptr;
+ MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate())
+ MCSectionSPIRV(SectionKind::getText(), Begin);
+
+ auto *F = new MCDataFragment();
+ Result->getFragmentList().insert(Result->begin(), F);
+ F->setParent(Result);
+
+ if (Begin)
+ Begin->setFragment(F);
+
+ return Result;
+}
+
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 3da477d90887a..5bd3fcceadb94 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -19,6 +19,7 @@
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionSPIRV.h"
#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/Support/Casting.h"
@@ -804,6 +805,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
SectionKind::getReadOnly());
}
+void MCObjectFileInfo::initSPIRVMCObjectFileInfo(const Triple &T) {
+ // Put everything in a single binary section.
+ TextSection = Ctx->getSPIRVSection();
+}
+
void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
TextSection = Ctx->getWasmSection(".text", SectionKind::getText());
DataSection = Ctx->getWasmSection(".data", SectionKind::getData());
@@ -1032,6 +1038,9 @@ void MCObjectFileInfo::initMCObjectFileInfo(MCContext &MCCtx, bool PIC,
case MCContext::IsGOFF:
initGOFFMCObjectFileInfo(TheTriple);
break;
+ case MCContext::IsSPIRV:
+ initSPIRVMCObjectFileInfo(TheTriple);
+ break;
case MCContext::IsWasm:
initWasmMCObjectFileInfo(TheTriple);
break;
@@ -1055,6 +1064,7 @@ MCSection *MCObjectFileInfo::getDwarfComdatSection(const char *Name,
case Triple::MachO:
case Triple::COFF:
case Triple::GOFF:
+ case Triple::SPIRV:
case Triple::XCOFF:
case Triple::DXContainer:
case Triple::UnknownObjectFormat:
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index defc86e06aa60..8869faef30dfe 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -792,6 +792,10 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
case MCContext::IsGOFF:
PlatformParser.reset(createGOFFAsmParser());
break;
+ case MCContext::IsSPIRV:
+ report_fatal_error(
+ "Need to implement createSPIRVAsmParser for SPIRV format.");
+ break;
case MCContext::IsWasm:
PlatformParser.reset(createWasmAsmParser());
break;
diff --git a/llvm/lib/MC/MCSPIRVStreamer.cpp b/llvm/lib/MC/MCSPIRVStreamer.cpp
new file mode 100644
index 0000000000000..863db7f36f29e
--- /dev/null
+++ b/llvm/lib/MC/MCSPIRVStreamer.cpp
@@ -0,0 +1,45 @@
+//===- lib/MC/MCSPIRVStreamer.cpp - SPIR-V Object Output ------*- C++ -*---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file assembles .s files and emits SPIR-V .o object files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSPIRVStreamer.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/TargetRegistry.h"
+
+using namespace llvm;
+
+void MCSPIRVStreamer::emitInstToData(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ MCAssembler &Assembler = getAssembler();
+ SmallVector<MCFixup, 0> Fixups;
+ SmallString<256> Code;
+ raw_svector_ostream VecOS(Code);
+ Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
+
+ // Append the encoded instruction to the current data fragment (or create a
+ // new such fragment if the current fragment is not a data fragment).
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ DF->setHasInstructions(STI);
+ DF->getContents().append(Code.begin(), Code.end());
+}
+
+MCStreamer *llvm::createSPIRVStreamer(MCContext &Context,
+ std::unique_ptr<MCAsmBackend> &&MAB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&CE,
+ bool RelaxAll) {
+ MCSPIRVStreamer *S = new MCSPIRVStreamer(Context, std::move(MAB),
+ std::move(OW), std::move(CE));
+ if (RelaxAll)
+ S->getAssembler().setRelaxAll(true);
+ return S;
+}
diff --git a/llvm/lib/MC/SPIRVObjectWriter.cpp b/llvm/lib/MC/SPIRVObjectWriter.cpp
new file mode 100644
index 0000000000000..4a07740e8d143
--- /dev/null
+++ b/llvm/lib/MC/SPIRVObjectWriter.cpp
@@ -0,0 +1,76 @@
+//===- llvm/MC/MCSPIRVObjectWriter.cpp - SPIR-V Object Writer ----*- C++ *-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCSPIRVObjectWriter.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/EndianStream.h"
+
+using namespace llvm;
+
+class SPIRVObjectWriter : public MCObjectWriter {
+ ::support::endian::Writer W;
+
+ /// The target specific SPIR-V writer instance.
+ std::unique_ptr<MCSPIRVObjectTargetWriter> TargetObjectWriter;
+
+public:
+ SPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS)
+ : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {}
+
+ ~SPIRVObjectWriter() override {}
+
+private:
+ void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue) override {}
+
+ void executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override {}
+
+ uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+ void writeHeader(const MCAssembler &Asm);
+};
+
+void SPIRVObjectWriter::writeHeader(const MCAssembler &Asm) {
+ constexpr uint32_t MagicNumber = 0x07230203;
+
+ // TODO: set the version on a min-necessary basis (just like the translator
+ // does) requires some refactoring of MCAssembler::VersionInfoType.
+ constexpr uint32_t Major = 1;
+ constexpr uint32_t Minor = 0;
+ constexpr uint32_t VersionNumber = 0 | (Major << 16) | (Minor << 8);
+ // TODO: check if we could use anything other than 0 (spec allows).
+ constexpr uint32_t GeneratorMagicNumber = 0;
+ // TODO: do not hardcode this as well.
+ constexpr uint32_t Bound = 900;
+ constexpr uint32_t Schema = 0;
+
+ W.write<uint32_t>(MagicNumber);
+ W.write<uint32_t>(VersionNumber);
+ W.write<uint32_t>(GeneratorMagicNumber);
+ W.write<uint32_t>(Bound);
+ W.write<uint32_t>(Schema);
+}
+
+uint64_t SPIRVObjectWriter::writeObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ uint64_t StartOffset = W.OS.tell();
+ writeHeader(Asm);
+ for (const MCSection &S : Asm)
+ Asm.writeSectionData(W.OS, &S, Layout);
+ return W.OS.tell() - StartOffset;
+}
+
+std::unique_ptr<MCObjectWriter>
+llvm::createSPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW,
+ raw_pwrite_stream &OS) {
+ return std::make_unique<SPIRVObjectWriter>(std::move(MOTW), OS);
+}
diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp
index d70a4210cbff2..4aacad40c05e8 100644
--- a/llvm/lib/Support/Triple.cpp
+++ b/llvm/lib/Support/Triple.cpp
@@ -631,15 +631,16 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
- // "xcoff" must come before "coff" because of the order-dependendent
- // pattern matching.
- .EndsWith("xcoff", Triple::XCOFF)
- .EndsWith("coff", Triple::COFF)
- .EndsWith("elf", Triple::ELF)
- .EndsWith("goff", Triple::GOFF)
- .EndsWith("macho", Triple::MachO)
- .EndsWith("wasm", Triple::Wasm)
- .Default(Triple::UnknownObjectFormat);
+ // "xcoff" must come before "coff" because of the order-dependendent
+ // pattern matching.
+ .EndsWith("xcoff", Triple::XCOFF)
+ .EndsWith("coff", Triple::COFF)
+ .EndsWith("elf", Triple::ELF)
+ .EndsWith("goff", Triple::GOFF)
+ .EndsWith("macho", Triple::MachO)
+ .EndsWith("wasm", Triple::Wasm)
+ .EndsWith("spirv", Triple::SPIRV)
+ .Default(Triple::UnknownObjectFormat);
}
static Triple::SubArchType parseSubArch(StringRef SubArchName) {
@@ -740,14 +741,24 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
switch (Kind) {
- case Triple::UnknownObjectFormat: return "";
- case Triple::COFF: return "coff";
- case Triple::ELF: return "elf";
- case Triple::GOFF: return "goff";
- case Triple::MachO: return "macho";
- case Triple::Wasm: return "wasm";
- case Triple::XCOFF: return "xcoff";
- case Triple::DXContainer: return "dxcontainer";
+ case Triple::UnknownObjectFormat:
+ return "";
+ case Triple::COFF:
+ return "coff";
+ case Triple::ELF:
+ return "elf";
+ case Triple::GOFF:
+ return "goff";
+ case Triple::MachO:
+ return "macho";
+ case Triple::Wasm:
+ return "wasm";
+ case Triple::XCOFF:
+ return "xcoff";
+ case Triple::DXContainer:
+ return "dxcontainer";
+ case Triple::SPIRV:
+ return "spirv";
}
llvm_unreachable("unknown object format type");
}
@@ -831,8 +842,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::spirv32:
case Triple::spirv64:
- // TODO: In future this will be Triple::SPIRV.
- return Triple::UnknownObjectFormat;
+ return Triple::SPIRV;
case Triple::dxil:
return Triple::DXContainer;
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index fdac90c0680a3..01c8d402c0d7c 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -6377,6 +6377,7 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
CurrentFormat = WASM;
break;
case MCContext::IsGOFF:
+ case MCContext::IsSPIRV:
case MCContext::IsXCOFF:
case MCContext::IsDXContainer:
llvm_unreachable("unexpected object format");
diff --git a/llvm/lib/Target/SPIRV/CMakeLists.txt b/llvm/lib/Target/SPIRV/CMakeLists.txt
index a0b3fe50df134..a6bef10bd4743 100644
--- a/llvm/lib/Target/SPIRV/CMakeLists.txt
+++ b/llvm/lib/Target/SPIRV/CMakeLists.txt
@@ -18,6 +18,8 @@ add_llvm_target(SPIRVCodeGen
LINK_COMPONENTS
CodeGen
Core
+ MC
+ SPIRVDesc
SPIRVInfo
Support
Target
@@ -26,4 +28,5 @@ add_llvm_target(SPIRVCodeGen
SPIRV
)
+add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/SPIRV/MCTargetDesc/CMakeLists.txt
new file mode 100644
index 0000000000000..fb56ffdd376b3
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_llvm_component_library(LLVMSPIRVDesc
+ SPIRVMCAsmInfo.cpp
+ SPIRVMCTargetDesc.cpp
+ SPIRVTargetStreamer.cpp
+ SPIRVAsmBackend.cpp
+ SPIRVMCCodeEmitter.cpp
+ SPIRVObjectTargetWriter.cpp
+ SPIRVInstPrinter.cpp
+
+ LINK_COMPONENTS
+ MC
+ SPIRVInfo
+ Support
+
+ ADD_TO_COMPONENT
+ SPIRV
+ )
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVAsmBackend.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVAsmBackend.cpp
new file mode 100644
index 0000000000000..4156a00264115
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVAsmBackend.cpp
@@ -0,0 +1,63 @@
+//===-- SPIRVAsmBackend.cpp - SPIR-V Assembler Backend ---------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/SPIRVMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Support/EndianStream.h"
+
+using namespace llvm;
+
+namespace {
+
+class SPIRVAsmBackend : public MCAsmBackend {
+public:
+ SPIRVAsmBackend(support::endianness Endian) : MCAsmBackend(Endian) {}
+
+ void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
+ uint64_t Value, bool IsResolved,
+ const MCSubtargetInfo *STI) const override {}
+
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ return createSPIRVObjectTargetWriter();
+ }
+
+ // No instruction requires relaxation.
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const override {
+ return false;
+ }
+
+ unsigned getNumFixupKinds() const override { return 1; }
+
+ bool mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const override {
+ return false;
+ }
+
+ void relaxInstruction(MCInst &Inst,
+ const MCSubtargetInfo &STI) const override {}
+
+ bool writeNopData(raw_ostream &OS, uint64_t Count,
+ const MCSubtargetInfo *STI) const override {
+ return false;
+ }
+};
+
+} // end anonymous namespace
+
+MCAsmBackend *llvm::createSPIRVAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &) {
+ return new SPIRVAsmBackend(support::little);
+}
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
new file mode 100644
index 0000000000000..dd3a5f0e82d50
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
@@ -0,0 +1,157 @@
+//===-- SPIRVInstPrinter.cpp - Output SPIR-V MCInsts as ASM -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class prints a SPIR-V MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVInstPrinter.h"
+#include "llvm/CodeGen/Register.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "asm-printer"
+
+// Include the auto-generated portion of the assembly writer.
+#include "SPIRVGenAsmWriter.inc"
+
+void SPIRVInstPrinter::printRemainingVariableOps(const MCInst *MI,
+ unsigned StartIndex,
+ raw_ostream &O,
+ bool SkipFirstSpace,
+ bool SkipImmediates) {
+ const unsigned NumOps = MI->getNumOperands();
+ for (unsigned i = StartIndex; i < NumOps; ++i) {
+ if (!SkipImmediates || !MI->getOperand(i).isImm()) {
+ if (!SkipFirstSpace || i != StartIndex)
+ O << ' ';
+ printOperand(MI, i, O);
+ }
+ }
+}
+
+void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
+ unsigned StartIndex,
+ raw_ostream &O) {
+ O << ' ';
+ if (MI->getNumOperands() - StartIndex == 2) { // Handle 64 bit literals.
+ uint64_t Imm = MI->getOperand(StartIndex).getImm();
+ Imm |= (MI->getOperand(StartIndex + 1).getImm() << 32);
+ O << Imm;
+ } else {
+ printRemainingVariableOps(MI, StartIndex, O, true, false);
+ }
+}
+
+void SPIRVInstPrinter::recordOpExtInstImport(const MCInst *MI) {
+ llvm_unreachable("Unimplemented recordOpExtInstImport");
+}
+
+void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address,
+ StringRef Annot, const MCSubtargetInfo &STI,
+ raw_ostream &OS) {
+ printInstruction(MI, Address, OS);
+ printAnnotation(OS, Annot);
+}
+
+void SPIRVInstPrinter::printOpExtInst(const MCInst *MI, raw_ostream &O) {
+ llvm_unreachable("Unimplemented printOpExtInst");
+}
+
+void SPIRVInstPrinter::printOpDecorate(const MCInst *MI, raw_ostream &O) {
+ llvm_unreachable("Unimplemented printOpDecorate");
+}
+
+static void printExpr(const MCExpr *Expr, raw_ostream &O) {
+#ifndef NDEBUG
+ const MCSymbolRefExpr *SRE;
+
+ if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
+ SRE = cast<MCSymbolRefExpr>(BE->getLHS());
+ else
+ SRE = cast<MCSymbolRefExpr>(Expr);
+
+ MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
+
+ assert(Kind == MCSymbolRefExpr::VK_None);
+#endif
+ O << *Expr;
+}
+
+void SPIRVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O, const char *Modifier) {
+ assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
+ if (OpNo < MI->getNumOperands()) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+ if (Op.isReg())
+ O << '%' << (Register::virtReg2Index(Op.getReg()) + 1);
+ else if (Op.isImm())
+ O << formatImm((int64_t)Op.getImm());
+ else if (Op.isDFPImm())
+ O << formatImm((double)Op.getDFPImm());
+ else if (Op.isExpr())
+ printExpr(Op.getExpr(), O);
+ else
+ llvm_unreachable("Unexpected operand type");
+ }
+}
+
+void SPIRVInstPrinter::printStringImm(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ llvm_unreachable("Unimplemented printStringImm");
+}
+
+void SPIRVInstPrinter::printExtInst(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ llvm_unreachable("Unimplemented printExtInst");
+}
+
+// Methods for printing textual names of SPIR-V enums.
+#define GEN_INSTR_PRINTER_IMPL(EnumName) \
+ void SPIRVInstPrinter::print##EnumName(const MCInst *MI, unsigned OpNo, \
+ raw_ostream &O) { \
+ llvm_unreachable("Unimplemented print" #EnumName); \
+ }
+GEN_INSTR_PRINTER_IMPL(Capability)
+GEN_INSTR_PRINTER_IMPL(SourceLanguage)
+GEN_INSTR_PRINTER_IMPL(ExecutionModel)
+GEN_INSTR_PRINTER_IMPL(AddressingModel)
+GEN_INSTR_PRINTER_IMPL(MemoryModel)
+GEN_INSTR_PRINTER_IMPL(ExecutionMode)
+GEN_INSTR_PRINTER_IMPL(StorageClass)
+GEN_INSTR_PRINTER_IMPL(Dim)
+GEN_INSTR_PRINTER_IMPL(SamplerAddressingMode)
+GEN_INSTR_PRINTER_IMPL(SamplerFilterMode)
+GEN_INSTR_PRINTER_IMPL(ImageFormat)
+GEN_INSTR_PRINTER_IMPL(ImageChannelOrder)
+GEN_INSTR_PRINTER_IMPL(ImageChannelDataType)
+GEN_INSTR_PRINTER_IMPL(ImageOperand)
+GEN_INSTR_PRINTER_IMPL(FPFastMathMode)
+GEN_INSTR_PRINTER_IMPL(FPRoundingMode)
+GEN_INSTR_PRINTER_IMPL(LinkageType)
+GEN_INSTR_PRINTER_IMPL(AccessQualifier)
+GEN_INSTR_PRINTER_IMPL(FunctionParameterAttribute)
+GEN_INSTR_PRINTER_IMPL(Decoration)
+GEN_INSTR_PRINTER_IMPL(BuiltIn)
+GEN_INSTR_PRINTER_IMPL(SelectionControl)
+GEN_INSTR_PRINTER_IMPL(LoopControl)
+GEN_INSTR_PRINTER_IMPL(FunctionControl)
+GEN_INSTR_PRINTER_IMPL(MemorySemantics)
+GEN_INSTR_PRINTER_IMPL(MemoryOperand)
+GEN_INSTR_PRINTER_IMPL(Scope)
+GEN_INSTR_PRINTER_IMPL(GroupOperation)
+GEN_INSTR_PRINTER_IMPL(KernelEnqueueFlags)
+GEN_INSTR_PRINTER_IMPL(KernelProfilingInfo)
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
new file mode 100644
index 0000000000000..cd3b6f1e6d665
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
@@ -0,0 +1,94 @@
+//===-- SPIRVInstPrinter.h - Output SPIR-V MCInsts as ASM -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class prints a SPIR-V MCInst to a .s file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPIRV_INSTPRINTER_SPIRVINSTPRINTER_H
+#define LLVM_LIB_TARGET_SPIRV_INSTPRINTER_SPIRVINSTPRINTER_H
+
+#include "llvm/MC/MCInstPrinter.h"
+
+namespace llvm {
+class SPIRVInstPrinter : public MCInstPrinter {
+private:
+ void recordOpExtInstImport(const MCInst *MI);
+
+public:
+ using MCInstPrinter::MCInstPrinter;
+
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &OS) override;
+ void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
+ const char *Modifier = nullptr);
+
+ void printStringImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printOpDecorate(const MCInst *MI, raw_ostream &O);
+ void printOpExtInst(const MCInst *MI, raw_ostream &O);
+ void printRemainingVariableOps(const MCInst *MI, unsigned StartIndex,
+ raw_ostream &O, bool SkipFirstSpace = false,
+ bool SkipImmediates = false);
+ void printOpConstantVarOps(const MCInst *MI, unsigned StartIndex,
+ raw_ostream &O);
+
+ void printExtInst(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ // SPIR-V enumerations printing.
+ void printCapability(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printSourceLanguage(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printExecutionModel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printAddressingModel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printMemoryModel(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printExecutionMode(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printStorageClass(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printDim(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printSamplerAddressingMode(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O);
+ void printSamplerFilterMode(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printImageFormat(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printImageChannelOrder(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printImageChannelDataType(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O);
+ void printImageOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printFPFastMathMode(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printFPRoundingMode(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printLinkageType(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printAccessQualifier(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printFunctionParameterAttribute(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O);
+
+ void printDecoration(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printBuiltIn(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printSelectionControl(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printLoopControl(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printFunctionControl(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printMemorySemantics(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printMemoryOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printScope(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printGroupOperation(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+
+ void printKernelEnqueueFlags(const MCInst *MI, unsigned OpNo, raw_ostream &O);
+ void printKernelProfilingInfo(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O);
+ // Autogenerated by tblgen.
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
+ static const char *getRegisterName(unsigned RegNo);
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_SPIRV_INSTPRINTER_SPIRVINSTPRINTER_H
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.cpp
new file mode 100644
index 0000000000000..2f3462f419e5a
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.cpp
@@ -0,0 +1,34 @@
+//===-- SPIRVMCAsmInfo.h - SPIR-V asm properties --------------*- C++ -*--====//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations of the SPIRVMCAsmInfo properties.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVMCAsmInfo.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace llvm;
+
+SPIRVMCAsmInfo::SPIRVMCAsmInfo(const Triple &TT,
+ const MCTargetOptions &Options) {
+ IsLittleEndian = true;
+
+ HasSingleParameterDotFile = false;
+ HasDotTypeDotSizeDirective = false;
+
+ MinInstAlignment = 4;
+
+ CodePointerSize = 4;
+ CommentString = ";";
+ HasFunctionAlignment = false;
+}
+
+bool SPIRVMCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {
+ return true;
+}
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.h
new file mode 100644
index 0000000000000..08e579e1c32c8
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCAsmInfo.h
@@ -0,0 +1,29 @@
+//===-- SPIRVMCAsmInfo.h - SPIR-V asm properties --------------*- C++ -*--====//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the SPIRVMCAsmInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVMCASMINFO_H
+#define LLVM_LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVMCASMINFO_H
+
+#include "llvm/MC/MCAsmInfo.h"
+
+namespace llvm {
+
+class Triple;
+
+class SPIRVMCAsmInfo : public MCAsmInfo {
+public:
+ explicit SPIRVMCAsmInfo(const Triple &TT, const MCTargetOptions &Options);
+ bool shouldOmitSectionDirective(StringRef SectionName) const override;
+};
+} // namespace llvm
+
+#endif // LLVM_LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVMCASMINFO_H
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCCodeEmitter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCCodeEmitter.cpp
new file mode 100644
index 0000000000000..d953bc590473f
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCCodeEmitter.cpp
@@ -0,0 +1,132 @@
+//===-- SPIRVMCCodeEmitter.cpp - Emit SPIR-V machine code -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SPIRVMCCodeEmitter class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/SPIRVMCTargetDesc.h"
+#include "llvm/CodeGen/Register.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/EndianStream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "spirv-mccodeemitter"
+
+namespace {
+
+class SPIRVMCCodeEmitter : public MCCodeEmitter {
+ const MCInstrInfo &MCII;
+
+public:
+ SPIRVMCCodeEmitter(const MCInstrInfo &mcii) : MCII(mcii) {}
+ SPIRVMCCodeEmitter(const SPIRVMCCodeEmitter &) = delete;
+ void operator=(const SPIRVMCCodeEmitter &) = delete;
+ ~SPIRVMCCodeEmitter() override = default;
+
+ // getBinaryCodeForInstr - TableGen'erated function for getting the
+ // binary encoding for an instruction.
+ uint64_t getBinaryCodeForInstr(const MCInst &MI,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
+ void encodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const override;
+
+private:
+ FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
+ void
+ verifyInstructionPredicates(const MCInst &MI,
+ const FeatureBitset &AvailableFeatures) const;
+};
+
+} // end anonymous namespace
+
+MCCodeEmitter *llvm::createSPIRVMCCodeEmitter(const MCInstrInfo &MCII,
+ MCContext &Ctx) {
+ return new SPIRVMCCodeEmitter(MCII);
+}
+
+using EndianWriter = support::endian::Writer;
+
+// Check if the instruction has a type argument for operand 1, and defines an ID
+// output register in operand 0. If so, we need to swap operands 0 and 1 so the
+// type comes first in the output, despide coming second in the MCInst.
+static bool hasType(const MCInst &MI, const MCInstrInfo &MII) {
+ MCInstrDesc MCDesc = MII.get(MI.getOpcode());
+ // If we define an output, and have at least one other argument.
+ if (MCDesc.getNumDefs() == 1 && MCDesc.getNumOperands() >= 2) {
+ // Check if we define an ID, and take a type as operand 1.
+ auto DefOpInfo = MCDesc.opInfo_begin();
+ auto FirstArgOpInfo = MCDesc.opInfo_begin() + 1;
+ return (DefOpInfo->RegClass == SPIRV::IDRegClassID ||
+ DefOpInfo->RegClass == SPIRV::ANYIDRegClassID) &&
+ FirstArgOpInfo->RegClass == SPIRV::TYPERegClassID;
+ }
+ return false;
+}
+
+static void emitOperand(const MCOperand &Op, EndianWriter &OSE) {
+ if (Op.isReg()) {
+ // Emit the id index starting at 1 (0 is an invalid index).
+ OSE.write<uint32_t>(Register::virtReg2Index(Op.getReg()) + 1);
+ } else if (Op.isImm()) {
+ OSE.write<uint32_t>(Op.getImm());
+ } else {
+ llvm_unreachable("Unexpected operand type in VReg");
+ }
+}
+
+// Emit the type in operand 1 before the ID in operand 0 it defines, and all
+// remaining operands in the order they come naturally.
+static void emitTypedInstrOperands(const MCInst &MI, EndianWriter &OSE) {
+ unsigned NumOps = MI.getNumOperands();
+ emitOperand(MI.getOperand(1), OSE);
+ emitOperand(MI.getOperand(0), OSE);
+ for (unsigned i = 2; i < NumOps; ++i)
+ emitOperand(MI.getOperand(i), OSE);
+}
+
+// Emit operands in the order they come naturally.
+static void emitUntypedInstrOperands(const MCInst &MI, EndianWriter &OSE) {
+ for (const auto &Op : MI)
+ emitOperand(Op, OSE);
+}
+
+void SPIRVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ auto Features = computeAvailableFeatures(STI.getFeatureBits());
+ verifyInstructionPredicates(MI, Features);
+
+ EndianWriter OSE(OS, support::little);
+
+ // Encode the first 32 SPIR-V bytes with the number of args and the opcode.
+ const uint64_t OpCode = getBinaryCodeForInstr(MI, Fixups, STI);
+ const uint32_t NumWords = MI.getNumOperands() + 1;
+ const uint32_t FirstWord = (NumWords << 16) | OpCode;
+ OSE.write<uint32_t>(FirstWord);
+
+ // Emit the instruction arguments (emitting the output type first if present).
+ if (hasType(MI, MCII))
+ emitTypedInstrOperands(MI, OSE);
+ else
+ emitUntypedInstrOperands(MI, OSE);
+}
+
+#define ENABLE_INSTR_PREDICATE_VERIFIER
+#include "SPIRVGenMCCodeEmitter.inc"
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.cpp
new file mode 100644
index 0000000000000..6b8b4a73af928
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.cpp
@@ -0,0 +1,102 @@
+//===-- SPIRVMCTargetDesc.cpp - SPIR-V Target Descriptions ----*- C++ -*---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides SPIR-V specific target descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVMCTargetDesc.h"
+#include "SPIRVInstPrinter.h"
+#include "SPIRVMCAsmInfo.h"
+#include "SPIRVTargetStreamer.h"
+#include "TargetInfo/SPIRVTargetInfo.h"
+#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/TargetRegistry.h"
+
+#define GET_INSTRINFO_MC_DESC
+#include "SPIRVGenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_MC_DESC
+#include "SPIRVGenSubtargetInfo.inc"
+
+#define GET_REGINFO_MC_DESC
+#include "SPIRVGenRegisterInfo.inc"
+
+using namespace llvm;
+
+static MCInstrInfo *createSPIRVMCInstrInfo() {
+ MCInstrInfo *X = new MCInstrInfo();
+ InitSPIRVMCInstrInfo(X);
+ return X;
+}
+
+static MCRegisterInfo *createSPIRVMCRegisterInfo(const Triple &TT) {
+ MCRegisterInfo *X = new MCRegisterInfo();
+ return X;
+}
+
+static MCSubtargetInfo *
+createSPIRVMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
+ return createSPIRVMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+}
+
+static MCStreamer *
+createSPIRVMCStreamer(const Triple &T, MCContext &Ctx,
+ std::unique_ptr<MCAsmBackend> &&MAB,
+ std::unique_ptr<MCObjectWriter> &&OW,
+ std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll) {
+ return createSPIRVStreamer(Ctx, std::move(MAB), std::move(OW),
+ std::move(Emitter), RelaxAll);
+}
+
+static MCTargetStreamer *createTargetAsmStreamer(MCStreamer &S,
+ formatted_raw_ostream &,
+ MCInstPrinter *, bool) {
+ return new SPIRVTargetStreamer(S);
+}
+
+static MCInstPrinter *createSPIRVMCInstPrinter(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) {
+ assert(SyntaxVariant == 0);
+ return new SPIRVInstPrinter(MAI, MII, MRI);
+}
+
+namespace {
+
+class SPIRVMCInstrAnalysis : public MCInstrAnalysis {
+public:
+ explicit SPIRVMCInstrAnalysis(const MCInstrInfo *Info)
+ : MCInstrAnalysis(Info) {}
+};
+
+} // end anonymous namespace
+
+static MCInstrAnalysis *createSPIRVInstrAnalysis(const MCInstrInfo *Info) {
+ return new SPIRVMCInstrAnalysis(Info);
+}
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTargetMC() {
+ for (Target *T : {&getTheSPIRV32Target(), &getTheSPIRV64Target()}) {
+ RegisterMCAsmInfo<SPIRVMCAsmInfo> X(*T);
+ TargetRegistry::RegisterMCInstrInfo(*T, createSPIRVMCInstrInfo);
+ TargetRegistry::RegisterMCRegInfo(*T, createSPIRVMCRegisterInfo);
+ TargetRegistry::RegisterMCSubtargetInfo(*T, createSPIRVMCSubtargetInfo);
+ TargetRegistry::RegisterSPIRVStreamer(*T, createSPIRVMCStreamer);
+ TargetRegistry::RegisterMCInstPrinter(*T, createSPIRVMCInstPrinter);
+ TargetRegistry::RegisterMCInstrAnalysis(*T, createSPIRVInstrAnalysis);
+ TargetRegistry::RegisterMCCodeEmitter(*T, createSPIRVMCCodeEmitter);
+ TargetRegistry::RegisterMCAsmBackend(*T, createSPIRVAsmBackend);
+ TargetRegistry::RegisterAsmTargetStreamer(*T, createTargetAsmStreamer);
+ }
+}
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.h
new file mode 100644
index 0000000000000..4009fa96aa68b
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVMCTargetDesc.h
@@ -0,0 +1,52 @@
+//===-- SPIRVMCTargetDesc.h - SPIR-V Target Descriptions --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides SPIR-V specific target descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVMCTARGETDESC_H
+#define LLVM_LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVMCTARGETDESC_H
+
+#include "llvm/Support/DataTypes.h"
+#include <memory>
+
+namespace llvm {
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCInstrInfo;
+class MCObjectTargetWriter;
+class MCRegisterInfo;
+class MCSubtargetInfo;
+class MCTargetOptions;
+class Target;
+
+MCCodeEmitter *createSPIRVMCCodeEmitter(const MCInstrInfo &MCII,
+ MCContext &Ctx);
+
+MCAsmBackend *createSPIRVAsmBackend(const Target &T, const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options);
+
+std::unique_ptr<MCObjectTargetWriter> createSPIRVObjectTargetWriter();
+} // namespace llvm
+
+// Defines symbolic names for SPIR-V registers. This defines a mapping from
+// register name to register number.
+#define GET_REGINFO_ENUM
+#include "SPIRVGenRegisterInfo.inc"
+
+// Defines symbolic names for the SPIR-V instructions.
+#define GET_INSTRINFO_ENUM
+#include "SPIRVGenInstrInfo.inc"
+
+#define GET_SUBTARGETINFO_ENUM
+#include "SPIRVGenSubtargetInfo.inc"
+
+#endif // LLVM_LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVMCTARGETDESC_H
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVObjectTargetWriter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVObjectTargetWriter.cpp
new file mode 100644
index 0000000000000..685168b4073d7
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVObjectTargetWriter.cpp
@@ -0,0 +1,25 @@
+//===- SPIRVObjectTargetWriter.cpp - SPIR-V Object Target Writer *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVMCTargetDesc.h"
+#include "llvm/MC/MCSPIRVObjectWriter.h"
+
+using namespace llvm;
+
+namespace {
+
+class SPIRVObjectTargetWriter : public MCSPIRVObjectTargetWriter {
+public:
+ SPIRVObjectTargetWriter() = default;
+};
+
+} // namespace
+
+std::unique_ptr<MCObjectTargetWriter> llvm::createSPIRVObjectTargetWriter() {
+ return std::make_unique<SPIRVObjectTargetWriter>();
+}
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.cpp
new file mode 100644
index 0000000000000..0a318e0e01e59
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.cpp
@@ -0,0 +1,18 @@
+//=====- SPIRVTargetStreamer.cpp - SPIRVTargetStreamer class ------------=====//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SPIRVTargetStreamer class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SPIRVTargetStreamer.h"
+
+using namespace llvm;
+
+SPIRVTargetStreamer::SPIRVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
+SPIRVTargetStreamer::~SPIRVTargetStreamer() {}
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.h
new file mode 100644
index 0000000000000..2cc8f50aba679
--- /dev/null
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVTargetStreamer.h
@@ -0,0 +1,28 @@
+//===-- SPIRVTargetStreamer.h - SPIRV Target Streamer ----------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVTARGETSTREAMER_H
+#define LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVTARGETSTREAMER_H
+
+#include "llvm/MC/MCStreamer.h"
+
+namespace llvm {
+
+class MCSection;
+
+class SPIRVTargetStreamer : public MCTargetStreamer {
+public:
+ SPIRVTargetStreamer(MCStreamer &S);
+ ~SPIRVTargetStreamer() override;
+
+ void changeSection(const MCSection *CurSection, MCSection *Section,
+ const MCExpr *SubSection, raw_ostream &OS) override{};
+};
+} // namespace llvm
+
+#endif // LIB_TARGET_SPIRV_MCTARGETDESC_SPIRVTARGETSTREAMER_H_
diff --git a/llvm/lib/Target/SPIRV/TargetInfo/SPIRVTargetInfo.cpp b/llvm/lib/Target/SPIRV/TargetInfo/SPIRVTargetInfo.cpp
index 12ca131477a7b..fb7cab4fe779c 100644
--- a/llvm/lib/Target/SPIRV/TargetInfo/SPIRVTargetInfo.cpp
+++ b/llvm/lib/Target/SPIRV/TargetInfo/SPIRVTargetInfo.cpp
@@ -26,8 +26,3 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTargetInfo() {
RegisterTarget<Triple::spirv64> Y(getTheSPIRV64Target(), "spirv64",
"SPIR-V 64-bit", "SPIRV");
}
-
-// FIXME: Temporary stub - this function must be defined for linking
-// to succeed and will be called unconditionally by llc, so must be a no-op.
-// Remove once this function is properly implemented.
-extern "C" void LLVMInitializeSPIRVTargetMC() {}
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 9216e8d274232..7dfe98c1a92a0 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2110,6 +2110,7 @@ StringRef ModuleAddressSanitizer::getGlobalMetadataSection() const {
case Triple::MachO: return "__DATA,__asan_globals,regular";
case Triple::Wasm:
case Triple::GOFF:
+ case Triple::SPIRV:
case Triple::XCOFF:
case Triple::DXContainer:
report_fatal_error(
diff --git a/llvm/unittests/ADT/TripleTest.cpp b/llvm/unittests/ADT/TripleTest.cpp
index 30785292029cd..19e5978acedf3 100644
--- a/llvm/unittests/ADT/TripleTest.cpp
+++ b/llvm/unittests/ADT/TripleTest.cpp
@@ -999,11 +999,13 @@ TEST(TripleTest, BitWidthPredicates) {
EXPECT_FALSE(T.isArch16Bit());
EXPECT_TRUE(T.isArch32Bit());
EXPECT_FALSE(T.isArch64Bit());
+ EXPECT_TRUE(T.isSPIRV());
T.setArch(Triple::spirv64);
EXPECT_FALSE(T.isArch16Bit());
EXPECT_FALSE(T.isArch32Bit());
EXPECT_TRUE(T.isArch64Bit());
+ EXPECT_TRUE(T.isSPIRV());
T.setArch(Triple::sparc);
EXPECT_FALSE(T.isArch16Bit());
@@ -1671,6 +1673,9 @@ TEST(TripleTest, FileFormat) {
EXPECT_EQ(Triple::ELF, Triple("csky-unknown-unknown").getObjectFormat());
EXPECT_EQ(Triple::ELF, Triple("csky-unknown-linux").getObjectFormat());
+ EXPECT_EQ(Triple::SPIRV, Triple("spirv32-unknown-unknown").getObjectFormat());
+ EXPECT_EQ(Triple::SPIRV, Triple("spirv64-unknown-unknown").getObjectFormat());
+
EXPECT_EQ(Triple::ELF,
Triple("loongarch32-unknown-unknown").getObjectFormat());
EXPECT_EQ(Triple::ELF, Triple("loongarch64-unknown-linux").getObjectFormat());
@@ -1702,6 +1707,9 @@ TEST(TripleTest, FileFormat) {
T.setObjectFormat(Triple::GOFF);
EXPECT_EQ(Triple::GOFF, T.getObjectFormat());
+
+ T.setObjectFormat(Triple::SPIRV);
+ EXPECT_EQ(Triple::SPIRV, T.getObjectFormat());
}
TEST(TripleTest, NormalizeWindows) {
More information about the llvm-commits
mailing list