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