| //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// This file contains DirectX target initializer. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #include "DirectXTargetMachine.h" |
| #include "DXILResourceAnalysis.h" |
| #include "DXILShaderFlags.h" |
| #include "DXILWriter/DXILWriterPass.h" |
| #include "DirectX.h" |
| #include "DirectXSubtarget.h" |
| #include "DirectXTargetTransformInfo.h" |
| #include "TargetInfo/DirectXTargetInfo.h" |
| #include "llvm/CodeGen/MachineModuleInfo.h" |
| #include "llvm/CodeGen/Passes.h" |
| #include "llvm/CodeGen/TargetPassConfig.h" |
| #include "llvm/IR/IRPrintingPasses.h" |
| #include "llvm/IR/LegacyPassManager.h" |
| #include "llvm/MC/MCSectionDXContainer.h" |
| #include "llvm/MC/SectionKind.h" |
| #include "llvm/MC/TargetRegistry.h" |
| #include "llvm/Passes/PassBuilder.h" |
| #include "llvm/Support/CodeGen.h" |
| #include "llvm/Support/Compiler.h" |
| #include "llvm/Support/ErrorHandling.h" |
| #include "llvm/Target/TargetLoweringObjectFile.h" |
| #include <optional> |
| |
| using namespace llvm; |
| |
| extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { |
| RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget()); |
| auto *PR = PassRegistry::getPassRegistry(); |
| initializeDXILPrepareModulePass(*PR); |
| initializeEmbedDXILPassPass(*PR); |
| initializeWriteDXILPassPass(*PR); |
| initializeDXILOpLoweringLegacyPass(*PR); |
| initializeDXILTranslateMetadataPass(*PR); |
| initializeDXILResourceWrapperPass(*PR); |
| initializeShaderFlagsAnalysisWrapperPass(*PR); |
| } |
| |
| class DXILTargetObjectFile : public TargetLoweringObjectFile { |
| public: |
| DXILTargetObjectFile() = default; |
| |
| MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, |
| const TargetMachine &TM) const override { |
| return getContext().getDXContainerSection(GO->getSection(), Kind); |
| } |
| |
| protected: |
| MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, |
| const TargetMachine &TM) const override { |
| llvm_unreachable("Not supported!"); |
| } |
| }; |
| |
| class DirectXPassConfig : public TargetPassConfig { |
| public: |
| DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM) |
| : TargetPassConfig(TM, PM) {} |
| |
| DirectXTargetMachine &getDirectXTargetMachine() const { |
| return getTM<DirectXTargetMachine>(); |
| } |
| |
| FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; } |
| void addCodeGenPrepare() override { |
| addPass(createDXILOpLoweringLegacyPass()); |
| addPass(createDXILPrepareModulePass()); |
| addPass(createDXILTranslateMetadataPass()); |
| } |
| }; |
| |
| DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT, |
| StringRef CPU, StringRef FS, |
| const TargetOptions &Options, |
| std::optional<Reloc::Model> RM, |
| std::optional<CodeModel::Model> CM, |
| CodeGenOpt::Level OL, bool JIT) |
| : LLVMTargetMachine(T, |
| "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-" |
| "f32:32-f64:64-n8:16:32:64", |
| TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, |
| OL), |
| TLOF(std::make_unique<DXILTargetObjectFile>()), |
| Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) { |
| initAsmInfo(); |
| } |
| |
| DirectXTargetMachine::~DirectXTargetMachine() {} |
| |
| void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { |
| PB.registerPipelineParsingCallback( |
| [](StringRef PassName, ModulePassManager &PM, |
| ArrayRef<PassBuilder::PipelineElement>) { |
| if (PassName == "print-dxil-resource") { |
| PM.addPass(DXILResourcePrinterPass(dbgs())); |
| return true; |
| } |
| if (PassName == "print-dx-shader-flags") { |
| PM.addPass(dxil::ShaderFlagsAnalysisPrinter(dbgs())); |
| return true; |
| } |
| return false; |
| }); |
| |
| PB.registerAnalysisRegistrationCallback([](ModuleAnalysisManager &MAM) { |
| MAM.registerPass([&] { return DXILResourceAnalysis(); }); |
| MAM.registerPass([&] { return dxil::ShaderFlagsAnalysis(); }); |
| }); |
| } |
| |
| bool DirectXTargetMachine::addPassesToEmitFile( |
| PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, |
| CodeGenFileType FileType, bool DisableVerify, |
| MachineModuleInfoWrapperPass *MMIWP) { |
| TargetPassConfig *PassConfig = createPassConfig(PM); |
| PassConfig->addCodeGenPrepare(); |
| |
| if (TargetPassConfig::willCompleteCodeGenPipeline()) { |
| PM.add(createDXILEmbedderPass()); |
| // We embed the other DXContainer globals after embedding DXIL so that the |
| // globals don't pollute the DXIL. |
| PM.add(createDXContainerGlobalsPass()); |
| } |
| switch (FileType) { |
| case CGFT_AssemblyFile: |
| PM.add(createDXILPrettyPrinterPass(Out)); |
| PM.add(createPrintModulePass(Out, "", true)); |
| break; |
| case CGFT_ObjectFile: |
| if (TargetPassConfig::willCompleteCodeGenPipeline()) { |
| if (!MMIWP) |
| MMIWP = new MachineModuleInfoWrapperPass(this); |
| PM.add(MMIWP); |
| if (addAsmPrinter(PM, Out, DwoOut, FileType, |
| MMIWP->getMMI().getContext())) |
| return true; |
| } else |
| PM.add(createDXILWriterPass(Out)); |
| break; |
| case CGFT_Null: |
| break; |
| } |
| return false; |
| } |
| |
| bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM, |
| MCContext *&Ctx, |
| raw_pwrite_stream &Out, |
| bool DisableVerify) { |
| return true; |
| } |
| |
| TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) { |
| return new DirectXPassConfig(*this, PM); |
| } |
| |
| const DirectXSubtarget * |
| DirectXTargetMachine::getSubtargetImpl(const Function &) const { |
| return Subtarget.get(); |
| } |
| |
| TargetTransformInfo |
| DirectXTargetMachine::getTargetTransformInfo(const Function &F) const { |
| return TargetTransformInfo(DirectXTTIImpl(this, F)); |
| } |
| |
| DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM, |
| const DirectXSubtarget &STI) |
| : TargetLowering(TM) {} |