xref: /src/contrib/llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1145449b1SDimitry Andric //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===//
2145449b1SDimitry Andric //
3145449b1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4145449b1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5145449b1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6145449b1SDimitry Andric //
7145449b1SDimitry Andric //===----------------------------------------------------------------------===//
8145449b1SDimitry Andric ///
9145449b1SDimitry Andric /// \file
10145449b1SDimitry Andric /// This file contains DirectX target initializer.
11145449b1SDimitry Andric ///
12145449b1SDimitry Andric //===----------------------------------------------------------------------===//
13145449b1SDimitry Andric 
14145449b1SDimitry Andric #include "DirectXTargetMachine.h"
15e3b55780SDimitry Andric #include "DXILResourceAnalysis.h"
16e3b55780SDimitry Andric #include "DXILShaderFlags.h"
17145449b1SDimitry Andric #include "DXILWriter/DXILWriterPass.h"
18145449b1SDimitry Andric #include "DirectX.h"
19145449b1SDimitry Andric #include "DirectXSubtarget.h"
20145449b1SDimitry Andric #include "DirectXTargetTransformInfo.h"
21145449b1SDimitry Andric #include "TargetInfo/DirectXTargetInfo.h"
22145449b1SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
23145449b1SDimitry Andric #include "llvm/CodeGen/Passes.h"
24145449b1SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
25145449b1SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
26145449b1SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
27145449b1SDimitry Andric #include "llvm/MC/MCSectionDXContainer.h"
28145449b1SDimitry Andric #include "llvm/MC/SectionKind.h"
29145449b1SDimitry Andric #include "llvm/MC/TargetRegistry.h"
30e3b55780SDimitry Andric #include "llvm/Passes/PassBuilder.h"
31145449b1SDimitry Andric #include "llvm/Support/CodeGen.h"
32145449b1SDimitry Andric #include "llvm/Support/Compiler.h"
33145449b1SDimitry Andric #include "llvm/Support/ErrorHandling.h"
34145449b1SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
35e3b55780SDimitry Andric #include <optional>
36145449b1SDimitry Andric 
37145449b1SDimitry Andric using namespace llvm;
38145449b1SDimitry Andric 
LLVMInitializeDirectXTarget()39145449b1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
40145449b1SDimitry Andric   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
41145449b1SDimitry Andric   auto *PR = PassRegistry::getPassRegistry();
42ac9a064cSDimitry Andric   initializeDXILIntrinsicExpansionLegacyPass(*PR);
43145449b1SDimitry Andric   initializeDXILPrepareModulePass(*PR);
44145449b1SDimitry Andric   initializeEmbedDXILPassPass(*PR);
45e3b55780SDimitry Andric   initializeWriteDXILPassPass(*PR);
46b1c73532SDimitry Andric   initializeDXContainerGlobalsPass(*PR);
47145449b1SDimitry Andric   initializeDXILOpLoweringLegacyPass(*PR);
48145449b1SDimitry Andric   initializeDXILTranslateMetadataPass(*PR);
49e3b55780SDimitry Andric   initializeDXILResourceWrapperPass(*PR);
50e3b55780SDimitry Andric   initializeShaderFlagsAnalysisWrapperPass(*PR);
51145449b1SDimitry Andric }
52145449b1SDimitry Andric 
53145449b1SDimitry Andric class DXILTargetObjectFile : public TargetLoweringObjectFile {
54145449b1SDimitry Andric public:
55145449b1SDimitry Andric   DXILTargetObjectFile() = default;
56145449b1SDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const57145449b1SDimitry Andric   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
58145449b1SDimitry Andric                                       const TargetMachine &TM) const override {
59145449b1SDimitry Andric     return getContext().getDXContainerSection(GO->getSection(), Kind);
60145449b1SDimitry Andric   }
61145449b1SDimitry Andric 
62145449b1SDimitry Andric protected:
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const63145449b1SDimitry Andric   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
64145449b1SDimitry Andric                                     const TargetMachine &TM) const override {
65145449b1SDimitry Andric     llvm_unreachable("Not supported!");
66145449b1SDimitry Andric   }
67145449b1SDimitry Andric };
68145449b1SDimitry Andric 
69145449b1SDimitry Andric class DirectXPassConfig : public TargetPassConfig {
70145449b1SDimitry Andric public:
DirectXPassConfig(DirectXTargetMachine & TM,PassManagerBase & PM)71145449b1SDimitry Andric   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
72145449b1SDimitry Andric       : TargetPassConfig(TM, PM) {}
73145449b1SDimitry Andric 
getDirectXTargetMachine() const74145449b1SDimitry Andric   DirectXTargetMachine &getDirectXTargetMachine() const {
75145449b1SDimitry Andric     return getTM<DirectXTargetMachine>();
76145449b1SDimitry Andric   }
77145449b1SDimitry Andric 
createTargetRegisterAllocator(bool)78145449b1SDimitry Andric   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
addCodeGenPrepare()79e3b55780SDimitry Andric   void addCodeGenPrepare() override {
80ac9a064cSDimitry Andric     addPass(createDXILIntrinsicExpansionLegacyPass());
81e3b55780SDimitry Andric     addPass(createDXILOpLoweringLegacyPass());
82e3b55780SDimitry Andric     addPass(createDXILTranslateMetadataPass());
83ac9a064cSDimitry Andric     addPass(createDXILPrepareModulePass());
84e3b55780SDimitry Andric   }
85145449b1SDimitry Andric };
86145449b1SDimitry Andric 
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)87145449b1SDimitry Andric DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
88145449b1SDimitry Andric                                            StringRef CPU, StringRef FS,
89145449b1SDimitry Andric                                            const TargetOptions &Options,
90e3b55780SDimitry Andric                                            std::optional<Reloc::Model> RM,
91e3b55780SDimitry Andric                                            std::optional<CodeModel::Model> CM,
92b1c73532SDimitry Andric                                            CodeGenOptLevel OL, bool JIT)
93145449b1SDimitry Andric     : LLVMTargetMachine(T,
94145449b1SDimitry Andric                         "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
95145449b1SDimitry Andric                         "f32:32-f64:64-n8:16:32:64",
96145449b1SDimitry Andric                         TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
97145449b1SDimitry Andric                         OL),
98145449b1SDimitry Andric       TLOF(std::make_unique<DXILTargetObjectFile>()),
99145449b1SDimitry Andric       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
100145449b1SDimitry Andric   initAsmInfo();
101145449b1SDimitry Andric }
102145449b1SDimitry Andric 
~DirectXTargetMachine()103145449b1SDimitry Andric DirectXTargetMachine::~DirectXTargetMachine() {}
104145449b1SDimitry Andric 
registerPassBuilderCallbacks(PassBuilder & PB)105ac9a064cSDimitry Andric void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
106ac9a064cSDimitry Andric #define GET_PASS_REGISTRY "DirectXPassRegistry.def"
107ac9a064cSDimitry Andric #include "llvm/Passes/TargetPassRegistry.inc"
108e3b55780SDimitry Andric }
109e3b55780SDimitry Andric 
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)110145449b1SDimitry Andric bool DirectXTargetMachine::addPassesToEmitFile(
111145449b1SDimitry Andric     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
112145449b1SDimitry Andric     CodeGenFileType FileType, bool DisableVerify,
113145449b1SDimitry Andric     MachineModuleInfoWrapperPass *MMIWP) {
114e3b55780SDimitry Andric   TargetPassConfig *PassConfig = createPassConfig(PM);
115e3b55780SDimitry Andric   PassConfig->addCodeGenPrepare();
116e3b55780SDimitry Andric 
117b1c73532SDimitry Andric   switch (FileType) {
118b1c73532SDimitry Andric   case CodeGenFileType::AssemblyFile:
119b1c73532SDimitry Andric     PM.add(createDXILPrettyPrinterPass(Out));
120b1c73532SDimitry Andric     PM.add(createPrintModulePass(Out, "", true));
121b1c73532SDimitry Andric     break;
122b1c73532SDimitry Andric   case CodeGenFileType::ObjectFile:
123145449b1SDimitry Andric     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
124145449b1SDimitry Andric       PM.add(createDXILEmbedderPass());
125e3b55780SDimitry Andric       // We embed the other DXContainer globals after embedding DXIL so that the
126e3b55780SDimitry Andric       // globals don't pollute the DXIL.
127e3b55780SDimitry Andric       PM.add(createDXContainerGlobalsPass());
128b1c73532SDimitry Andric 
129145449b1SDimitry Andric       if (!MMIWP)
130145449b1SDimitry Andric         MMIWP = new MachineModuleInfoWrapperPass(this);
131145449b1SDimitry Andric       PM.add(MMIWP);
132145449b1SDimitry Andric       if (addAsmPrinter(PM, Out, DwoOut, FileType,
133145449b1SDimitry Andric                         MMIWP->getMMI().getContext()))
134145449b1SDimitry Andric         return true;
135145449b1SDimitry Andric     } else
136145449b1SDimitry Andric       PM.add(createDXILWriterPass(Out));
137145449b1SDimitry Andric     break;
138b1c73532SDimitry Andric   case CodeGenFileType::Null:
139145449b1SDimitry Andric     break;
140145449b1SDimitry Andric   }
141145449b1SDimitry Andric   return false;
142145449b1SDimitry Andric }
143145449b1SDimitry Andric 
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)144145449b1SDimitry Andric bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
145145449b1SDimitry Andric                                              MCContext *&Ctx,
146145449b1SDimitry Andric                                              raw_pwrite_stream &Out,
147145449b1SDimitry Andric                                              bool DisableVerify) {
148145449b1SDimitry Andric   return true;
149145449b1SDimitry Andric }
150145449b1SDimitry Andric 
createPassConfig(PassManagerBase & PM)151145449b1SDimitry Andric TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
152145449b1SDimitry Andric   return new DirectXPassConfig(*this, PM);
153145449b1SDimitry Andric }
154145449b1SDimitry Andric 
155145449b1SDimitry Andric const DirectXSubtarget *
getSubtargetImpl(const Function &) const156145449b1SDimitry Andric DirectXTargetMachine::getSubtargetImpl(const Function &) const {
157145449b1SDimitry Andric   return Subtarget.get();
158145449b1SDimitry Andric }
159145449b1SDimitry Andric 
160145449b1SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F) const161145449b1SDimitry Andric DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
162145449b1SDimitry Andric   return TargetTransformInfo(DirectXTTIImpl(this, F));
163145449b1SDimitry Andric }
164145449b1SDimitry Andric 
DirectXTargetLowering(const DirectXTargetMachine & TM,const DirectXSubtarget & STI)165145449b1SDimitry Andric DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
166145449b1SDimitry Andric                                              const DirectXSubtarget &STI)
167145449b1SDimitry Andric     : TargetLowering(TM) {}
168