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