xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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"
15bdd1243dSDimitry Andric #include "DXILResourceAnalysis.h"
16bdd1243dSDimitry 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"
30bdd1243dSDimitry 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"
35bdd1243dSDimitry 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();
42*0fca6ea1SDimitry Andric   initializeDXILIntrinsicExpansionLegacyPass(*PR);
4381ad6265SDimitry Andric   initializeDXILPrepareModulePass(*PR);
4481ad6265SDimitry Andric   initializeEmbedDXILPassPass(*PR);
45bdd1243dSDimitry Andric   initializeWriteDXILPassPass(*PR);
465f757f3fSDimitry Andric   initializeDXContainerGlobalsPass(*PR);
4781ad6265SDimitry Andric   initializeDXILOpLoweringLegacyPass(*PR);
4881ad6265SDimitry Andric   initializeDXILTranslateMetadataPass(*PR);
49bdd1243dSDimitry Andric   initializeDXILResourceWrapperPass(*PR);
50bdd1243dSDimitry Andric   initializeShaderFlagsAnalysisWrapperPass(*PR);
5181ad6265SDimitry Andric }
5281ad6265SDimitry Andric 
5381ad6265SDimitry Andric class DXILTargetObjectFile : public TargetLoweringObjectFile {
5481ad6265SDimitry Andric public:
5581ad6265SDimitry Andric   DXILTargetObjectFile() = default;
5681ad6265SDimitry Andric 
5781ad6265SDimitry Andric   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
5881ad6265SDimitry Andric                                       const TargetMachine &TM) const override {
5981ad6265SDimitry Andric     return getContext().getDXContainerSection(GO->getSection(), Kind);
6081ad6265SDimitry Andric   }
6181ad6265SDimitry Andric 
6281ad6265SDimitry Andric protected:
6381ad6265SDimitry Andric   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
6481ad6265SDimitry Andric                                     const TargetMachine &TM) const override {
6581ad6265SDimitry Andric     llvm_unreachable("Not supported!");
6681ad6265SDimitry Andric   }
6781ad6265SDimitry Andric };
6881ad6265SDimitry Andric 
6981ad6265SDimitry Andric class DirectXPassConfig : public TargetPassConfig {
7081ad6265SDimitry Andric public:
7181ad6265SDimitry Andric   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
7281ad6265SDimitry Andric       : TargetPassConfig(TM, PM) {}
7381ad6265SDimitry Andric 
7481ad6265SDimitry Andric   DirectXTargetMachine &getDirectXTargetMachine() const {
7581ad6265SDimitry Andric     return getTM<DirectXTargetMachine>();
7681ad6265SDimitry Andric   }
7781ad6265SDimitry Andric 
7881ad6265SDimitry Andric   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
79bdd1243dSDimitry Andric   void addCodeGenPrepare() override {
80*0fca6ea1SDimitry Andric     addPass(createDXILIntrinsicExpansionLegacyPass());
81bdd1243dSDimitry Andric     addPass(createDXILOpLoweringLegacyPass());
82bdd1243dSDimitry Andric     addPass(createDXILTranslateMetadataPass());
83*0fca6ea1SDimitry Andric     addPass(createDXILPrepareModulePass());
84bdd1243dSDimitry Andric   }
8581ad6265SDimitry Andric };
8681ad6265SDimitry Andric 
8781ad6265SDimitry Andric DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
8881ad6265SDimitry Andric                                            StringRef CPU, StringRef FS,
8981ad6265SDimitry Andric                                            const TargetOptions &Options,
90bdd1243dSDimitry Andric                                            std::optional<Reloc::Model> RM,
91bdd1243dSDimitry Andric                                            std::optional<CodeModel::Model> CM,
925f757f3fSDimitry Andric                                            CodeGenOptLevel OL, bool JIT)
9381ad6265SDimitry Andric     : LLVMTargetMachine(T,
9481ad6265SDimitry Andric                         "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
9581ad6265SDimitry Andric                         "f32:32-f64:64-n8:16:32:64",
9681ad6265SDimitry Andric                         TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
9781ad6265SDimitry Andric                         OL),
9881ad6265SDimitry Andric       TLOF(std::make_unique<DXILTargetObjectFile>()),
9981ad6265SDimitry Andric       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
10081ad6265SDimitry Andric   initAsmInfo();
10181ad6265SDimitry Andric }
10281ad6265SDimitry Andric 
10381ad6265SDimitry Andric DirectXTargetMachine::~DirectXTargetMachine() {}
10481ad6265SDimitry Andric 
105*0fca6ea1SDimitry Andric void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
106*0fca6ea1SDimitry Andric #define GET_PASS_REGISTRY "DirectXPassRegistry.def"
107*0fca6ea1SDimitry Andric #include "llvm/Passes/TargetPassRegistry.inc"
108bdd1243dSDimitry Andric }
109bdd1243dSDimitry Andric 
11081ad6265SDimitry Andric bool DirectXTargetMachine::addPassesToEmitFile(
11181ad6265SDimitry Andric     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
11281ad6265SDimitry Andric     CodeGenFileType FileType, bool DisableVerify,
11381ad6265SDimitry Andric     MachineModuleInfoWrapperPass *MMIWP) {
114bdd1243dSDimitry Andric   TargetPassConfig *PassConfig = createPassConfig(PM);
115bdd1243dSDimitry Andric   PassConfig->addCodeGenPrepare();
116bdd1243dSDimitry Andric 
1175f757f3fSDimitry Andric   switch (FileType) {
1185f757f3fSDimitry Andric   case CodeGenFileType::AssemblyFile:
1195f757f3fSDimitry Andric     PM.add(createDXILPrettyPrinterPass(Out));
1205f757f3fSDimitry Andric     PM.add(createPrintModulePass(Out, "", true));
1215f757f3fSDimitry Andric     break;
1225f757f3fSDimitry Andric   case CodeGenFileType::ObjectFile:
12381ad6265SDimitry Andric     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
12481ad6265SDimitry Andric       PM.add(createDXILEmbedderPass());
125bdd1243dSDimitry Andric       // We embed the other DXContainer globals after embedding DXIL so that the
126bdd1243dSDimitry Andric       // globals don't pollute the DXIL.
127bdd1243dSDimitry Andric       PM.add(createDXContainerGlobalsPass());
1285f757f3fSDimitry Andric 
12981ad6265SDimitry Andric       if (!MMIWP)
13081ad6265SDimitry Andric         MMIWP = new MachineModuleInfoWrapperPass(this);
13181ad6265SDimitry Andric       PM.add(MMIWP);
13281ad6265SDimitry Andric       if (addAsmPrinter(PM, Out, DwoOut, FileType,
13381ad6265SDimitry Andric                         MMIWP->getMMI().getContext()))
13481ad6265SDimitry Andric         return true;
13581ad6265SDimitry Andric     } else
13681ad6265SDimitry Andric       PM.add(createDXILWriterPass(Out));
13781ad6265SDimitry Andric     break;
1385f757f3fSDimitry Andric   case CodeGenFileType::Null:
13981ad6265SDimitry Andric     break;
14081ad6265SDimitry Andric   }
14181ad6265SDimitry Andric   return false;
14281ad6265SDimitry Andric }
14381ad6265SDimitry Andric 
14481ad6265SDimitry Andric bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
14581ad6265SDimitry Andric                                              MCContext *&Ctx,
14681ad6265SDimitry Andric                                              raw_pwrite_stream &Out,
14781ad6265SDimitry Andric                                              bool DisableVerify) {
14881ad6265SDimitry Andric   return true;
14981ad6265SDimitry Andric }
15081ad6265SDimitry Andric 
15181ad6265SDimitry Andric TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
15281ad6265SDimitry Andric   return new DirectXPassConfig(*this, PM);
15381ad6265SDimitry Andric }
15481ad6265SDimitry Andric 
15581ad6265SDimitry Andric const DirectXSubtarget *
15681ad6265SDimitry Andric DirectXTargetMachine::getSubtargetImpl(const Function &) const {
15781ad6265SDimitry Andric   return Subtarget.get();
15881ad6265SDimitry Andric }
15981ad6265SDimitry Andric 
16081ad6265SDimitry Andric TargetTransformInfo
16181ad6265SDimitry Andric DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
16281ad6265SDimitry Andric   return TargetTransformInfo(DirectXTTIImpl(this, F));
16381ad6265SDimitry Andric }
16481ad6265SDimitry Andric 
16581ad6265SDimitry Andric DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
16681ad6265SDimitry Andric                                              const DirectXSubtarget &STI)
16781ad6265SDimitry Andric     : TargetLowering(TM) {}
168