181ad6265SDimitry Andric //===- DirectXTargetMachine.cpp - DirectX Target Implementation -*- C++ -*-===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric ///
981ad6265SDimitry Andric /// \file
1081ad6265SDimitry Andric /// This file contains DirectX target initializer.
1181ad6265SDimitry Andric ///
1281ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1381ad6265SDimitry Andric
1481ad6265SDimitry Andric #include "DirectXTargetMachine.h"
15bdd1243dSDimitry Andric #include "DXILResourceAnalysis.h"
16bdd1243dSDimitry Andric #include "DXILShaderFlags.h"
1781ad6265SDimitry Andric #include "DXILWriter/DXILWriterPass.h"
1881ad6265SDimitry Andric #include "DirectX.h"
1981ad6265SDimitry Andric #include "DirectXSubtarget.h"
2081ad6265SDimitry Andric #include "DirectXTargetTransformInfo.h"
2181ad6265SDimitry Andric #include "TargetInfo/DirectXTargetInfo.h"
2281ad6265SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
2381ad6265SDimitry Andric #include "llvm/CodeGen/Passes.h"
2481ad6265SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
2581ad6265SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
2681ad6265SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
2781ad6265SDimitry Andric #include "llvm/MC/MCSectionDXContainer.h"
2881ad6265SDimitry Andric #include "llvm/MC/SectionKind.h"
2981ad6265SDimitry Andric #include "llvm/MC/TargetRegistry.h"
30bdd1243dSDimitry Andric #include "llvm/Passes/PassBuilder.h"
3181ad6265SDimitry Andric #include "llvm/Support/CodeGen.h"
3281ad6265SDimitry Andric #include "llvm/Support/Compiler.h"
3381ad6265SDimitry Andric #include "llvm/Support/ErrorHandling.h"
3481ad6265SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
35bdd1243dSDimitry Andric #include <optional>
3681ad6265SDimitry Andric
3781ad6265SDimitry Andric using namespace llvm;
3881ad6265SDimitry Andric
LLVMInitializeDirectXTarget()3981ad6265SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
4081ad6265SDimitry Andric RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
4181ad6265SDimitry Andric auto *PR = PassRegistry::getPassRegistry();
42*0fca6ea1SDimitry Andric initializeDXILIntrinsicExpansionLegacyPass(*PR);
4381ad6265SDimitry Andric initializeDXILPrepareModulePass(*PR);
4481ad6265SDimitry Andric initializeEmbedDXILPassPass(*PR);
45bdd1243dSDimitry Andric initializeWriteDXILPassPass(*PR);
465f757f3fSDimitry Andric initializeDXContainerGlobalsPass(*PR);
4781ad6265SDimitry Andric initializeDXILOpLoweringLegacyPass(*PR);
4881ad6265SDimitry Andric initializeDXILTranslateMetadataPass(*PR);
49bdd1243dSDimitry Andric initializeDXILResourceWrapperPass(*PR);
50bdd1243dSDimitry Andric initializeShaderFlagsAnalysisWrapperPass(*PR);
5181ad6265SDimitry Andric }
5281ad6265SDimitry Andric
5381ad6265SDimitry Andric class DXILTargetObjectFile : public TargetLoweringObjectFile {
5481ad6265SDimitry Andric public:
5581ad6265SDimitry Andric DXILTargetObjectFile() = default;
5681ad6265SDimitry Andric
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const5781ad6265SDimitry Andric MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
5881ad6265SDimitry Andric const TargetMachine &TM) const override {
5981ad6265SDimitry Andric return getContext().getDXContainerSection(GO->getSection(), Kind);
6081ad6265SDimitry Andric }
6181ad6265SDimitry Andric
6281ad6265SDimitry Andric protected:
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const6381ad6265SDimitry Andric MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
6481ad6265SDimitry Andric const TargetMachine &TM) const override {
6581ad6265SDimitry Andric llvm_unreachable("Not supported!");
6681ad6265SDimitry Andric }
6781ad6265SDimitry Andric };
6881ad6265SDimitry Andric
6981ad6265SDimitry Andric class DirectXPassConfig : public TargetPassConfig {
7081ad6265SDimitry Andric public:
DirectXPassConfig(DirectXTargetMachine & TM,PassManagerBase & PM)7181ad6265SDimitry Andric DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
7281ad6265SDimitry Andric : TargetPassConfig(TM, PM) {}
7381ad6265SDimitry Andric
getDirectXTargetMachine() const7481ad6265SDimitry Andric DirectXTargetMachine &getDirectXTargetMachine() const {
7581ad6265SDimitry Andric return getTM<DirectXTargetMachine>();
7681ad6265SDimitry Andric }
7781ad6265SDimitry Andric
createTargetRegisterAllocator(bool)7881ad6265SDimitry Andric FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
addCodeGenPrepare()79bdd1243dSDimitry Andric void addCodeGenPrepare() override {
80*0fca6ea1SDimitry Andric addPass(createDXILIntrinsicExpansionLegacyPass());
81bdd1243dSDimitry Andric addPass(createDXILOpLoweringLegacyPass());
82bdd1243dSDimitry Andric addPass(createDXILTranslateMetadataPass());
83*0fca6ea1SDimitry Andric addPass(createDXILPrepareModulePass());
84bdd1243dSDimitry Andric }
8581ad6265SDimitry Andric };
8681ad6265SDimitry Andric
DirectXTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,std::optional<Reloc::Model> RM,std::optional<CodeModel::Model> CM,CodeGenOptLevel OL,bool JIT)8781ad6265SDimitry Andric DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
8881ad6265SDimitry Andric StringRef CPU, StringRef FS,
8981ad6265SDimitry Andric const TargetOptions &Options,
90bdd1243dSDimitry Andric std::optional<Reloc::Model> RM,
91bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM,
925f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT)
9381ad6265SDimitry Andric : LLVMTargetMachine(T,
9481ad6265SDimitry Andric "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
9581ad6265SDimitry Andric "f32:32-f64:64-n8:16:32:64",
9681ad6265SDimitry Andric TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
9781ad6265SDimitry Andric OL),
9881ad6265SDimitry Andric TLOF(std::make_unique<DXILTargetObjectFile>()),
9981ad6265SDimitry Andric Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
10081ad6265SDimitry Andric initAsmInfo();
10181ad6265SDimitry Andric }
10281ad6265SDimitry Andric
~DirectXTargetMachine()10381ad6265SDimitry Andric DirectXTargetMachine::~DirectXTargetMachine() {}
10481ad6265SDimitry Andric
registerPassBuilderCallbacks(PassBuilder & PB)105*0fca6ea1SDimitry Andric void DirectXTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
106*0fca6ea1SDimitry Andric #define GET_PASS_REGISTRY "DirectXPassRegistry.def"
107*0fca6ea1SDimitry Andric #include "llvm/Passes/TargetPassRegistry.inc"
108bdd1243dSDimitry Andric }
109bdd1243dSDimitry Andric
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)11081ad6265SDimitry Andric bool DirectXTargetMachine::addPassesToEmitFile(
11181ad6265SDimitry Andric PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
11281ad6265SDimitry Andric CodeGenFileType FileType, bool DisableVerify,
11381ad6265SDimitry Andric MachineModuleInfoWrapperPass *MMIWP) {
114bdd1243dSDimitry Andric TargetPassConfig *PassConfig = createPassConfig(PM);
115bdd1243dSDimitry Andric PassConfig->addCodeGenPrepare();
116bdd1243dSDimitry Andric
1175f757f3fSDimitry Andric switch (FileType) {
1185f757f3fSDimitry Andric case CodeGenFileType::AssemblyFile:
1195f757f3fSDimitry Andric PM.add(createDXILPrettyPrinterPass(Out));
1205f757f3fSDimitry Andric PM.add(createPrintModulePass(Out, "", true));
1215f757f3fSDimitry Andric break;
1225f757f3fSDimitry Andric case CodeGenFileType::ObjectFile:
12381ad6265SDimitry Andric if (TargetPassConfig::willCompleteCodeGenPipeline()) {
12481ad6265SDimitry Andric PM.add(createDXILEmbedderPass());
125bdd1243dSDimitry Andric // We embed the other DXContainer globals after embedding DXIL so that the
126bdd1243dSDimitry Andric // globals don't pollute the DXIL.
127bdd1243dSDimitry Andric PM.add(createDXContainerGlobalsPass());
1285f757f3fSDimitry Andric
12981ad6265SDimitry Andric if (!MMIWP)
13081ad6265SDimitry Andric MMIWP = new MachineModuleInfoWrapperPass(this);
13181ad6265SDimitry Andric PM.add(MMIWP);
13281ad6265SDimitry Andric if (addAsmPrinter(PM, Out, DwoOut, FileType,
13381ad6265SDimitry Andric MMIWP->getMMI().getContext()))
13481ad6265SDimitry Andric return true;
13581ad6265SDimitry Andric } else
13681ad6265SDimitry Andric PM.add(createDXILWriterPass(Out));
13781ad6265SDimitry Andric break;
1385f757f3fSDimitry Andric case CodeGenFileType::Null:
13981ad6265SDimitry Andric break;
14081ad6265SDimitry Andric }
14181ad6265SDimitry Andric return false;
14281ad6265SDimitry Andric }
14381ad6265SDimitry Andric
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)14481ad6265SDimitry Andric bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
14581ad6265SDimitry Andric MCContext *&Ctx,
14681ad6265SDimitry Andric raw_pwrite_stream &Out,
14781ad6265SDimitry Andric bool DisableVerify) {
14881ad6265SDimitry Andric return true;
14981ad6265SDimitry Andric }
15081ad6265SDimitry Andric
createPassConfig(PassManagerBase & PM)15181ad6265SDimitry Andric TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
15281ad6265SDimitry Andric return new DirectXPassConfig(*this, PM);
15381ad6265SDimitry Andric }
15481ad6265SDimitry Andric
15581ad6265SDimitry Andric const DirectXSubtarget *
getSubtargetImpl(const Function &) const15681ad6265SDimitry Andric DirectXTargetMachine::getSubtargetImpl(const Function &) const {
15781ad6265SDimitry Andric return Subtarget.get();
15881ad6265SDimitry Andric }
15981ad6265SDimitry Andric
16081ad6265SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F) const16181ad6265SDimitry Andric DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
16281ad6265SDimitry Andric return TargetTransformInfo(DirectXTTIImpl(this, F));
16381ad6265SDimitry Andric }
16481ad6265SDimitry Andric
DirectXTargetLowering(const DirectXTargetMachine & TM,const DirectXSubtarget & STI)16581ad6265SDimitry Andric DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
16681ad6265SDimitry Andric const DirectXSubtarget &STI)
16781ad6265SDimitry Andric : TargetLowering(TM) {}
168