xref: /llvm-project/llvm/lib/Target/DirectX/DirectXTargetMachine.cpp (revision 220185552f4484155b2893a1568f5d71c23a33cf)
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