[llvm] 2af61e6 - [DirectX] Add DirectX target object writer

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 17 19:33:16 PDT 2022


Author: Chris Bieneman
Date: 2022-06-17T21:33:08-05:00
New Revision: 2af61e620eeae6d248c37eee096200016bc102f9

URL: https://github.com/llvm/llvm-project/commit/2af61e620eeae6d248c37eee096200016bc102f9
DIFF: https://github.com/llvm/llvm-project/commit/2af61e620eeae6d248c37eee096200016bc102f9.diff

LOG: [DirectX] Add DirectX target object writer

This is the last piece to bring together writing DXContainer files
containing DXIL through the DirectX backend.

While this change only has one test, all of the tests under
llvm/test/tools/dxil-dis also exercise this code. With this change the
output object file type for the dxil target is now DXContainer. Each of
the existing tests will generate DXContainer files, and the dxil-dis
tests additionally verify that the DXContainers generated are
well-formed and can be parsed by the DirectXShaderCompiler tools.

Depends on D127153 and D127165

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

Added: 
    llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.cpp
    llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.h

Modified: 
    llvm/lib/Target/DirectX/DirectXSubtarget.cpp
    llvm/lib/Target/DirectX/DirectXSubtarget.h
    llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
    llvm/lib/Target/DirectX/MCTargetDesc/CMakeLists.txt
    llvm/lib/Target/DirectX/MCTargetDesc/DirectXMCTargetDesc.cpp
    llvm/test/CodeGen/DirectX/embed-dxil.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/DirectX/DirectXSubtarget.cpp b/llvm/lib/Target/DirectX/DirectXSubtarget.cpp
index 96023224f0289..526b7d29fb13e 100644
--- a/llvm/lib/Target/DirectX/DirectXSubtarget.cpp
+++ b/llvm/lib/Target/DirectX/DirectXSubtarget.cpp
@@ -24,4 +24,6 @@ using namespace llvm;
 
 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() {}

diff  --git a/llvm/lib/Target/DirectX/DirectXSubtarget.h b/llvm/lib/Target/DirectX/DirectXSubtarget.h
index 8840c0e038fac..464d05a0e1ffe 100644
--- a/llvm/lib/Target/DirectX/DirectXSubtarget.h
+++ b/llvm/lib/Target/DirectX/DirectXSubtarget.h
@@ -13,6 +13,8 @@
 #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"
@@ -26,7 +28,11 @@ namespace llvm {
 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,
@@ -39,6 +45,10 @@ class DirectXSubtarget : public DirectXGenSubtargetInfo {
   const DirectXTargetLowering *getTargetLowering() const override {
     return &TL;
   }
+
+  const DirectXFrameLowering *getFrameLowering() const override { return &FL; }
+
+  const DirectXInstrInfo *getInstrInfo() const override { return &InstrInfo; }
 };
 
 } // end namespace llvm

diff  --git a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
index 91d9ebb3d6960..44bef80ea6fb8 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp
@@ -17,10 +17,12 @@
 #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"
@@ -45,7 +47,7 @@ class DXILTargetObjectFile : public TargetLoweringObjectFile {
 
   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
                                       const TargetMachine &TM) const override {
-    llvm_unreachable("Not supported!");
+    return getContext().getDXContainerSection(GO->getSection(), Kind);
   }
 
 protected:
@@ -79,7 +81,9 @@ DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
                         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() {}
 
@@ -90,16 +94,23 @@ bool DirectXTargetMachine::addPassesToEmitFile(
   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;

diff  --git a/llvm/lib/Target/DirectX/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/DirectX/MCTargetDesc/CMakeLists.txt
index 7ffa93a1faded..392fb99b490cf 100644
--- a/llvm/lib/Target/DirectX/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/DirectX/MCTargetDesc/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_llvm_component_library(LLVMDirectXDesc
+  DirectXContainerObjectWriter.cpp
   DirectXMCTargetDesc.cpp
 
   LINK_COMPONENTS

diff  --git a/llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.cpp b/llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.cpp
new file mode 100644
index 0000000000000..78ccbc444bceb
--- /dev/null
+++ b/llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.cpp
@@ -0,0 +1,28 @@
+//===-- 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>();
+}

diff  --git a/llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.h b/llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.h
new file mode 100644
index 0000000000000..a6fbdc865f7d7
--- /dev/null
+++ b/llvm/lib/Target/DirectX/MCTargetDesc/DirectXContainerObjectWriter.h
@@ -0,0 +1,24 @@
+//===-- 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

diff  --git a/llvm/lib/Target/DirectX/MCTargetDesc/DirectXMCTargetDesc.cpp b/llvm/lib/Target/DirectX/MCTargetDesc/DirectXMCTargetDesc.cpp
index be690b7287057..0c97ab62a37b5 100644
--- a/llvm/lib/Target/DirectX/MCTargetDesc/DirectXMCTargetDesc.cpp
+++ b/llvm/lib/Target/DirectX/MCTargetDesc/DirectXMCTargetDesc.cpp
@@ -11,17 +11,142 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#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);
+}

diff  --git a/llvm/test/CodeGen/DirectX/embed-dxil.ll b/llvm/test/CodeGen/DirectX/embed-dxil.ll
index f56fefede7fce..c84bd2cac2698 100644
--- a/llvm/test/CodeGen/DirectX/embed-dxil.ll
+++ b/llvm/test/CodeGen/DirectX/embed-dxil.ll
@@ -1,6 +1,7 @@
 ; 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
@@ -9,3 +10,34 @@ define i32 @add(i32 %a, i32 %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,


        


More information about the llvm-commits mailing list