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 "DXILDataScalarization.h" 16 #include "DXILFlattenArrays.h" 17 #include "DXILIntrinsicExpansion.h" 18 #include "DXILOpLowering.h" 19 #include "DXILPrettyPrinter.h" 20 #include "DXILResourceAccess.h" 21 #include "DXILResourceAnalysis.h" 22 #include "DXILShaderFlags.h" 23 #include "DXILTranslateMetadata.h" 24 #include "DXILWriter/DXILWriterPass.h" 25 #include "DirectX.h" 26 #include "DirectXSubtarget.h" 27 #include "DirectXTargetTransformInfo.h" 28 #include "TargetInfo/DirectXTargetInfo.h" 29 #include "llvm/CodeGen/MachineModuleInfo.h" 30 #include "llvm/CodeGen/Passes.h" 31 #include "llvm/CodeGen/TargetPassConfig.h" 32 #include "llvm/IR/IRPrintingPasses.h" 33 #include "llvm/IR/LegacyPassManager.h" 34 #include "llvm/InitializePasses.h" 35 #include "llvm/MC/MCSectionDXContainer.h" 36 #include "llvm/MC/SectionKind.h" 37 #include "llvm/MC/TargetRegistry.h" 38 #include "llvm/Passes/PassBuilder.h" 39 #include "llvm/Support/CodeGen.h" 40 #include "llvm/Support/Compiler.h" 41 #include "llvm/Support/ErrorHandling.h" 42 #include "llvm/Target/TargetLoweringObjectFile.h" 43 #include "llvm/Transforms/Scalar/Scalarizer.h" 44 #include <optional> 45 46 using namespace llvm; 47 48 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() { 49 RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget()); 50 auto *PR = PassRegistry::getPassRegistry(); 51 initializeDXILIntrinsicExpansionLegacyPass(*PR); 52 initializeDXILDataScalarizationLegacyPass(*PR); 53 initializeDXILFlattenArraysLegacyPass(*PR); 54 initializeScalarizerLegacyPassPass(*PR); 55 initializeDXILPrepareModulePass(*PR); 56 initializeEmbedDXILPassPass(*PR); 57 initializeWriteDXILPassPass(*PR); 58 initializeDXContainerGlobalsPass(*PR); 59 initializeDXILOpLoweringLegacyPass(*PR); 60 initializeDXILResourceAccessLegacyPass(*PR); 61 initializeDXILTranslateMetadataLegacyPass(*PR); 62 initializeDXILResourceMDWrapperPass(*PR); 63 initializeShaderFlagsAnalysisWrapperPass(*PR); 64 initializeDXILFinalizeLinkageLegacyPass(*PR); 65 } 66 67 class DXILTargetObjectFile : public TargetLoweringObjectFile { 68 public: 69 DXILTargetObjectFile() = default; 70 71 MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind, 72 const TargetMachine &TM) const override { 73 return getContext().getDXContainerSection(GO->getSection(), Kind); 74 } 75 76 protected: 77 MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, 78 const TargetMachine &TM) const override { 79 llvm_unreachable("Not supported!"); 80 } 81 }; 82 83 class DirectXPassConfig : public TargetPassConfig { 84 public: 85 DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM) 86 : TargetPassConfig(TM, PM) {} 87 88 DirectXTargetMachine &getDirectXTargetMachine() const { 89 return getTM<DirectXTargetMachine>(); 90 } 91 92 FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; } 93 void addCodeGenPrepare() override { 94 addPass(createDXILFinalizeLinkageLegacyPass()); 95 addPass(createDXILIntrinsicExpansionLegacyPass()); 96 addPass(createDXILDataScalarizationLegacyPass()); 97 addPass(createDXILFlattenArraysLegacyPass()); 98 addPass(createDXILResourceAccessLegacyPass()); 99 ScalarizerPassOptions DxilScalarOptions; 100 DxilScalarOptions.ScalarizeLoadStore = true; 101 addPass(createScalarizerPass(DxilScalarOptions)); 102 addPass(createDXILTranslateMetadataLegacyPass()); 103 addPass(createDXILOpLoweringLegacyPass()); 104 addPass(createDXILPrepareModulePass()); 105 } 106 }; 107 108 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT, 109 StringRef CPU, StringRef FS, 110 const TargetOptions &Options, 111 std::optional<Reloc::Model> RM, 112 std::optional<CodeModel::Model> CM, 113 CodeGenOptLevel OL, bool JIT) 114 : CodeGenTargetMachineImpl( 115 T, 116 "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-" 117 "f32:32-f64:64-n8:16:32:64", 118 TT, CPU, FS, Options, Reloc::Static, CodeModel::Small, OL), 119 TLOF(std::make_unique<DXILTargetObjectFile>()), 120 Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) { 121 initAsmInfo(); 122 } 123 124 DirectXTargetMachine::~DirectXTargetMachine() {} 125 126 void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) { 127 #define GET_PASS_REGISTRY "DirectXPassRegistry.def" 128 #include "llvm/Passes/TargetPassRegistry.inc" 129 } 130 131 bool DirectXTargetMachine::addPassesToEmitFile( 132 PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, 133 CodeGenFileType FileType, bool DisableVerify, 134 MachineModuleInfoWrapperPass *MMIWP) { 135 TargetPassConfig *PassConfig = createPassConfig(PM); 136 PassConfig->addCodeGenPrepare(); 137 138 switch (FileType) { 139 case CodeGenFileType::AssemblyFile: 140 PM.add(createDXILPrettyPrinterLegacyPass(Out)); 141 PM.add(createPrintModulePass(Out, "", true)); 142 break; 143 case CodeGenFileType::ObjectFile: 144 if (TargetPassConfig::willCompleteCodeGenPipeline()) { 145 PM.add(createDXILEmbedderPass()); 146 // We embed the other DXContainer globals after embedding DXIL so that the 147 // globals don't pollute the DXIL. 148 PM.add(createDXContainerGlobalsPass()); 149 150 if (!MMIWP) 151 MMIWP = new MachineModuleInfoWrapperPass(this); 152 PM.add(MMIWP); 153 if (addAsmPrinter(PM, Out, DwoOut, FileType, 154 MMIWP->getMMI().getContext())) 155 return true; 156 } else 157 PM.add(createDXILWriterPass(Out)); 158 break; 159 case CodeGenFileType::Null: 160 break; 161 } 162 return false; 163 } 164 165 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM, 166 MCContext *&Ctx, 167 raw_pwrite_stream &Out, 168 bool DisableVerify) { 169 return true; 170 } 171 172 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) { 173 return new DirectXPassConfig(*this, PM); 174 } 175 176 const DirectXSubtarget * 177 DirectXTargetMachine::getSubtargetImpl(const Function &) const { 178 return Subtarget.get(); 179 } 180 181 TargetTransformInfo 182 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const { 183 return TargetTransformInfo(DirectXTTIImpl(this, F)); 184 } 185 186 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM, 187 const DirectXSubtarget &STI) 188 : TargetLowering(TM) {} 189