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 "DXILWriter/DXILWriterPass.h"
16 #include "DirectX.h"
17 #include "DirectXSubtarget.h"
18 #include "DirectXTargetTransformInfo.h"
19 #include "TargetInfo/DirectXTargetInfo.h"
20 #include "llvm/CodeGen/MachineModuleInfo.h"
21 #include "llvm/CodeGen/Passes.h"
22 #include "llvm/CodeGen/TargetPassConfig.h"
23 #include "llvm/IR/IRPrintingPasses.h"
24 #include "llvm/IR/LegacyPassManager.h"
25 #include "llvm/MC/MCSectionDXContainer.h"
26 #include "llvm/MC/SectionKind.h"
27 #include "llvm/MC/TargetRegistry.h"
28 #include "llvm/Support/CodeGen.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Target/TargetLoweringObjectFile.h"
32 
33 using namespace llvm;
34 
35 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeDirectXTarget() {
36   RegisterTargetMachine<DirectXTargetMachine> X(getTheDirectXTarget());
37   auto *PR = PassRegistry::getPassRegistry();
38   initializeDXILPrepareModulePass(*PR);
39   initializeEmbedDXILPassPass(*PR);
40   initializeDXILOpLoweringLegacyPass(*PR);
41   initializeDXILTranslateMetadataPass(*PR);
42 }
43 
44 class DXILTargetObjectFile : public TargetLoweringObjectFile {
45 public:
46   DXILTargetObjectFile() = default;
47 
48   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
49                                       const TargetMachine &TM) const override {
50     return getContext().getDXContainerSection(GO->getSection(), Kind);
51   }
52 
53 protected:
54   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
55                                     const TargetMachine &TM) const override {
56     llvm_unreachable("Not supported!");
57   }
58 };
59 
60 class DirectXPassConfig : public TargetPassConfig {
61 public:
62   DirectXPassConfig(DirectXTargetMachine &TM, PassManagerBase &PM)
63       : TargetPassConfig(TM, PM) {}
64 
65   DirectXTargetMachine &getDirectXTargetMachine() const {
66     return getTM<DirectXTargetMachine>();
67   }
68 
69   FunctionPass *createTargetRegisterAllocator(bool) override { return nullptr; }
70 };
71 
72 DirectXTargetMachine::DirectXTargetMachine(const Target &T, const Triple &TT,
73                                            StringRef CPU, StringRef FS,
74                                            const TargetOptions &Options,
75                                            Optional<Reloc::Model> RM,
76                                            Optional<CodeModel::Model> CM,
77                                            CodeGenOpt::Level OL, bool JIT)
78     : LLVMTargetMachine(T,
79                         "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-"
80                         "f32:32-f64:64-n8:16:32:64",
81                         TT, CPU, FS, Options, Reloc::Static, CodeModel::Small,
82                         OL),
83       TLOF(std::make_unique<DXILTargetObjectFile>()),
84       Subtarget(std::make_unique<DirectXSubtarget>(TT, CPU, FS, *this)) {
85   initAsmInfo();
86 }
87 
88 DirectXTargetMachine::~DirectXTargetMachine() {}
89 
90 bool DirectXTargetMachine::addPassesToEmitFile(
91     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
92     CodeGenFileType FileType, bool DisableVerify,
93     MachineModuleInfoWrapperPass *MMIWP) {
94   PM.add(createDXILOpLoweringLegacyPass());
95   PM.add(createDXILPrepareModulePass());
96   PM.add(createDXILTranslateMetadataPass());
97   if (TargetPassConfig::willCompleteCodeGenPipeline()) {
98     PM.add(createDXILEmbedderPass());
99   }
100   switch (FileType) {
101   case CGFT_AssemblyFile:
102     PM.add(createPrintModulePass(Out, "", true));
103     break;
104   case CGFT_ObjectFile:
105     if (TargetPassConfig::willCompleteCodeGenPipeline()) {
106       if (!MMIWP)
107         MMIWP = new MachineModuleInfoWrapperPass(this);
108       PM.add(MMIWP);
109       if (addAsmPrinter(PM, Out, DwoOut, FileType,
110                         MMIWP->getMMI().getContext()))
111         return true;
112     } else
113       PM.add(createDXILWriterPass(Out));
114     break;
115   case CGFT_Null:
116     break;
117   }
118   return false;
119 }
120 
121 bool DirectXTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
122                                              MCContext *&Ctx,
123                                              raw_pwrite_stream &Out,
124                                              bool DisableVerify) {
125   return true;
126 }
127 
128 TargetPassConfig *DirectXTargetMachine::createPassConfig(PassManagerBase &PM) {
129   return new DirectXPassConfig(*this, PM);
130 }
131 
132 const DirectXSubtarget *
133 DirectXTargetMachine::getSubtargetImpl(const Function &) const {
134   return Subtarget.get();
135 }
136 
137 TargetTransformInfo
138 DirectXTargetMachine::getTargetTransformInfo(const Function &F) const {
139   return TargetTransformInfo(DirectXTTIImpl(this, F));
140 }
141 
142 DirectXTargetLowering::DirectXTargetLowering(const DirectXTargetMachine &TM,
143                                              const DirectXSubtarget &STI)
144     : TargetLowering(TM) {}
145