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