xref: /llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision bfd05102d817fce38938ce864f89ad90ef0b6cda)
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 "DXILDataScalarization.h"
16 #include "DXILFlattenArrays.h"
17 #include "DXILIntrinsicExpansion.h"
18 #include "DXILOpLowering.h"
19 #include "DXILPrettyPrinter.h"
20 #include "DXILResourceAccess.h"
21 #include "DXILResourceAnalysis.h"
22 #include "DXILShaderFlags.h"
23 #include "DXILTranslateMetadata.h"
24 #include "DXILWriter/DXILWriterPass.h"
25 #include "DirectX.h"
26 #include "DirectXSubtarget.h"
27 #include "DirectXTargetTransformInfo.h"
28 #include "TargetInfo/DirectXTargetInfo.h"
29 #include "llvm/CodeGen/MachineModuleInfo.h"
30 #include "llvm/CodeGen/Passes.h"
31 #include "llvm/CodeGen/TargetPassConfig.h"
32 #include "llvm/IR/IRPrintingPasses.h"
33 #include "llvm/IR/LegacyPassManager.h"
34 #include "llvm/InitializePasses.h"
35 #include "llvm/MC/MCSectionDXContainer.h"
36 #include "llvm/MC/SectionKind.h"
37 #include "llvm/MC/TargetRegistry.h"
38 #include "llvm/Passes/PassBuilder.h"
39 #include "llvm/Support/CodeGen.h"
40 #include "llvm/Support/Compiler.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include "llvm/Target/TargetLoweringObjectFile.h"
43 #include "llvm/Transforms/Scalar/Scalarizer.h"
44 #include <optional>
45 
46 using namespace llvm;
47 
48 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
49   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
50   auto *PR = PassRegistry::getPassRegistry();
51   initializeDXILIntrinsicExpansionLegacyPass(*PR);
52   initializeDXILDataScalarizationLegacyPass(*PR);
53   initializeDXILFlattenArraysLegacyPass(*PR);
54   initializeScalarizerLegacyPassPass(*PR);
55   initializeDXILPrepareModulePass(*PR);
56   initializeEmbedDXILPassPass(*PR);
57   initializeWriteDXILPassPass(*PR);
58   initializeDXContainerGlobalsPass(*PR);
59   initializeDXILOpLoweringLegacyPass(*PR);
60   initializeDXILResourceAccessLegacyPass(*PR);
61   initializeDXILTranslateMetadataLegacyPass(*PR);
62   initializeDXILResourceMDWrapperPass(*PR);
63   initializeShaderFlagsAnalysisWrapperPass(*PR);
64   initializeDXILFinalizeLinkageLegacyPass(*PR);
65 }
66 
67 class DXILTargetObjectFile : public TargetLoweringObjectFile {
68 public:
69   DXILTargetObjectFile() = default;
70 
71   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
72                                       const TargetMachine &TM) const override {
73     return getContext().getDXContainerSection(GO->getSection(), Kind);
74   }
75 
76 protected:
77   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
78                                     const TargetMachine &TM) const override {
79     llvm_unreachable("Not supported!");
80   }
81 };
82 
83 class DirectXPassConfig : public TargetPassConfig {
84 public:
85   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
86       : TargetPassConfig(TM, PM) {}
87 
88   DirectXTargetMachine &getDirectXTargetMachine() const {
89     return getTM<DirectXTargetMachine>();
90   }
91 
92   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
93   void addCodeGenPrepare() override {
94     addPass(createDXILFinalizeLinkageLegacyPass());
95     addPass(createDXILIntrinsicExpansionLegacyPass());
96     addPass(createDXILDataScalarizationLegacyPass());
97     addPass(createDXILFlattenArraysLegacyPass());
98     addPass(createDXILResourceAccessLegacyPass());
99     ScalarizerPassOptions DxilScalarOptions;
100     DxilScalarOptions.ScalarizeLoadStore = true;
101     addPass(createScalarizerPass(DxilScalarOptions));
102     addPass(createDXILTranslateMetadataLegacyPass());
103     addPass(createDXILOpLoweringLegacyPass());
104     addPass(createDXILPrepareModulePass());
105   }
106 };
107 
108 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
109                                            StringRef CPU, StringRef FS,
110                                            const TargetOptions &Options,
111                                            std::optional<Reloc::Model> RM,
112                                            std::optional<CodeModel::Model> CM,
113                                            CodeGenOptLevel OL, bool JIT)
114     : CodeGenTargetMachineImpl(
115           T,
116           "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
117           "f32:32-f64:64-n8:16:32:64",
118           TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, OL),
119       TLOF(std::make_unique<DXILTargetObjectFile>()),
120       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
121   initAsmInfo();
122 }
123 
124 DirectXTargetMachine::~DirectXTargetMachine() {}
125 
126 void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
127 #define GET_PASS_REGISTRY "DirectXPassRegistry.def"
128 #include "llvm/Passes/TargetPassRegistry.inc"
129 }
130 
131 bool DirectXTargetMachine::addPassesToEmitFile(
132     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
133     CodeGenFileType FileType, bool DisableVerify,
134     MachineModuleInfoWrapperPass *MMIWP) {
135   TargetPassConfig *PassConfig = createPassConfig(PM);
136   PassConfig->addCodeGenPrepare();
137 
138   switch (FileType) {
139   case CodeGenFileType::AssemblyFile:
140     PM.add(createDXILPrettyPrinterLegacyPass(Out));
141     PM.add(createPrintModulePass(Out, "", true));
142     break;
143   case CodeGenFileType::ObjectFile:
144     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
145       PM.add(createDXILEmbedderPass());
146       // We embed the other DXContainer globals after embedding DXIL so that the
147       // globals don't pollute the DXIL.
148       PM.add(createDXContainerGlobalsPass());
149 
150       if (!MMIWP)
151         MMIWP = new MachineModuleInfoWrapperPass(this);
152       PM.add(MMIWP);
153       if (addAsmPrinter(PM, Out, DwoOut, FileType,
154                         MMIWP->getMMI().getContext()))
155         return true;
156     } else
157       PM.add(createDXILWriterPass(Out));
158     break;
159   case CodeGenFileType::Null:
160     break;
161   }
162   return false;
163 }
164 
165 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
166                                              MCContext *&Ctx,
167                                              raw_pwrite_stream &Out,
168                                              bool DisableVerify) {
169   return true;
170 }
171 
172 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
173   return new DirectXPassConfig(*this, PM);
174 }
175 
176 const DirectXSubtarget *
177 DirectXTargetMachine::getSubtargetImpl(const Function &) const {
178   return Subtarget.get();
179 }
180 
181 TargetTransformInfo
182 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
183   return TargetTransformInfo(DirectXTTIImpl(this, F));
184 }
185 
186 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
187                                              const DirectXSubtarget &STI)
188     : TargetLowering(TM) {}
189