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