xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
181ad6265SDimitry Andric //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric ///
981ad6265SDimitry Andric /// \file
1081ad6265SDimitry Andric /// This file contains DirectX target initializer.
1181ad6265SDimitry Andric ///
1281ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1381ad6265SDimitry Andric 
1481ad6265SDimitry Andric #include "DirectXTargetMachine.h"
15*bdd1243dSDimitry Andric #include "DXILResourceAnalysis.h"
16*bdd1243dSDimitry Andric #include "DXILShaderFlags.h"
1781ad6265SDimitry Andric #include "DXILWriter/DXILWriterPass.h"
1881ad6265SDimitry Andric #include "DirectX.h"
1981ad6265SDimitry Andric #include "DirectXSubtarget.h"
2081ad6265SDimitry Andric #include "DirectXTargetTransformInfo.h"
2181ad6265SDimitry Andric #include "TargetInfo/DirectXTargetInfo.h"
2281ad6265SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
2381ad6265SDimitry Andric #include "llvm/CodeGen/Passes.h"
2481ad6265SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
2581ad6265SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
2681ad6265SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
2781ad6265SDimitry Andric #include "llvm/MC/MCSectionDXContainer.h"
2881ad6265SDimitry Andric #include "llvm/MC/SectionKind.h"
2981ad6265SDimitry Andric #include "llvm/MC/TargetRegistry.h"
30*bdd1243dSDimitry Andric #include "llvm/Passes/PassBuilder.h"
3181ad6265SDimitry Andric #include "llvm/Support/CodeGen.h"
3281ad6265SDimitry Andric #include "llvm/Support/Compiler.h"
3381ad6265SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3481ad6265SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
35*bdd1243dSDimitry Andric #include <optional>
3681ad6265SDimitry Andric 
3781ad6265SDimitry Andric using namespace llvm;
3881ad6265SDimitry Andric 
3981ad6265SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
4081ad6265SDimitry Andric   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
4181ad6265SDimitry Andric   auto *PR = PassRegistry::getPassRegistry();
4281ad6265SDimitry Andric   initializeDXILPrepareModulePass(*PR);
4381ad6265SDimitry Andric   initializeEmbedDXILPassPass(*PR);
44*bdd1243dSDimitry Andric   initializeWriteDXILPassPass(*PR);
4581ad6265SDimitry Andric   initializeDXILOpLoweringLegacyPass(*PR);
4681ad6265SDimitry Andric   initializeDXILTranslateMetadataPass(*PR);
47*bdd1243dSDimitry Andric   initializeDXILResourceWrapperPass(*PR);
48*bdd1243dSDimitry Andric   initializeShaderFlagsAnalysisWrapperPass(*PR);
4981ad6265SDimitry Andric }
5081ad6265SDimitry Andric 
5181ad6265SDimitry Andric class DXILTargetObjectFile : public TargetLoweringObjectFile {
5281ad6265SDimitry Andric public:
5381ad6265SDimitry Andric   DXILTargetObjectFile() = default;
5481ad6265SDimitry Andric 
5581ad6265SDimitry Andric   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
5681ad6265SDimitry Andric                                       const TargetMachine &TM) const override {
5781ad6265SDimitry Andric     return getContext().getDXContainerSection(GO->getSection(), Kind);
5881ad6265SDimitry Andric   }
5981ad6265SDimitry Andric 
6081ad6265SDimitry Andric protected:
6181ad6265SDimitry Andric   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
6281ad6265SDimitry Andric                                     const TargetMachine &TM) const override {
6381ad6265SDimitry Andric     llvm_unreachable("Not supported!");
6481ad6265SDimitry Andric   }
6581ad6265SDimitry Andric };
6681ad6265SDimitry Andric 
6781ad6265SDimitry Andric class DirectXPassConfig : public TargetPassConfig {
6881ad6265SDimitry Andric public:
6981ad6265SDimitry Andric   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
7081ad6265SDimitry Andric       : TargetPassConfig(TM, PM) {}
7181ad6265SDimitry Andric 
7281ad6265SDimitry Andric   DirectXTargetMachine &getDirectXTargetMachine() const {
7381ad6265SDimitry Andric     return getTM<DirectXTargetMachine>();
7481ad6265SDimitry Andric   }
7581ad6265SDimitry Andric 
7681ad6265SDimitry Andric   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
77*bdd1243dSDimitry Andric   void addCodeGenPrepare() override {
78*bdd1243dSDimitry Andric     addPass(createDXILOpLoweringLegacyPass());
79*bdd1243dSDimitry Andric     addPass(createDXILPrepareModulePass());
80*bdd1243dSDimitry Andric     addPass(createDXILTranslateMetadataPass());
81*bdd1243dSDimitry Andric   }
8281ad6265SDimitry Andric };
8381ad6265SDimitry Andric 
8481ad6265SDimitry Andric DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
8581ad6265SDimitry Andric                                            StringRef CPU, StringRef FS,
8681ad6265SDimitry Andric                                            const TargetOptions &Options,
87*bdd1243dSDimitry Andric                                            std::optional<Reloc::Model> RM,
88*bdd1243dSDimitry Andric                                            std::optional<CodeModel::Model> CM,
8981ad6265SDimitry Andric                                            CodeGenOpt::Level OL, bool JIT)
9081ad6265SDimitry Andric     : LLVMTargetMachine(T,
9181ad6265SDimitry Andric                         "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
9281ad6265SDimitry Andric                         "f32:32-f64:64-n8:16:32:64",
9381ad6265SDimitry Andric                         TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
9481ad6265SDimitry Andric                         OL),
9581ad6265SDimitry Andric       TLOF(std::make_unique<DXILTargetObjectFile>()),
9681ad6265SDimitry Andric       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
9781ad6265SDimitry Andric   initAsmInfo();
9881ad6265SDimitry Andric }
9981ad6265SDimitry Andric 
10081ad6265SDimitry Andric DirectXTargetMachine::~DirectXTargetMachine() {}
10181ad6265SDimitry Andric 
102*bdd1243dSDimitry Andric void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
103*bdd1243dSDimitry Andric   PB.registerPipelineParsingCallback(
104*bdd1243dSDimitry Andric       [](StringRef PassName, ModulePassManager &PM,
105*bdd1243dSDimitry Andric          ArrayRef<PassBuilder::PipelineElement>) {
106*bdd1243dSDimitry Andric         if (PassName == "print-dxil-resource") {
107*bdd1243dSDimitry Andric           PM.addPass(DXILResourcePrinterPass(dbgs()));
108*bdd1243dSDimitry Andric           return true;
109*bdd1243dSDimitry Andric         }
110*bdd1243dSDimitry Andric         if (PassName == "print-dx-shader-flags") {
111*bdd1243dSDimitry Andric           PM.addPass(dxil::ShaderFlagsAnalysisPrinter(dbgs()));
112*bdd1243dSDimitry Andric           return true;
113*bdd1243dSDimitry Andric         }
114*bdd1243dSDimitry Andric         return false;
115*bdd1243dSDimitry Andric       });
116*bdd1243dSDimitry Andric 
117*bdd1243dSDimitry Andric   PB.registerAnalysisRegistrationCallback([](ModuleAnalysisManager &MAM) {
118*bdd1243dSDimitry Andric     MAM.registerPass([&] { return DXILResourceAnalysis(); });
119*bdd1243dSDimitry Andric     MAM.registerPass([&] { return dxil::ShaderFlagsAnalysis(); });
120*bdd1243dSDimitry Andric   });
121*bdd1243dSDimitry Andric }
122*bdd1243dSDimitry Andric 
12381ad6265SDimitry Andric bool DirectXTargetMachine::addPassesToEmitFile(
12481ad6265SDimitry Andric     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
12581ad6265SDimitry Andric     CodeGenFileType FileType, bool DisableVerify,
12681ad6265SDimitry Andric     MachineModuleInfoWrapperPass *MMIWP) {
127*bdd1243dSDimitry Andric   TargetPassConfig *PassConfig = createPassConfig(PM);
128*bdd1243dSDimitry Andric   PassConfig->addCodeGenPrepare();
129*bdd1243dSDimitry Andric 
13081ad6265SDimitry Andric   if (TargetPassConfig::willCompleteCodeGenPipeline()) {
13181ad6265SDimitry Andric     PM.add(createDXILEmbedderPass());
132*bdd1243dSDimitry Andric     // We embed the other DXContainer globals after embedding DXIL so that the
133*bdd1243dSDimitry Andric     // globals don't pollute the DXIL.
134*bdd1243dSDimitry Andric     PM.add(createDXContainerGlobalsPass());
13581ad6265SDimitry Andric   }
13681ad6265SDimitry Andric   switch (FileType) {
13781ad6265SDimitry Andric   case CGFT_AssemblyFile:
138*bdd1243dSDimitry Andric     PM.add(createDXILPrettyPrinterPass(Out));
13981ad6265SDimitry Andric     PM.add(createPrintModulePass(Out, "", true));
14081ad6265SDimitry Andric     break;
14181ad6265SDimitry Andric   case CGFT_ObjectFile:
14281ad6265SDimitry Andric     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
14381ad6265SDimitry Andric       if (!MMIWP)
14481ad6265SDimitry Andric         MMIWP = new MachineModuleInfoWrapperPass(this);
14581ad6265SDimitry Andric       PM.add(MMIWP);
14681ad6265SDimitry Andric       if (addAsmPrinter(PM, Out, DwoOut, FileType,
14781ad6265SDimitry Andric                         MMIWP->getMMI().getContext()))
14881ad6265SDimitry Andric         return true;
14981ad6265SDimitry Andric     } else
15081ad6265SDimitry Andric       PM.add(createDXILWriterPass(Out));
15181ad6265SDimitry Andric     break;
15281ad6265SDimitry Andric   case CGFT_Null:
15381ad6265SDimitry Andric     break;
15481ad6265SDimitry Andric   }
15581ad6265SDimitry Andric   return false;
15681ad6265SDimitry Andric }
15781ad6265SDimitry Andric 
15881ad6265SDimitry Andric bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
15981ad6265SDimitry Andric                                              MCContext *&Ctx,
16081ad6265SDimitry Andric                                              raw_pwrite_stream &Out,
16181ad6265SDimitry Andric                                              bool DisableVerify) {
16281ad6265SDimitry Andric   return true;
16381ad6265SDimitry Andric }
16481ad6265SDimitry Andric 
16581ad6265SDimitry Andric TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
16681ad6265SDimitry Andric   return new DirectXPassConfig(*this, PM);
16781ad6265SDimitry Andric }
16881ad6265SDimitry Andric 
16981ad6265SDimitry Andric const DirectXSubtarget *
17081ad6265SDimitry Andric DirectXTargetMachine::getSubtargetImpl(const Function &) const {
17181ad6265SDimitry Andric   return Subtarget.get();
17281ad6265SDimitry Andric }
17381ad6265SDimitry Andric 
17481ad6265SDimitry Andric TargetTransformInfo
17581ad6265SDimitry Andric DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
17681ad6265SDimitry Andric   return TargetTransformInfo(DirectXTTIImpl(this, F));
17781ad6265SDimitry Andric }
17881ad6265SDimitry Andric 
17981ad6265SDimitry Andric DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
18081ad6265SDimitry Andric                                              const DirectXSubtarget &STI)
18181ad6265SDimitry Andric     : TargetLowering(TM) {}
182