xref: /llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision bfd05102d817fce38938ce864f89ad90ef0b6cda)
144a14a6aSChris Bieneman //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===//
244a14a6aSChris Bieneman //
344a14a6aSChris Bieneman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
444a14a6aSChris Bieneman // See https://llvm.org/LICENSE.txt for license information.
544a14a6aSChris Bieneman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
644a14a6aSChris Bieneman //
744a14a6aSChris Bieneman //===----------------------------------------------------------------------===//
844a14a6aSChris Bieneman ///
944a14a6aSChris Bieneman /// \file
1044a14a6aSChris Bieneman /// This file contains DirectX target initializer.
1144a14a6aSChris Bieneman ///
1244a14a6aSChris Bieneman //===----------------------------------------------------------------------===//
1344a14a6aSChris Bieneman 
1444a14a6aSChris Bieneman #include "DirectXTargetMachine.h"
151bc9b67bSMatt Arsenault #include "DXILDataScalarization.h"
165ac624c8SFarzon Lotfi #include "DXILFlattenArrays.h"
1781ee3855SJustin Bogner #include "DXILIntrinsicExpansion.h"
1881ee3855SJustin Bogner #include "DXILOpLowering.h"
1981ee3855SJustin Bogner #include "DXILPrettyPrinter.h"
200fca76d5SJustin Bogner #include "DXILResourceAccess.h"
2122018555SXiang Li #include "DXILResourceAnalysis.h"
222b2afb25SChris Bieneman #include "DXILShaderFlags.h"
2381ee3855SJustin Bogner #include "DXILTranslateMetadata.h"
24f2526c1aSChris Bieneman #include "DXILWriter/DXILWriterPass.h"
256599fdabSChris Bieneman #include "DirectX.h"
2644a14a6aSChris Bieneman #include "DirectXSubtarget.h"
2744a14a6aSChris Bieneman #include "DirectXTargetTransformInfo.h"
2844a14a6aSChris Bieneman #include "TargetInfo/DirectXTargetInfo.h"
292af61e62SChris Bieneman #include "llvm/CodeGen/MachineModuleInfo.h"
3044a14a6aSChris Bieneman #include "llvm/CodeGen/Passes.h"
3144a14a6aSChris Bieneman #include "llvm/CodeGen/TargetPassConfig.h"
328f0cd7c1SXiang Li #include "llvm/IR/IRPrintingPasses.h"
3344a14a6aSChris Bieneman #include "llvm/IR/LegacyPassManager.h"
34c05e29bfSFarzon Lotfi #include "llvm/InitializePasses.h"
352af61e62SChris Bieneman #include "llvm/MC/MCSectionDXContainer.h"
3644a14a6aSChris Bieneman #include "llvm/MC/SectionKind.h"
3744a14a6aSChris Bieneman #include "llvm/MC/TargetRegistry.h"
3822018555SXiang Li #include "llvm/Passes/PassBuilder.h"
3944a14a6aSChris Bieneman #include "llvm/Support/CodeGen.h"
4044a14a6aSChris Bieneman #include "llvm/Support/Compiler.h"
4144a14a6aSChris Bieneman #include "llvm/Support/ErrorHandling.h"
4244a14a6aSChris Bieneman #include "llvm/Target/TargetLoweringObjectFile.h"
43c05e29bfSFarzon Lotfi #include "llvm/Transforms/Scalar/Scalarizer.h"
448c7c20f0SKrzysztof Parzyszek #include <optional>
4544a14a6aSChris Bieneman 
4644a14a6aSChris Bieneman using namespace llvm;
4744a14a6aSChris Bieneman 
4844a14a6aSChris Bieneman extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
4944a14a6aSChris Bieneman   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
506599fdabSChris Bieneman   auto *PR = PassRegistry::getPassRegistry();
51de1a97dbSFarzon Lotfi   initializeDXILIntrinsicExpansionLegacyPass(*PR);
52324bdd66SFarzon Lotfi   initializeDXILDataScalarizationLegacyPass(*PR);
535ac624c8SFarzon Lotfi   initializeDXILFlattenArraysLegacyPass(*PR);
54c05e29bfSFarzon Lotfi   initializeScalarizerLegacyPassPass(*PR);
556599fdabSChris Bieneman   initializeDXILPrepareModulePass(*PR);
56d401a993SChris Bieneman   initializeEmbedDXILPassPass(*PR);
57e3becfacSXiang Li   initializeWriteDXILPassPass(*PR);
5872017fcfSJustin Bogner   initializeDXContainerGlobalsPass(*PR);
5985285be9SXiang Li   initializeDXILOpLoweringLegacyPass(*PR);
600fca76d5SJustin Bogner   initializeDXILResourceAccessLegacyPass(*PR);
6181ee3855SJustin Bogner   initializeDXILTranslateMetadataLegacyPass(*PR);
621c5f6cfcSJustin Bogner   initializeDXILResourceMDWrapperPass(*PR);
636e05c8dfSChris Bieneman   initializeShaderFlagsAnalysisWrapperPass(*PR);
64db279c72SHelena Kotas   initializeDXILFinalizeLinkageLegacyPass(*PR);
6544a14a6aSChris Bieneman }
6644a14a6aSChris Bieneman 
6744a14a6aSChris Bieneman class DXILTargetObjectFile : public TargetLoweringObjectFile {
6844a14a6aSChris Bieneman public:
6944a14a6aSChris Bieneman   DXILTargetObjectFile() = default;
7044a14a6aSChris Bieneman 
7144a14a6aSChris Bieneman   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
7244a14a6aSChris Bieneman                                       const TargetMachine &TM) const override {
732af61e62SChris Bieneman     return getContext().getDXContainerSection(GO->getSection(), Kind);
7444a14a6aSChris Bieneman   }
7544a14a6aSChris Bieneman 
7644a14a6aSChris Bieneman protected:
7744a14a6aSChris Bieneman   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
7844a14a6aSChris Bieneman                                     const TargetMachine &TM) const override {
7944a14a6aSChris Bieneman     llvm_unreachable("Not supported!");
8044a14a6aSChris Bieneman   }
8144a14a6aSChris Bieneman };
8244a14a6aSChris Bieneman 
8344a14a6aSChris Bieneman class DirectXPassConfig : public TargetPassConfig {
8444a14a6aSChris Bieneman public:
8544a14a6aSChris Bieneman   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
8644a14a6aSChris Bieneman       : TargetPassConfig(TM, PM) {}
8744a14a6aSChris Bieneman 
8844a14a6aSChris Bieneman   DirectXTargetMachine &getDirectXTargetMachine() const {
8944a14a6aSChris Bieneman     return getTM<DirectXTargetMachine>();
9044a14a6aSChris Bieneman   }
9144a14a6aSChris Bieneman 
9244a14a6aSChris Bieneman   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
9320f7f9b7SXiang Li   void addCodeGenPrepare() override {
9493d2a2caSJustin Bogner     addPass(createDXILFinalizeLinkageLegacyPass());
95de1a97dbSFarzon Lotfi     addPass(createDXILIntrinsicExpansionLegacyPass());
96324bdd66SFarzon Lotfi     addPass(createDXILDataScalarizationLegacyPass());
970fca76d5SJustin Bogner     addPass(createDXILFlattenArraysLegacyPass());
980fca76d5SJustin Bogner     addPass(createDXILResourceAccessLegacyPass());
99c05e29bfSFarzon Lotfi     ScalarizerPassOptions DxilScalarOptions;
100c05e29bfSFarzon Lotfi     DxilScalarOptions.ScalarizeLoadStore = true;
101c05e29bfSFarzon Lotfi     addPass(createScalarizerPass(DxilScalarOptions));
10281ee3855SJustin Bogner     addPass(createDXILTranslateMetadataLegacyPass());
103*bfd05102SJustin Bogner     addPass(createDXILOpLoweringLegacyPass());
1045e9dd882SXiang Li     addPass(createDXILPrepareModulePass());
10520f7f9b7SXiang Li   }
10644a14a6aSChris Bieneman };
10744a14a6aSChris Bieneman 
10844a14a6aSChris Bieneman DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
10944a14a6aSChris Bieneman                                            StringRef CPU, StringRef FS,
11044a14a6aSChris Bieneman                                            const TargetOptions &Options,
111bac97427SFangrui Song                                            std::optional<Reloc::Model> RM,
1128c7c20f0SKrzysztof Parzyszek                                            std::optional<CodeModel::Model> CM,
1130a1aa6cdSArthur Eubanks                                            CodeGenOptLevel OL, bool JIT)
114eec21cceSMatin Raayai     : CodeGenTargetMachineImpl(
115bb3f5e1fSMatin Raayai           T,
11644a14a6aSChris Bieneman           "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
11744a14a6aSChris Bieneman           "f32:32-f64:64-n8:16:32:64",
118bb3f5e1fSMatin Raayai           TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, OL),
11944a14a6aSChris Bieneman       TLOF(std::make_unique<DXILTargetObjectFile>()),
1202af61e62SChris Bieneman       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
1212af61e62SChris Bieneman   initAsmInfo();
1222af61e62SChris Bieneman }
12344a14a6aSChris Bieneman 
12444a14a6aSChris Bieneman DirectXTargetMachine::~DirectXTargetMachine() {}
12544a14a6aSChris Bieneman 
1265cd0ba30SNikita Popov void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
12776fdb590Spaperchalice #define GET_PASS_REGISTRY "DirectXPassRegistry.def"
12876fdb590Spaperchalice #include "llvm/Passes/TargetPassRegistry.inc"
12922018555SXiang Li }
13022018555SXiang Li 
13144a14a6aSChris Bieneman bool DirectXTargetMachine::addPassesToEmitFile(
13244a14a6aSChris Bieneman     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
13344a14a6aSChris Bieneman     CodeGenFileType FileType, bool DisableVerify,
13444a14a6aSChris Bieneman     MachineModuleInfoWrapperPass *MMIWP) {
13520f7f9b7SXiang Li   TargetPassConfig *PassConfig = createPassConfig(PM);
13620f7f9b7SXiang Li   PassConfig->addCodeGenPrepare();
13720f7f9b7SXiang Li 
1382af61e62SChris Bieneman   switch (FileType) {
1390a1aa6cdSArthur Eubanks   case CodeGenFileType::AssemblyFile:
14081ee3855SJustin Bogner     PM.add(createDXILPrettyPrinterLegacyPass(Out));
14144a14a6aSChris Bieneman     PM.add(createPrintModulePass(Out, "", true));
14244a14a6aSChris Bieneman     break;
1430a1aa6cdSArthur Eubanks   case CodeGenFileType::ObjectFile:
1442af61e62SChris Bieneman     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
14572017fcfSJustin Bogner       PM.add(createDXILEmbedderPass());
14672017fcfSJustin Bogner       // We embed the other DXContainer globals after embedding DXIL so that the
14772017fcfSJustin Bogner       // globals don't pollute the DXIL.
14872017fcfSJustin Bogner       PM.add(createDXContainerGlobalsPass());
14972017fcfSJustin Bogner 
1502af61e62SChris Bieneman       if (!MMIWP)
1512af61e62SChris Bieneman         MMIWP = new MachineModuleInfoWrapperPass(this);
1522af61e62SChris Bieneman       PM.add(MMIWP);
1532af61e62SChris Bieneman       if (addAsmPrinter(PM, Out, DwoOut, FileType,
1542af61e62SChris Bieneman                         MMIWP->getMMI().getContext()))
1552af61e62SChris Bieneman         return true;
1562af61e62SChris Bieneman     } else
157f2526c1aSChris Bieneman       PM.add(createDXILWriterPass(Out));
15844a14a6aSChris Bieneman     break;
1590a1aa6cdSArthur Eubanks   case CodeGenFileType::Null:
16044a14a6aSChris Bieneman     break;
16144a14a6aSChris Bieneman   }
16244a14a6aSChris Bieneman   return false;
16344a14a6aSChris Bieneman }
16444a14a6aSChris Bieneman 
16544a14a6aSChris Bieneman bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
16644a14a6aSChris Bieneman                                              MCContext *&Ctx,
16744a14a6aSChris Bieneman                                              raw_pwrite_stream &Out,
16844a14a6aSChris Bieneman                                              bool DisableVerify) {
16944a14a6aSChris Bieneman   return true;
17044a14a6aSChris Bieneman }
17144a14a6aSChris Bieneman 
17244a14a6aSChris Bieneman TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
17344a14a6aSChris Bieneman   return new DirectXPassConfig(*this, PM);
17444a14a6aSChris Bieneman }
17544a14a6aSChris Bieneman 
17644a14a6aSChris Bieneman const DirectXSubtarget *
17744a14a6aSChris Bieneman DirectXTargetMachine::getSubtargetImpl(const Function &) const {
17844a14a6aSChris Bieneman   return Subtarget.get();
17944a14a6aSChris Bieneman }
18044a14a6aSChris Bieneman 
18144a14a6aSChris Bieneman TargetTransformInfo
18244a14a6aSChris Bieneman DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
18344a14a6aSChris Bieneman   return TargetTransformInfo(DirectXTTIImpl(this, F));
18444a14a6aSChris Bieneman }
18544a14a6aSChris Bieneman 
18644a14a6aSChris Bieneman DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
18744a14a6aSChris Bieneman                                              const DirectXSubtarget &STI)
18844a14a6aSChris Bieneman     : TargetLowering(TM) {}
189