1 //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
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 // This file implements the LLVMTargetMachine class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Analysis/Passes.h"
14 #include "llvm/CodeGen/AsmPrinter.h"
15 #include "llvm/CodeGen/BasicTTIImpl.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/CodeGen/Passes.h"
18 #include "llvm/CodeGen/TargetPassConfig.h"
19 #include "llvm/IR/LegacyPassManager.h"
20 #include "llvm/MC/MCAsmBackend.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/MC/MCCodeEmitter.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/FormattedStream.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include "llvm/Target/TargetOptions.h"
34 using namespace llvm;
35
36 static cl::opt<bool>
37 EnableTrapUnreachable("trap-unreachable", cl::Hidden,
38 cl::desc("Enable generating trap for unreachable"));
39
40 static cl::opt<bool> EnableNoTrapAfterNoreturn(
41 "no-trap-after-noreturn", cl::Hidden,
42 cl::desc("Do not emit a trap instruction for 'unreachable' IR instructions "
43 "after noreturn calls, even if --trap-unreachable is set."));
44
initAsmInfo()45 void LLVMTargetMachine::initAsmInfo() {
46 MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
47 assert(MRI && "Unable to create reg info");
48 MII.reset(TheTarget.createMCInstrInfo());
49 assert(MII && "Unable to create instruction info");
50 // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
51 // to some backends having subtarget feature dependent module level
52 // code generation. This is similar to the hack in the AsmPrinter for
53 // module level assembly etc.
54 STI.reset(TheTarget.createMCSubtargetInfo(
55 getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
56 assert(STI && "Unable to create subtarget info");
57
58 MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
59 *MRI, getTargetTriple().str(), Options.MCOptions);
60 // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
61 // and if the old one gets included then MCAsmInfo will be NULL and
62 // we'll crash later.
63 // Provide the user with a useful error message about what's wrong.
64 assert(TmpAsmInfo && "MCAsmInfo not initialized. "
65 "Make sure you include the correct TargetSelect.h"
66 "and that InitializeAllTargetMCs() is being invoked!");
67
68 if (Options.BinutilsVersion.first > 0)
69 TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
70
71 if (Options.DisableIntegratedAS) {
72 TmpAsmInfo->setUseIntegratedAssembler(false);
73 // If there is explict option disable integratedAS, we can't use it for
74 // inlineasm either.
75 TmpAsmInfo->setParseInlineAsmUsingAsmParser(false);
76 }
77
78 TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);
79
80 TmpAsmInfo->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames);
81
82 if (Options.ExceptionModel != ExceptionHandling::None)
83 TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
84
85 AsmInfo.reset(TmpAsmInfo);
86 }
87
LLVMTargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Reloc::Model RM,CodeModel::Model CM,CodeGenOptLevel OL)88 LLVMTargetMachine::LLVMTargetMachine(const Target &T,
89 StringRef DataLayoutString,
90 const Triple &TT, StringRef CPU,
91 StringRef FS, const TargetOptions &Options,
92 Reloc::Model RM, CodeModel::Model CM,
93 CodeGenOptLevel OL)
94 : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
95 this->RM = RM;
96 this->CMModel = CM;
97 this->OptLevel = OL;
98
99 if (EnableTrapUnreachable)
100 this->Options.TrapUnreachable = true;
101 if (EnableNoTrapAfterNoreturn)
102 this->Options.NoTrapAfterNoreturn = true;
103 }
104
105 TargetTransformInfo
getTargetTransformInfo(const Function & F) const106 LLVMTargetMachine::getTargetTransformInfo(const Function &F) const {
107 return TargetTransformInfo(BasicTTIImpl(this, F));
108 }
109
110 /// addPassesToX helper drives creation and initialization of TargetPassConfig.
111 static TargetPassConfig *
addPassesToGenerateCode(LLVMTargetMachine & TM,PassManagerBase & PM,bool DisableVerify,MachineModuleInfoWrapperPass & MMIWP)112 addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM,
113 bool DisableVerify,
114 MachineModuleInfoWrapperPass &MMIWP) {
115 // Targets may override createPassConfig to provide a target-specific
116 // subclass.
117 TargetPassConfig *PassConfig = TM.createPassConfig(PM);
118 // Set PassConfig options provided by TargetMachine.
119 PassConfig->setDisableVerify(DisableVerify);
120 PM.add(PassConfig);
121 PM.add(&MMIWP);
122
123 if (PassConfig->addISelPasses())
124 return nullptr;
125 PassConfig->addMachinePasses();
126 PassConfig->setInitialized();
127 return PassConfig;
128 }
129
addAsmPrinter(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)130 bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
131 raw_pwrite_stream &Out,
132 raw_pwrite_stream *DwoOut,
133 CodeGenFileType FileType,
134 MCContext &Context) {
135 Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
136 createMCStreamer(Out, DwoOut, FileType, Context);
137 if (auto Err = MCStreamerOrErr.takeError())
138 return true;
139
140 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
141 FunctionPass *Printer =
142 getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
143 if (!Printer)
144 return true;
145
146 PM.add(Printer);
147 return false;
148 }
149
createMCStreamer(raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)150 Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
151 raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
152 MCContext &Context) {
153 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
154 const MCAsmInfo &MAI = *getMCAsmInfo();
155 const MCRegisterInfo &MRI = *getMCRegisterInfo();
156 const MCInstrInfo &MII = *getMCInstrInfo();
157
158 std::unique_ptr<MCStreamer> AsmStreamer;
159
160 switch (FileType) {
161 case CodeGenFileType::AssemblyFile: {
162 MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
163 getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
164
165 // Create a code emitter if asked to show the encoding.
166 std::unique_ptr<MCCodeEmitter> MCE;
167 if (Options.MCOptions.ShowMCEncoding)
168 MCE.reset(getTarget().createMCCodeEmitter(MII, Context));
169
170 std::unique_ptr<MCAsmBackend> MAB(
171 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
172 auto FOut = std::make_unique<formatted_raw_ostream>(Out);
173 MCStreamer *S = getTarget().createAsmStreamer(
174 Context, std::move(FOut), InstPrinter, std::move(MCE), std::move(MAB));
175 AsmStreamer.reset(S);
176 break;
177 }
178 case CodeGenFileType::ObjectFile: {
179 // Create the code emitter for the target if it exists. If not, .o file
180 // emission fails.
181 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context);
182 if (!MCE)
183 return make_error<StringError>("createMCCodeEmitter failed",
184 inconvertibleErrorCode());
185 MCAsmBackend *MAB =
186 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
187 if (!MAB)
188 return make_error<StringError>("createMCAsmBackend failed",
189 inconvertibleErrorCode());
190
191 Triple T(getTargetTriple().str());
192 AsmStreamer.reset(getTarget().createMCObjectStreamer(
193 T, Context, std::unique_ptr<MCAsmBackend>(MAB),
194 DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
195 : MAB->createObjectWriter(Out),
196 std::unique_ptr<MCCodeEmitter>(MCE), STI));
197 break;
198 }
199 case CodeGenFileType::Null:
200 // The Null output is intended for use for performance analysis and testing,
201 // not real users.
202 AsmStreamer.reset(getTarget().createNullStreamer(Context));
203 break;
204 }
205
206 return std::move(AsmStreamer);
207 }
208
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)209 bool LLVMTargetMachine::addPassesToEmitFile(
210 PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
211 CodeGenFileType FileType, bool DisableVerify,
212 MachineModuleInfoWrapperPass *MMIWP) {
213 // Add common CodeGen passes.
214 if (!MMIWP)
215 MMIWP = new MachineModuleInfoWrapperPass(this);
216 TargetPassConfig *PassConfig =
217 addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
218 if (!PassConfig)
219 return true;
220
221 if (TargetPassConfig::willCompleteCodeGenPipeline()) {
222 if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
223 return true;
224 } else {
225 // MIR printing is redundant with -filetype=null.
226 if (FileType != CodeGenFileType::Null)
227 PM.add(createPrintMIRPass(Out));
228 }
229
230 PM.add(createFreeMachineFunctionPass());
231 return false;
232 }
233
234 /// addPassesToEmitMC - Add passes to the specified pass manager to get
235 /// machine code emitted with the MCJIT. This method returns true if machine
236 /// code is not supported. It fills the MCContext Ctx pointer which can be
237 /// used to build custom MCStreamer.
238 ///
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)239 bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
240 raw_pwrite_stream &Out,
241 bool DisableVerify) {
242 // Add common CodeGen passes.
243 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
244 TargetPassConfig *PassConfig =
245 addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
246 if (!PassConfig)
247 return true;
248 assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
249 "Cannot emit MC with limited codegen pipeline");
250
251 Ctx = &MMIWP->getMMI().getContext();
252 // libunwind is unable to load compact unwind dynamically, so we must generate
253 // DWARF unwind info for the JIT.
254 Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
255
256 // Create the code emitter for the target if it exists. If not, .o file
257 // emission fails.
258 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
259 const MCRegisterInfo &MRI = *getMCRegisterInfo();
260 std::unique_ptr<MCCodeEmitter> MCE(
261 getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx));
262 MCAsmBackend *MAB =
263 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
264 if (!MCE || !MAB)
265 return true;
266
267 const Triple &T = getTargetTriple();
268 std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
269 T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
270 std::move(MCE), STI));
271
272 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
273 FunctionPass *Printer =
274 getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
275 if (!Printer)
276 return true;
277
278 PM.add(Printer);
279 PM.add(createFreeMachineFunctionPass());
280
281 return false; // success!
282 }
283