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