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"
34using namespace llvm;
35
36static cl::opt<bool>
37 EnableTrapUnreachable("trap-unreachable", cl::Hidden,
38 cl::desc("Enable generating trap for unreachable"));
39
40static 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
45void LLVMTargetMachine::initAsmInfo() {
46 MRI.reset(p: TheTarget.createMCRegInfo(TT: getTargetTriple().str()));
47 assert(MRI && "Unable to create reg info");
48 MII.reset(p: 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(p: TheTarget.createMCSubtargetInfo(
55 TheTriple: getTargetTriple().str(), CPU: getTargetCPU(), Features: getTargetFeatureString()));
56 assert(STI && "Unable to create subtarget info");
57
58 MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
59 MRI: *MRI, TheTriple: getTargetTriple().str(), Options: 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(p: TmpAsmInfo);
86}
87
88LLVMTargetMachine::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
105TargetTransformInfo
106LLVMTargetMachine::getTargetTransformInfo(const Function &F) const {
107 return TargetTransformInfo(BasicTTIImpl(this, F));
108}
109
110/// addPassesToX helper drives creation and initialization of TargetPassConfig.
111static TargetPassConfig *
112addPassesToGenerateCode(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(P: PassConfig);
121 PM.add(P: &MMIWP);
122
123 if (PassConfig->addISelPasses())
124 return nullptr;
125 PassConfig->addMachinePasses();
126 PassConfig->setInitialized();
127 return PassConfig;
128}
129
130bool 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, Ctx&: 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(TM&: *this, Streamer: std::move(*MCStreamerOrErr));
143 if (!Printer)
144 return true;
145
146 PM.add(P: Printer);
147 return false;
148}
149
150Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
151 raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
152 MCContext &Context) {
153 if (Options.MCOptions.MCSaveTempLabels)
154 Context.setAllowTemporaryLabels(false);
155
156 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
157 const MCAsmInfo &MAI = *getMCAsmInfo();
158 const MCRegisterInfo &MRI = *getMCRegisterInfo();
159 const MCInstrInfo &MII = *getMCInstrInfo();
160
161 std::unique_ptr<MCStreamer> AsmStreamer;
162
163 switch (FileType) {
164 case CodeGenFileType::AssemblyFile: {
165 MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
166 T: getTargetTriple(), SyntaxVariant: MAI.getAssemblerDialect(), MAI, MII, MRI);
167
168 // Create a code emitter if asked to show the encoding.
169 std::unique_ptr<MCCodeEmitter> MCE;
170 if (Options.MCOptions.ShowMCEncoding)
171 MCE.reset(p: getTarget().createMCCodeEmitter(II: MII, Ctx&: Context));
172
173 bool UseDwarfDirectory = false;
174 switch (Options.MCOptions.MCUseDwarfDirectory) {
175 case MCTargetOptions::DisableDwarfDirectory:
176 UseDwarfDirectory = false;
177 break;
178 case MCTargetOptions::EnableDwarfDirectory:
179 UseDwarfDirectory = true;
180 break;
181 case MCTargetOptions::DefaultDwarfDirectory:
182 UseDwarfDirectory = MAI.enableDwarfFileDirectoryDefault();
183 break;
184 }
185
186 std::unique_ptr<MCAsmBackend> MAB(
187 getTarget().createMCAsmBackend(STI, MRI, Options: Options.MCOptions));
188 auto FOut = std::make_unique<formatted_raw_ostream>(args&: Out);
189 MCStreamer *S = getTarget().createAsmStreamer(
190 Ctx&: Context, OS: std::move(FOut), IsVerboseAsm: Options.MCOptions.AsmVerbose,
191 UseDwarfDirectory, InstPrint: InstPrinter, CE: std::move(MCE), TAB: std::move(MAB),
192 ShowInst: Options.MCOptions.ShowMCInst);
193 AsmStreamer.reset(p: S);
194 break;
195 }
196 case CodeGenFileType::ObjectFile: {
197 // Create the code emitter for the target if it exists. If not, .o file
198 // emission fails.
199 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(II: MII, Ctx&: Context);
200 if (!MCE)
201 return make_error<StringError>(Args: "createMCCodeEmitter failed",
202 Args: inconvertibleErrorCode());
203 MCAsmBackend *MAB =
204 getTarget().createMCAsmBackend(STI, MRI, Options: Options.MCOptions);
205 if (!MAB)
206 return make_error<StringError>(Args: "createMCAsmBackend failed",
207 Args: inconvertibleErrorCode());
208
209 Triple T(getTargetTriple().str());
210 AsmStreamer.reset(p: getTarget().createMCObjectStreamer(
211 T, Ctx&: Context, TAB: std::unique_ptr<MCAsmBackend>(MAB),
212 OW: DwoOut ? MAB->createDwoObjectWriter(OS&: Out, DwoOS&: *DwoOut)
213 : MAB->createObjectWriter(OS&: Out),
214 Emitter: std::unique_ptr<MCCodeEmitter>(MCE), STI, RelaxAll: Options.MCOptions.MCRelaxAll,
215 IncrementalLinkerCompatible: Options.MCOptions.MCIncrementalLinkerCompatible,
216 /*DWARFMustBeAtTheEnd*/ true));
217 break;
218 }
219 case CodeGenFileType::Null:
220 // The Null output is intended for use for performance analysis and testing,
221 // not real users.
222 AsmStreamer.reset(p: getTarget().createNullStreamer(Ctx&: Context));
223 break;
224 }
225
226 return std::move(AsmStreamer);
227}
228
229bool LLVMTargetMachine::addPassesToEmitFile(
230 PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
231 CodeGenFileType FileType, bool DisableVerify,
232 MachineModuleInfoWrapperPass *MMIWP) {
233 // Add common CodeGen passes.
234 if (!MMIWP)
235 MMIWP = new MachineModuleInfoWrapperPass(this);
236 TargetPassConfig *PassConfig =
237 addPassesToGenerateCode(TM&: *this, PM, DisableVerify, MMIWP&: *MMIWP);
238 if (!PassConfig)
239 return true;
240
241 if (TargetPassConfig::willCompleteCodeGenPipeline()) {
242 if (addAsmPrinter(PM, Out, DwoOut, FileType, Context&: MMIWP->getMMI().getContext()))
243 return true;
244 } else {
245 // MIR printing is redundant with -filetype=null.
246 if (FileType != CodeGenFileType::Null)
247 PM.add(P: createPrintMIRPass(OS&: Out));
248 }
249
250 PM.add(P: createFreeMachineFunctionPass());
251 return false;
252}
253
254/// addPassesToEmitMC - Add passes to the specified pass manager to get
255/// machine code emitted with the MCJIT. This method returns true if machine
256/// code is not supported. It fills the MCContext Ctx pointer which can be
257/// used to build custom MCStreamer.
258///
259bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
260 raw_pwrite_stream &Out,
261 bool DisableVerify) {
262 // Add common CodeGen passes.
263 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
264 TargetPassConfig *PassConfig =
265 addPassesToGenerateCode(TM&: *this, PM, DisableVerify, MMIWP&: *MMIWP);
266 if (!PassConfig)
267 return true;
268 assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
269 "Cannot emit MC with limited codegen pipeline");
270
271 Ctx = &MMIWP->getMMI().getContext();
272 // libunwind is unable to load compact unwind dynamically, so we must generate
273 // DWARF unwind info for the JIT.
274 Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
275 if (Options.MCOptions.MCSaveTempLabels)
276 Ctx->setAllowTemporaryLabels(false);
277
278 // Create the code emitter for the target if it exists. If not, .o file
279 // emission fails.
280 const MCSubtargetInfo &STI = *getMCSubtargetInfo();
281 const MCRegisterInfo &MRI = *getMCRegisterInfo();
282 std::unique_ptr<MCCodeEmitter> MCE(
283 getTarget().createMCCodeEmitter(II: *getMCInstrInfo(), Ctx&: *Ctx));
284 std::unique_ptr<MCAsmBackend> MAB(
285 getTarget().createMCAsmBackend(STI, MRI, Options: Options.MCOptions));
286 if (!MCE || !MAB)
287 return true;
288
289 const Triple &T = getTargetTriple();
290 std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
291 T, Ctx&: *Ctx, TAB: std::move(MAB), OW: MAB->createObjectWriter(OS&: Out), Emitter: std::move(MCE),
292 STI, RelaxAll: Options.MCOptions.MCRelaxAll,
293 IncrementalLinkerCompatible: Options.MCOptions.MCIncrementalLinkerCompatible,
294 /*DWARFMustBeAtTheEnd*/ true));
295
296 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
297 FunctionPass *Printer =
298 getTarget().createAsmPrinter(TM&: *this, Streamer: std::move(AsmStreamer));
299 if (!Printer)
300 return true;
301
302 PM.add(P: Printer);
303 PM.add(P: createFreeMachineFunctionPass());
304
305 return false; // success!
306}
307

source code of llvm/lib/CodeGen/LLVMTargetMachine.cpp