1 //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains DirectX target initializer. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "DirectXTargetMachine.h" 15 #include "DXILResourceAnalysis.h" 16 #include "DXILShaderFlags.h" 17 #include "DXILWriter/DXILWriterPass.h" 18 #include "DirectX.h" 19 #include "DirectXSubtarget.h" 20 #include "DirectXTargetTransformInfo.h" 21 #include "TargetInfo/DirectXTargetInfo.h" 22 #include "llvm/CodeGen/MachineModuleInfo.h" 23 #include "llvm/CodeGen/Passes.h" 24 #include "llvm/CodeGen/TargetPassConfig.h" 25 #include "llvm/IR/IRPrintingPasses.h" 26 #include "llvm/IR/LegacyPassManager.h" 27 #include "llvm/MC/MCSectionDXContainer.h" 28 #include "llvm/MC/SectionKind.h" 29 #include "llvm/MC/TargetRegistry.h" 30 #include "llvm/Passes/PassBuilder.h" 31 #include "llvm/Support/CodeGen.h" 32 #include "llvm/Support/Compiler.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Target/TargetLoweringObjectFile.h" 35 #include <optional> 36 37 using namespace llvm; 38 39 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { 40 RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget()); 41 auto *PR = PassRegistry::getPassRegistry(); 42 initializeDXILIntrinsicExpansionLegacyPass(*PR); 43 initializeDXILPrepareModulePass(*PR); 44 initializeEmbedDXILPassPass(*PR); 45 initializeWriteDXILPassPass(*PR); 46 initializeDXContainerGlobalsPass(*PR); 47 initializeDXILOpLoweringLegacyPass(*PR); 48 initializeDXILTranslateMetadataPass(*PR); 49 initializeDXILResourceWrapperPass(*PR); 50 initializeShaderFlagsAnalysisWrapperPass(*PR); 51 } 52 53 class DXILTargetObjectFile : public TargetLoweringObjectFile { 54 public: 55 DXILTargetObjectFile() = default; 56 57 MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, 58 const TargetMachine &TM) const override { 59 return getContext().getDXContainerSection(GO->getSection(), Kind); 60 } 61 62 protected: 63 MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, 64 const TargetMachine &TM) const override { 65 llvm_unreachable("Not supported!"); 66 } 67 }; 68 69 class DirectXPassConfig : public TargetPassConfig { 70 public: 71 DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM) 72 : TargetPassConfig(TM, PM) {} 73 74 DirectXTargetMachine &getDirectXTargetMachine() const { 75 return getTM<DirectXTargetMachine>(); 76 } 77 78 FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; } 79 void addCodeGenPrepare() override { 80 addPass(createDXILIntrinsicExpansionLegacyPass()); 81 addPass(createDXILOpLoweringLegacyPass()); 82 addPass(createDXILTranslateMetadataPass()); 83 addPass(createDXILPrepareModulePass()); 84 } 85 }; 86 87 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT, 88 StringRef CPU, StringRef FS, 89 const TargetOptions &Options, 90 std::optional<Reloc::Model> RM, 91 std::optional<CodeModel::Model> CM, 92 CodeGenOptLevel OL, bool JIT) 93 : LLVMTargetMachine(T, 94 "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-" 95 "f32:32-f64:64-n8:16:32:64", 96 TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, 97 OL), 98 TLOF(std::make_unique<DXILTargetObjectFile>()), 99 Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) { 100 initAsmInfo(); 101 } 102 103 DirectXTargetMachine::~DirectXTargetMachine() {} 104 105 void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { 106 #define GET_PASS_REGISTRY "DirectXPassRegistry.def" 107 #include "llvm/Passes/TargetPassRegistry.inc" 108 } 109 110 bool DirectXTargetMachine::addPassesToEmitFile( 111 PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, 112 CodeGenFileType FileType, bool DisableVerify, 113 MachineModuleInfoWrapperPass *MMIWP) { 114 TargetPassConfig *PassConfig = createPassConfig(PM); 115 PassConfig->addCodeGenPrepare(); 116 117 switch (FileType) { 118 case CodeGenFileType::AssemblyFile: 119 PM.add(createDXILPrettyPrinterPass(Out)); 120 PM.add(createPrintModulePass(Out, "", true)); 121 break; 122 case CodeGenFileType::ObjectFile: 123 if (TargetPassConfig::willCompleteCodeGenPipeline()) { 124 PM.add(createDXILEmbedderPass()); 125 // We embed the other DXContainer globals after embedding DXIL so that the 126 // globals don't pollute the DXIL. 127 PM.add(createDXContainerGlobalsPass()); 128 129 if (!MMIWP) 130 MMIWP = new MachineModuleInfoWrapperPass(this); 131 PM.add(MMIWP); 132 if (addAsmPrinter(PM, Out, DwoOut, FileType, 133 MMIWP->getMMI().getContext())) 134 return true; 135 } else 136 PM.add(createDXILWriterPass(Out)); 137 break; 138 case CodeGenFileType::Null: 139 break; 140 } 141 return false; 142 } 143 144 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM, 145 MCContext *&Ctx, 146 raw_pwrite_stream &Out, 147 bool DisableVerify) { 148 return true; 149 } 150 151 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) { 152 return new DirectXPassConfig(*this, PM); 153 } 154 155 const DirectXSubtarget * 156 DirectXTargetMachine::getSubtargetImpl(const Function &) const { 157 return Subtarget.get(); 158 } 159 160 TargetTransformInfo 161 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const { 162 return TargetTransformInfo(DirectXTTIImpl(this, F)); 163 } 164 165 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM, 166 const DirectXSubtarget &STI) 167 : TargetLowering(TM) {} 168