xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
1 //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file contains DirectX target initializer.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "DirectXTargetMachine.h"
15 #include "DXILResourceAnalysis.h"
16 #include "DXILShaderFlags.h"
17 #include "DXILWriter/DXILWriterPass.h"
18 #include "DirectX.h"
19 #include "DirectXSubtarget.h"
20 #include "DirectXTargetTransformInfo.h"
21 #include "TargetInfo/DirectXTargetInfo.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/CodeGen/TargetPassConfig.h"
25 #include "llvm/IR/IRPrintingPasses.h"
26 #include "llvm/IR/LegacyPassManager.h"
27 #include "llvm/MC/MCSectionDXContainer.h"
28 #include "llvm/MC/SectionKind.h"
29 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Passes/PassBuilder.h"
31 #include "llvm/Support/CodeGen.h"
32 #include "llvm/Support/Compiler.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Target/TargetLoweringObjectFile.h"
35 #include <optional>
36 
37 using namespace llvm;
38 
39 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
40   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
41   auto *PR = PassRegistry::getPassRegistry();
42   initializeDXILPrepareModulePass(*PR);
43   initializeEmbedDXILPassPass(*PR);
44   initializeWriteDXILPassPass(*PR);
45   initializeDXContainerGlobalsPass(*PR);
46   initializeDXILOpLoweringLegacyPass(*PR);
47   initializeDXILTranslateMetadataPass(*PR);
48   initializeDXILResourceWrapperPass(*PR);
49   initializeShaderFlagsAnalysisWrapperPass(*PR);
50 }
51 
52 class DXILTargetObjectFile : public TargetLoweringObjectFile {
53 public:
54   DXILTargetObjectFile() = default;
55 
56   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
57                                       const TargetMachine &TM) const override {
58     return getContext().getDXContainerSection(GO->getSection(), Kind);
59   }
60 
61 protected:
62   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
63                                     const TargetMachine &TM) const override {
64     llvm_unreachable("Not supported!");
65   }
66 };
67 
68 class DirectXPassConfig : public TargetPassConfig {
69 public:
70   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
71       : TargetPassConfig(TM, PM) {}
72 
73   DirectXTargetMachine &getDirectXTargetMachine() const {
74     return getTM<DirectXTargetMachine>();
75   }
76 
77   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
78   void addCodeGenPrepare() override {
79     addPass(createDXILOpLoweringLegacyPass());
80     addPass(createDXILPrepareModulePass());
81     addPass(createDXILTranslateMetadataPass());
82   }
83 };
84 
85 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
86                                            StringRef CPU, StringRef FS,
87                                            const TargetOptions &Options,
88                                            std::optional<Reloc::Model> RM,
89                                            std::optional<CodeModel::Model> CM,
90                                            CodeGenOptLevel OL, bool JIT)
91     : LLVMTargetMachine(T,
92                         "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
93                         "f32:32-f64:64-n8:16:32:64",
94                         TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
95                         OL),
96       TLOF(std::make_unique<DXILTargetObjectFile>()),
97       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
98   initAsmInfo();
99 }
100 
101 DirectXTargetMachine::~DirectXTargetMachine() {}
102 
103 void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
104   PB.registerPipelineParsingCallback(
105       [](StringRef PassName, ModulePassManager &PM,
106          ArrayRef<PassBuilder::PipelineElement>) {
107         if (PassName == "print-dxil-resource") {
108           PM.addPass(DXILResourcePrinterPass(dbgs()));
109           return true;
110         }
111         if (PassName == "print-dx-shader-flags") {
112           PM.addPass(dxil::ShaderFlagsAnalysisPrinter(dbgs()));
113           return true;
114         }
115         return false;
116       });
117 
118   PB.registerAnalysisRegistrationCallback([](ModuleAnalysisManager &MAM) {
119     MAM.registerPass([&] { return DXILResourceAnalysis(); });
120     MAM.registerPass([&] { return dxil::ShaderFlagsAnalysis(); });
121   });
122 }
123 
124 bool DirectXTargetMachine::addPassesToEmitFile(
125     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
126     CodeGenFileType FileType, bool DisableVerify,
127     MachineModuleInfoWrapperPass *MMIWP) {
128   TargetPassConfig *PassConfig = createPassConfig(PM);
129   PassConfig->addCodeGenPrepare();
130 
131   switch (FileType) {
132   case CodeGenFileType::AssemblyFile:
133     PM.add(createDXILPrettyPrinterPass(Out));
134     PM.add(createPrintModulePass(Out, "", true));
135     break;
136   case CodeGenFileType::ObjectFile:
137     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
138       PM.add(createDXILEmbedderPass());
139       // We embed the other DXContainer globals after embedding DXIL so that the
140       // globals don't pollute the DXIL.
141       PM.add(createDXContainerGlobalsPass());
142 
143       if (!MMIWP)
144         MMIWP = new MachineModuleInfoWrapperPass(this);
145       PM.add(MMIWP);
146       if (addAsmPrinter(PM, Out, DwoOut, FileType,
147                         MMIWP->getMMI().getContext()))
148         return true;
149     } else
150       PM.add(createDXILWriterPass(Out));
151     break;
152   case CodeGenFileType::Null:
153     break;
154   }
155   return false;
156 }
157 
158 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
159                                              MCContext *&Ctx,
160                                              raw_pwrite_stream &Out,
161                                              bool DisableVerify) {
162   return true;
163 }
164 
165 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
166   return new DirectXPassConfig(*this, PM);
167 }
168 
169 const DirectXSubtarget *
170 DirectXTargetMachine::getSubtargetImpl(const Function &) const {
171   return Subtarget.get();
172 }
173 
174 TargetTransformInfo
175 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
176   return TargetTransformInfo(DirectXTTIImpl(this, F));
177 }
178 
179 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
180                                              const DirectXSubtarget &STI)
181     : TargetLowering(TM) {}
182