DirectXSubtarget::DirectXSubtarget(const Triple &TT, StringRef CPU,
StringRef FS, const DirectXTargetMachine &TM)
- : DirectXGenSubtargetInfo(TT, CPU, CPU, FS), TL(TM, *this) {}
+ : DirectXGenSubtargetInfo(TT, CPU, CPU, FS), FL(*this), TL(TM, *this) {}
+
+void DirectXSubtarget::anchor() {}
#ifndef LLVM_DIRECTX_DIRECTXSUBTARGET_H
#define LLVM_DIRECTX_DIRECTXSUBTARGET_H
+#include "DirectXFrameLowering.h"
+#include "DirectXInstrInfo.h"
#include "DirectXTargetLowering.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
class DirectXTargetMachine;
class DirectXSubtarget : public DirectXGenSubtargetInfo {
+ DirectXFrameLowering FL;
DirectXTargetLowering TL;
+ DirectXInstrInfo InstrInfo;
+
+ virtual void anchor(); // virtual anchor method
public:
DirectXSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
const DirectXTargetLowering *getTargetLowering() const override {
return &TL;
}
+
+ const DirectXFrameLowering *getFrameLowering() const override { return &FL; }
+
+ const DirectXInstrInfo *getInstrInfo() const override { return &InstrInfo; }
};
} // end namespace llvm
#include "DirectXSubtarget.h"
#include "DirectXTargetTransformInfo.h"
#include "TargetInfo/DirectXTargetInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/MC/MCSectionDXContainer.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CodeGen.h"
MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override {
- llvm_unreachable("Not supported!");
+ return getContext().getDXContainerSection(GO->getSection(), Kind);
}
protected:
TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
OL),
TLOF(std::make_unique<DXILTargetObjectFile>()),
- Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {}
+ Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
+ initAsmInfo();
+}
DirectXTargetMachine::~DirectXTargetMachine() {}
PM.add(createDXILOpLoweringLegacyPass());
PM.add(createDXILPrepareModulePass());
PM.add(createDXILTranslateMetadataPass());
+ if (TargetPassConfig::willCompleteCodeGenPipeline()) {
+ PM.add(createDXILEmbedderPass());
+ }
switch (FileType) {
case CGFT_AssemblyFile:
- if (TargetPassConfig::willCompleteCodeGenPipeline()) {
- PM.add(createDXILEmbedderPass());
- }
PM.add(createPrintModulePass(Out, "", true));
break;
case CGFT_ObjectFile:
- // TODO: Use MC Object streamer to write DXContainer
- PM.add(createDXILWriterPass(Out));
+ if (TargetPassConfig::willCompleteCodeGenPipeline()) {
+ if (!MMIWP)
+ MMIWP = new MachineModuleInfoWrapperPass(this);
+ PM.add(MMIWP);
+ if (addAsmPrinter(PM, Out, DwoOut, FileType,
+ MMIWP->getMMI().getContext()))
+ return true;
+ } else
+ PM.add(createDXILWriterPass(Out));
break;
case CGFT_Null:
break;
add_llvm_component_library(LLVMDirectXDesc
+ DirectXContainerObjectWriter.cpp
DirectXMCTargetDesc.cpp
LINK_COMPONENTS
--- /dev/null
+//===-- DirectXContainerObjectWriter.cpp - DX 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains DXContainer object writers for the DirectX backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DirectXContainerObjectWriter.h"
+#include "llvm/MC/MCDXContainerWriter.h"
+
+using namespace llvm;
+
+namespace {
+class DirectXContainerObjectWriter : public MCDXContainerTargetWriter {
+public:
+ DirectXContainerObjectWriter() : MCDXContainerTargetWriter() {}
+};
+} // namespace
+
+std::unique_ptr<MCObjectTargetWriter>
+llvm::createDXContainerTargetObjectWriter() {
+ return std::make_unique<DirectXContainerObjectWriter>();
+}
--- /dev/null
+//===-- DirectXContainerObjectWriter.h - DX 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains DXContainer object writers for the DirectX backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DIRECTX_DIRECTXCONTAINEROBJECTWRITER_H
+#define LLVM_DIRECTX_DIRECTXCONTAINEROBJECTWRITER_H
+
+#include "llvm/MC/MCObjectWriter.h"
+
+namespace llvm {
+
+std::unique_ptr<MCObjectTargetWriter> createDXContainerTargetObjectWriter();
+
+}
+
+#endif // LLVM_DIRECTX_DIRECTXCONTAINEROBJECTWRITER_H
///
//===----------------------------------------------------------------------===//
+#include "DirectXMCTargetDesc.h"
+#include "DirectXContainerObjectWriter.h"
+#include "TargetInfo/DirectXTargetInfo.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCDXContainerWriter.h"
+#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Compiler.h"
+#include <memory>
using namespace llvm;
+#define GET_INSTRINFO_MC_DESC
+#define GET_INSTRINFO_MC_HELPERS
+#include "DirectXGenInstrInfo.inc"
+
#define GET_SUBTARGETINFO_MC_DESC
#include "DirectXGenSubtargetInfo.inc"
-extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTargetMC() {}
+#define GET_REGINFO_MC_DESC
+#include "DirectXGenRegisterInfo.inc"
+
+namespace {
+
+// DXILInstPrinter is a null stub because DXIL instructions aren't printed.
+class DXILInstPrinter : public MCInstPrinter {
+public:
+ DXILInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI)
+ : MCInstPrinter(MAI, MII, MRI) {}
+
+ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
+ const MCSubtargetInfo &STI, raw_ostream &O) override {}
+
+ std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override {
+ return std::make_pair<const char *, uint64_t>("", 0ull);
+ }
+
+private:
+};
+
+class DXILMCCodeEmitter : public MCCodeEmitter {
+public:
+ DXILMCCodeEmitter() {}
+
+ void encodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const override {}
+};
+
+class DXILAsmBackend : public MCAsmBackend {
+
+public:
+ DXILAsmBackend(const MCSubtargetInfo &STI) : MCAsmBackend(support::little) {}
+ ~DXILAsmBackend() override = default;
+
+ 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 createDXContainerTargetObjectWriter();
+ }
+
+ unsigned getNumFixupKinds() const override { return 0; }
+
+ bool writeNopData(raw_ostream &OS, uint64_t Count,
+ const MCSubtargetInfo *STI) const override {
+ return true;
+ }
+
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+ const MCRelaxableFragment *DF,
+ const MCAsmLayout &Layout) const override {
+ return true;
+ }
+};
+
+class DirectXMCAsmInfo : public MCAsmInfo {
+public:
+ explicit DirectXMCAsmInfo(const Triple &TT, const MCTargetOptions &Options)
+ : MCAsmInfo() {}
+};
+
+} // namespace
+
+static MCInstPrinter *createDXILMCInstPrinter(const Triple &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI) {
+ if (SyntaxVariant == 0)
+ return new DXILInstPrinter(MAI, MII, MRI);
+ return nullptr;
+}
+
+MCCodeEmitter *createDXILMCCodeEmitter(const MCInstrInfo &MCII,
+ MCContext &Ctx) {
+ return new DXILMCCodeEmitter();
+}
+
+MCAsmBackend *createDXILMCAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
+ const MCTargetOptions &Options) {
+ return new DXILAsmBackend(STI);
+}
+
+static MCSubtargetInfo *
+createDirectXMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
+ return createDirectXMCSubtargetInfoImpl(TT, CPU, /*TuneCPU*/ CPU, FS);
+}
+
+static MCRegisterInfo *createDirectXMCRegisterInfo(const Triple &Triple) {
+ return new MCRegisterInfo();
+}
+
+static MCInstrInfo *createDirectXMCInstrInfo() { return new MCInstrInfo(); }
+
+extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTargetMC() {
+ Target &T = getTheDirectXTarget();
+ RegisterMCAsmInfo<DirectXMCAsmInfo> X(T);
+ TargetRegistry::RegisterMCInstrInfo(T, createDirectXMCInstrInfo);
+ TargetRegistry::RegisterMCInstPrinter(T, createDXILMCInstPrinter);
+ TargetRegistry::RegisterMCRegInfo(T, createDirectXMCRegisterInfo);
+ TargetRegistry::RegisterMCSubtargetInfo(T, createDirectXMCSubtargetInfo);
+ TargetRegistry::RegisterMCCodeEmitter(T, createDXILMCCodeEmitter);
+ TargetRegistry::RegisterMCAsmBackend(T, createDXILMCAsmBackend);
+}
; RUN: llc %s --filetype=asm -o - | FileCheck %s
; RUN: opt %s -dxil-embed -S -o - | FileCheck %s
-target triple = "dxil-unknown-unknown"
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+target triple = "dxil-unknown-shadermodel6.5-library"
define i32 @add(i32 %a, i32 %b) {
%sum = add i32 %a, %b
; CHECK: @dx.dxil = private constant [[BC_TYPE:\[[0-9]+ x i8\]]] c"BC\C0\DE{{[^"]+}}", section "DXIL", align 4
; CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @dx.dxil], section "llvm.metadata"
+
+; This is using regex matches on some sizes, offsets and fields. These are all
+; going to change as the DirectX backend continues to evolve and implement more
+; features. Rather than extending this test to cover those future features, this
+; test's matches are extremely fuzzy so that it won't break.
+
+; DXC: --- !dxcontainer
+; DXC-NEXT: Header:
+; DXC-NEXT: Hash: [ 0x0, 0x0, 0x0,
+; DXC: Version:
+; DXC-NEXT: Major: 1
+; DXC-NEXT: Minor: 0
+; DXC-NEXT: FileSize: [[#]]
+; DXC-NEXT: PartCount: [[#]]
+; DXC-NEXT: PartOffsets: [ {{[0-9, ]+}} ]
+; DXC-NEXT: Parts:
+
+; In verifying the DXIL part, this test captures the size of the part, and
+; derives the program header and dxil size fields from the part's size.
+
+; DXC: - Name: DXIL
+; DXC-NEXT: Size: [[#SIZE:]]
+; DXC-NEXT: Program:
+; DXC-NEXT: MajorVersion: 6
+; DXC-NEXT: MinorVersion: 5
+; DXC-NEXT: ShaderKind: 6
+; DXC-NEXT: Size: [[#div(SIZE,4) - 2]]
+; DXC-NEXT: DXILMajorVersion: [[#]]
+; DXC-NEXT: DXILMinorVersion: [[#]]
+; DXC-NEXT: DXILSize: [[#SIZE - 32]]
+; DXC-NEXT: DXIL: [ 0x42, 0x43, 0xC0, 0xDE,