xref: /freebsd/contrib/llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
LLVMInitializeDirectXTarget()39 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
40   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
41   auto *PR = PassRegistry::getPassRegistry();
42   initializeDXILIntrinsicExpansionLegacyPass(*PR);
43   initializeDXILPrepareModulePass(*PR);
44   initializeEmbedDXILPassPass(*PR);
45   initializeWriteDXILPassPass(*PR);
46   initializeDXContainerGlobalsPass(*PR);
47   initializeDXILOpLoweringLegacyPass(*PR);
48   initializeDXILTranslateMetadataPass(*PR);
49   initializeDXILResourceWrapperPass(*PR);
50   initializeShaderFlagsAnalysisWrapperPass(*PR);
51 }
52 
53 class DXILTargetObjectFile : public TargetLoweringObjectFile {
54 public:
55   DXILTargetObjectFile() = default;
56 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const57   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
58                                       const TargetMachine &TM) const override {
59     return getContext().getDXContainerSection(GO->getSection(), Kind);
60   }
61 
62 protected:
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const63   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
64                                     const TargetMachine &TM) const override {
65     llvm_unreachable("Not supported!");
66   }
67 };
68 
69 class DirectXPassConfig : public TargetPassConfig {
70 public:
DirectXPassConfig(DirectXTargetMachine & TM,PassManagerBase & PM)71   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
72       : TargetPassConfig(TM, PM) {}
73 
getDirectXTargetMachine() const74   DirectXTargetMachine &getDirectXTargetMachine() const {
75     return getTM<DirectXTargetMachine>();
76   }
77 
createTargetRegisterAllocator(bool)78   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
addCodeGenPrepare()79   void addCodeGenPrepare() override {
80     addPass(createDXILIntrinsicExpansionLegacyPass());
81     addPass(createDXILOpLoweringLegacyPass());
82     addPass(createDXILTranslateMetadataPass());
83     addPass(createDXILPrepareModulePass());
84   }
85 };
86 
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)87 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
88                                            StringRef CPU, StringRef FS,
89                                            const TargetOptions &Options,
90                                            std::optional<Reloc::Model> RM,
91                                            std::optional<CodeModel::Model> CM,
92                                            CodeGenOptLevel OL, bool JIT)
93     : LLVMTargetMachine(T,
94                         "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
95                         "f32:32-f64:64-n8:16:32:64",
96                         TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
97                         OL),
98       TLOF(std::make_unique<DXILTargetObjectFile>()),
99       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
100   initAsmInfo();
101 }
102 
~DirectXTargetMachine()103 DirectXTargetMachine::~DirectXTargetMachine() {}
104 
registerPassBuilderCallbacks(PassBuilder & PB)105 void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
106 #define GET_PASS_REGISTRY "DirectXPassRegistry.def"
107 #include "llvm/Passes/TargetPassRegistry.inc"
108 }
109 
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)110 bool DirectXTargetMachine::addPassesToEmitFile(
111     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
112     CodeGenFileType FileType, bool DisableVerify,
113     MachineModuleInfoWrapperPass *MMIWP) {
114   TargetPassConfig *PassConfig = createPassConfig(PM);
115   PassConfig->addCodeGenPrepare();
116 
117   switch (FileType) {
118   case CodeGenFileType::AssemblyFile:
119     PM.add(createDXILPrettyPrinterPass(Out));
120     PM.add(createPrintModulePass(Out, "", true));
121     break;
122   case CodeGenFileType::ObjectFile:
123     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
124       PM.add(createDXILEmbedderPass());
125       // We embed the other DXContainer globals after embedding DXIL so that the
126       // globals don't pollute the DXIL.
127       PM.add(createDXContainerGlobalsPass());
128 
129       if (!MMIWP)
130         MMIWP = new MachineModuleInfoWrapperPass(this);
131       PM.add(MMIWP);
132       if (addAsmPrinter(PM, Out, DwoOut, FileType,
133                         MMIWP->getMMI().getContext()))
134         return true;
135     } else
136       PM.add(createDXILWriterPass(Out));
137     break;
138   case CodeGenFileType::Null:
139     break;
140   }
141   return false;
142 }
143 
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)144 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
145                                              MCContext *&Ctx,
146                                              raw_pwrite_stream &Out,
147                                              bool DisableVerify) {
148   return true;
149 }
150 
createPassConfig(PassManagerBase & PM)151 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
152   return new DirectXPassConfig(*this, PM);
153 }
154 
155 const DirectXSubtarget *
getSubtargetImpl(const Function &) const156 DirectXTargetMachine::getSubtargetImpl(const Function &) const {
157   return Subtarget.get();
158 }
159 
160 TargetTransformInfo
getTargetTransformInfo(const Function & F) const161 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
162   return TargetTransformInfo(DirectXTTIImpl(this, F));
163 }
164 
DirectXTargetLowering(const DirectXTargetMachine & TM,const DirectXSubtarget & STI)165 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
166                                              const DirectXSubtarget &STI)
167     : TargetLowering(TM) {}
168