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 "DXILWriter/DXILWriterPass.h" 17 #include "DirectX.h" 18 #include "DirectXSubtarget.h" 19 #include "DirectXTargetTransformInfo.h" 20 #include "TargetInfo/DirectXTargetInfo.h" 21 #include "llvm/CodeGen/MachineModuleInfo.h" 22 #include "llvm/CodeGen/Passes.h" 23 #include "llvm/CodeGen/TargetPassConfig.h" 24 #include "llvm/IR/IRPrintingPasses.h" 25 #include "llvm/IR/LegacyPassManager.h" 26 #include "llvm/MC/MCSectionDXContainer.h" 27 #include "llvm/MC/SectionKind.h" 28 #include "llvm/MC/TargetRegistry.h" 29 #include "llvm/Passes/PassBuilder.h" 30 #include "llvm/Support/CodeGen.h" 31 #include "llvm/Support/Compiler.h" 32 #include "llvm/Support/ErrorHandling.h" 33 #include "llvm/Target/TargetLoweringObjectFile.h" 34 35 using namespace llvm; 36 37 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { 38 RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget()); 39 auto *PR = PassRegistry::getPassRegistry(); 40 initializeDXILPrepareModulePass(*PR); 41 initializeEmbedDXILPassPass(*PR); 42 initializeDXILOpLoweringLegacyPass(*PR); 43 initializeDXILTranslateMetadataPass(*PR); 44 initializeDXILResourceWrapperPass(*PR); 45 } 46 47 class DXILTargetObjectFile : public TargetLoweringObjectFile { 48 public: 49 DXILTargetObjectFile() = default; 50 51 MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, 52 const TargetMachine &TM) const override { 53 return getContext().getDXContainerSection(GO->getSection(), Kind); 54 } 55 56 protected: 57 MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, 58 const TargetMachine &TM) const override { 59 llvm_unreachable("Not supported!"); 60 } 61 }; 62 63 class DirectXPassConfig : public TargetPassConfig { 64 public: 65 DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM) 66 : TargetPassConfig(TM, PM) {} 67 68 DirectXTargetMachine &getDirectXTargetMachine() const { 69 return getTM<DirectXTargetMachine>(); 70 } 71 72 FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; } 73 void addCodeGenPrepare() override { 74 addPass(createDXILOpLoweringLegacyPass()); 75 addPass(createDXILPrepareModulePass()); 76 addPass(createDXILTranslateMetadataPass()); 77 } 78 }; 79 80 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT, 81 StringRef CPU, StringRef FS, 82 const TargetOptions &Options, 83 Optional<Reloc::Model> RM, 84 Optional<CodeModel::Model> CM, 85 CodeGenOpt::Level OL, bool JIT) 86 : LLVMTargetMachine(T, 87 "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-" 88 "f32:32-f64:64-n8:16:32:64", 89 TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, 90 OL), 91 TLOF(std::make_unique<DXILTargetObjectFile>()), 92 Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) { 93 initAsmInfo(); 94 } 95 96 DirectXTargetMachine::~DirectXTargetMachine() {} 97 98 void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { 99 PB.registerPipelineParsingCallback( 100 [](StringRef PassName, ModulePassManager &PM, 101 ArrayRef<PassBuilder::PipelineElement>) { 102 if (PassName == "print-dxil-resource") { 103 PM.addPass(DXILResourcePrinterPass(dbgs())); 104 return true; 105 } 106 return false; 107 }); 108 109 PB.registerAnalysisRegistrationCallback([](ModuleAnalysisManager &MAM) { 110 MAM.registerPass([&] { return DXILResourceAnalysis(); }); 111 }); 112 } 113 114 bool DirectXTargetMachine::addPassesToEmitFile( 115 PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, 116 CodeGenFileType FileType, bool DisableVerify, 117 MachineModuleInfoWrapperPass *MMIWP) { 118 TargetPassConfig *PassConfig = createPassConfig(PM); 119 PassConfig->addCodeGenPrepare(); 120 121 if (TargetPassConfig::willCompleteCodeGenPipeline()) { 122 PM.add(createDXILEmbedderPass()); 123 } 124 switch (FileType) { 125 case CGFT_AssemblyFile: 126 PM.add(createPrintModulePass(Out, "", true)); 127 break; 128 case CGFT_ObjectFile: 129 if (TargetPassConfig::willCompleteCodeGenPipeline()) { 130 if (!MMIWP) 131 MMIWP = new MachineModuleInfoWrapperPass(this); 132 PM.add(MMIWP); 133 if (addAsmPrinter(PM, Out, DwoOut, FileType, 134 MMIWP->getMMI().getContext())) 135 return true; 136 } else 137 PM.add(createDXILWriterPass(Out)); 138 break; 139 case CGFT_Null: 140 break; 141 } 142 return false; 143 } 144 145 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM, 146 MCContext *&Ctx, 147 raw_pwrite_stream &Out, 148 bool DisableVerify) { 149 return true; 150 } 151 152 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) { 153 return new DirectXPassConfig(*this, PM); 154 } 155 156 const DirectXSubtarget * 157 DirectXTargetMachine::getSubtargetImpl(const Function &) const { 158 return Subtarget.get(); 159 } 160 161 TargetTransformInfo 162 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const { 163 return TargetTransformInfo(DirectXTTIImpl(this, F)); 164 } 165 166 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM, 167 const DirectXSubtarget &STI) 168 : TargetLowering(TM) {} 169