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