1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #include "clang/CodeGen/BackendUtil.h" |
10 | #include "clang/Basic/CodeGenOptions.h" |
11 | #include "clang/Basic/Diagnostic.h" |
12 | #include "clang/Basic/LangOptions.h" |
13 | #include "clang/Basic/TargetOptions.h" |
14 | #include "clang/Frontend/FrontendDiagnostic.h" |
15 | #include "clang/Frontend/Utils.h" |
16 | #include "clang/Lex/HeaderSearchOptions.h" |
17 | #include "llvm/ADT/SmallSet.h" |
18 | #include "llvm/ADT/StringExtras.h" |
19 | #include "llvm/ADT/StringSwitch.h" |
20 | #include "llvm/ADT/Triple.h" |
21 | #include "llvm/Analysis/TargetLibraryInfo.h" |
22 | #include "llvm/Analysis/TargetTransformInfo.h" |
23 | #include "llvm/Bitcode/BitcodeReader.h" |
24 | #include "llvm/Bitcode/BitcodeWriter.h" |
25 | #include "llvm/Bitcode/BitcodeWriterPass.h" |
26 | #include "llvm/CodeGen/RegAllocRegistry.h" |
27 | #include "llvm/CodeGen/SchedulerRegistry.h" |
28 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
29 | #include "llvm/IR/DataLayout.h" |
30 | #include "llvm/IR/IRPrintingPasses.h" |
31 | #include "llvm/IR/LegacyPassManager.h" |
32 | #include "llvm/IR/Module.h" |
33 | #include "llvm/IR/ModuleSummaryIndex.h" |
34 | #include "llvm/IR/Verifier.h" |
35 | #include "llvm/LTO/LTOBackend.h" |
36 | #include "llvm/MC/MCAsmInfo.h" |
37 | #include "llvm/MC/SubtargetFeature.h" |
38 | #include "llvm/Passes/PassBuilder.h" |
39 | #include "llvm/Passes/PassPlugin.h" |
40 | #include "llvm/Support/BuryPointer.h" |
41 | #include "llvm/Support/CommandLine.h" |
42 | #include "llvm/Support/MemoryBuffer.h" |
43 | #include "llvm/Support/PrettyStackTrace.h" |
44 | #include "llvm/Support/TargetRegistry.h" |
45 | #include "llvm/Support/Timer.h" |
46 | #include "llvm/Support/raw_ostream.h" |
47 | #include "llvm/Target/TargetMachine.h" |
48 | #include "llvm/Target/TargetOptions.h" |
49 | #include "llvm/Transforms/Coroutines.h" |
50 | #include "llvm/Transforms/IPO.h" |
51 | #include "llvm/Transforms/IPO/AlwaysInliner.h" |
52 | #include "llvm/Transforms/IPO/PassManagerBuilder.h" |
53 | #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" |
54 | #include "llvm/Transforms/InstCombine/InstCombine.h" |
55 | #include "llvm/Transforms/Instrumentation.h" |
56 | #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" |
57 | #include "llvm/Transforms/Instrumentation/BoundsChecking.h" |
58 | #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" |
59 | #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" |
60 | #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" |
61 | #include "llvm/Transforms/ObjCARC.h" |
62 | #include "llvm/Transforms/Scalar.h" |
63 | #include "llvm/Transforms/Scalar/GVN.h" |
64 | #include "llvm/Transforms/Utils.h" |
65 | #include "llvm/Transforms/Utils/CanonicalizeAliases.h" |
66 | #include "llvm/Transforms/Utils/NameAnonGlobals.h" |
67 | #include "llvm/Transforms/Utils/SymbolRewriter.h" |
68 | #include <memory> |
69 | using namespace clang; |
70 | using namespace llvm; |
71 | |
72 | namespace { |
73 | |
74 | |
75 | static constexpr StringLiteral DefaultProfileGenName = "default_%m.profraw"; |
76 | |
77 | class EmitAssemblyHelper { |
78 | DiagnosticsEngine &Diags; |
79 | const HeaderSearchOptions &HSOpts; |
80 | const CodeGenOptions &CodeGenOpts; |
81 | const clang::TargetOptions &TargetOpts; |
82 | const LangOptions &LangOpts; |
83 | Module *TheModule; |
84 | |
85 | Timer CodeGenerationTime; |
86 | |
87 | std::unique_ptr<raw_pwrite_stream> OS; |
88 | |
89 | TargetIRAnalysis getTargetIRAnalysis() const { |
90 | if (TM) |
91 | return TM->getTargetIRAnalysis(); |
92 | |
93 | return TargetIRAnalysis(); |
94 | } |
95 | |
96 | void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM); |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | |
106 | void CreateTargetMachine(bool MustCreateTM); |
107 | |
108 | |
109 | |
110 | |
111 | bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action, |
112 | raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS); |
113 | |
114 | std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) { |
115 | std::error_code EC; |
116 | auto F = llvm::make_unique<llvm::ToolOutputFile>(Path, EC, |
117 | llvm::sys::fs::F_None); |
118 | if (EC) { |
119 | Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message(); |
120 | F.reset(); |
121 | } |
122 | return F; |
123 | } |
124 | |
125 | public: |
126 | EmitAssemblyHelper(DiagnosticsEngine &_Diags, |
127 | const HeaderSearchOptions &, |
128 | const CodeGenOptions &CGOpts, |
129 | const clang::TargetOptions &TOpts, |
130 | const LangOptions &LOpts, Module *M) |
131 | : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts), |
132 | TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), |
133 | CodeGenerationTime("codegen", "Code Generation Time") {} |
134 | |
135 | ~EmitAssemblyHelper() { |
136 | if (CodeGenOpts.DisableFree) |
137 | BuryPointer(std::move(TM)); |
138 | } |
139 | |
140 | std::unique_ptr<TargetMachine> TM; |
141 | |
142 | void EmitAssembly(BackendAction Action, |
143 | std::unique_ptr<raw_pwrite_stream> OS); |
144 | |
145 | void EmitAssemblyWithNewPassManager(BackendAction Action, |
146 | std::unique_ptr<raw_pwrite_stream> OS); |
147 | }; |
148 | |
149 | |
150 | |
151 | class PassManagerBuilderWrapper : public PassManagerBuilder { |
152 | public: |
153 | PassManagerBuilderWrapper(const Triple &TargetTriple, |
154 | const CodeGenOptions &CGOpts, |
155 | const LangOptions &LangOpts) |
156 | : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts), |
157 | LangOpts(LangOpts) {} |
158 | const Triple &getTargetTriple() const { return TargetTriple; } |
159 | const CodeGenOptions &getCGOpts() const { return CGOpts; } |
160 | const LangOptions &getLangOpts() const { return LangOpts; } |
161 | |
162 | private: |
163 | const Triple &TargetTriple; |
164 | const CodeGenOptions &CGOpts; |
165 | const LangOptions &LangOpts; |
166 | }; |
167 | } |
168 | |
169 | static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { |
170 | if (Builder.OptLevel > 0) |
171 | PM.add(createObjCARCAPElimPass()); |
172 | } |
173 | |
174 | static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { |
175 | if (Builder.OptLevel > 0) |
176 | PM.add(createObjCARCExpandPass()); |
177 | } |
178 | |
179 | static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { |
180 | if (Builder.OptLevel > 0) |
181 | PM.add(createObjCARCOptPass()); |
182 | } |
183 | |
184 | static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder, |
185 | legacy::PassManagerBase &PM) { |
186 | PM.add(createAddDiscriminatorsPass()); |
187 | } |
188 | |
189 | static void addBoundsCheckingPass(const PassManagerBuilder &Builder, |
190 | legacy::PassManagerBase &PM) { |
191 | PM.add(createBoundsCheckingLegacyPass()); |
192 | } |
193 | |
194 | static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, |
195 | legacy::PassManagerBase &PM) { |
196 | const PassManagerBuilderWrapper &BuilderWrapper = |
197 | static_cast<const PassManagerBuilderWrapper&>(Builder); |
198 | const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); |
199 | SanitizerCoverageOptions Opts; |
200 | Opts.CoverageType = |
201 | static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType); |
202 | Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls; |
203 | Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB; |
204 | Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp; |
205 | Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv; |
206 | Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep; |
207 | Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters; |
208 | Opts.TracePC = CGOpts.SanitizeCoverageTracePC; |
209 | Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard; |
210 | Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune; |
211 | Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters; |
212 | Opts.PCTable = CGOpts.SanitizeCoveragePCTable; |
213 | Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth; |
214 | PM.add(createSanitizerCoverageModulePass(Opts)); |
215 | } |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) { |
222 | if (!CGOpts.SanitizeAddressGlobalsDeadStripping) |
223 | return false; |
224 | switch (T.getObjectFormat()) { |
225 | case Triple::MachO: |
226 | case Triple::COFF: |
227 | return true; |
228 | case Triple::ELF: |
229 | return CGOpts.DataSections && !CGOpts.DisableIntegratedAS; |
230 | default: |
231 | return false; |
232 | } |
233 | } |
234 | |
235 | static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, |
236 | legacy::PassManagerBase &PM) { |
237 | const PassManagerBuilderWrapper &BuilderWrapper = |
238 | static_cast<const PassManagerBuilderWrapper&>(Builder); |
239 | const Triple &T = BuilderWrapper.getTargetTriple(); |
240 | const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); |
241 | bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address); |
242 | bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope; |
243 | bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator; |
244 | bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); |
245 | PM.add(createAddressSanitizerFunctionPass( false, Recover, |
246 | UseAfterScope)); |
247 | PM.add(createModuleAddressSanitizerLegacyPassPass( |
248 | false, Recover, UseGlobalsGC, UseOdrIndicator)); |
249 | } |
250 | |
251 | static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, |
252 | legacy::PassManagerBase &PM) { |
253 | PM.add(createAddressSanitizerFunctionPass( |
254 | true, true, false)); |
255 | PM.add(createModuleAddressSanitizerLegacyPassPass( |
256 | true, true, true, |
257 | false)); |
258 | } |
259 | |
260 | static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, |
261 | legacy::PassManagerBase &PM) { |
262 | const PassManagerBuilderWrapper &BuilderWrapper = |
263 | static_cast<const PassManagerBuilderWrapper &>(Builder); |
264 | const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); |
265 | bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress); |
266 | PM.add(createHWAddressSanitizerPass( false, Recover)); |
267 | } |
268 | |
269 | static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder, |
270 | legacy::PassManagerBase &PM) { |
271 | PM.add(createHWAddressSanitizerPass( |
272 | true, true)); |
273 | } |
274 | |
275 | static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder, |
276 | legacy::PassManagerBase &PM, |
277 | bool CompileKernel) { |
278 | const PassManagerBuilderWrapper &BuilderWrapper = |
279 | static_cast<const PassManagerBuilderWrapper&>(Builder); |
280 | const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); |
281 | int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins; |
282 | bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory); |
283 | PM.add(createMemorySanitizerLegacyPassPass( |
284 | MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel})); |
285 | |
286 | |
287 | |
288 | |
289 | if (Builder.OptLevel > 0) { |
290 | PM.add(createEarlyCSEPass()); |
291 | PM.add(createReassociatePass()); |
292 | PM.add(createLICMPass()); |
293 | PM.add(createGVNPass()); |
294 | PM.add(createInstructionCombiningPass()); |
295 | PM.add(createDeadStoreEliminationPass()); |
296 | } |
297 | } |
298 | |
299 | static void addMemorySanitizerPass(const PassManagerBuilder &Builder, |
300 | legacy::PassManagerBase &PM) { |
301 | addGeneralOptsForMemorySanitizer(Builder, PM, false); |
302 | } |
303 | |
304 | static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder, |
305 | legacy::PassManagerBase &PM) { |
306 | addGeneralOptsForMemorySanitizer(Builder, PM, true); |
307 | } |
308 | |
309 | static void addThreadSanitizerPass(const PassManagerBuilder &Builder, |
310 | legacy::PassManagerBase &PM) { |
311 | PM.add(createThreadSanitizerLegacyPassPass()); |
312 | } |
313 | |
314 | static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, |
315 | legacy::PassManagerBase &PM) { |
316 | const PassManagerBuilderWrapper &BuilderWrapper = |
317 | static_cast<const PassManagerBuilderWrapper&>(Builder); |
318 | const LangOptions &LangOpts = BuilderWrapper.getLangOpts(); |
319 | PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles)); |
320 | } |
321 | |
322 | static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, |
323 | const CodeGenOptions &CodeGenOpts) { |
324 | TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple); |
325 | if (!CodeGenOpts.SimplifyLibCalls) |
326 | TLII->disableAllFunctions(); |
327 | else { |
328 | |
329 | LibFunc F; |
330 | for (auto &FuncName : CodeGenOpts.getNoBuiltinFuncs()) |
331 | if (TLII->getLibFunc(FuncName, F)) |
332 | TLII->setUnavailable(F); |
333 | } |
334 | |
335 | switch (CodeGenOpts.getVecLib()) { |
336 | case CodeGenOptions::Accelerate: |
337 | TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate); |
338 | break; |
339 | case CodeGenOptions::SVML: |
340 | TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML); |
341 | break; |
342 | default: |
343 | break; |
344 | } |
345 | return TLII; |
346 | } |
347 | |
348 | static void addSymbolRewriterPass(const CodeGenOptions &Opts, |
349 | legacy::PassManager *MPM) { |
350 | llvm::SymbolRewriter::RewriteDescriptorList DL; |
351 | |
352 | llvm::SymbolRewriter::RewriteMapParser MapParser; |
353 | for (const auto &MapFile : Opts.RewriteMapFiles) |
354 | MapParser.parse(MapFile, &DL); |
355 | |
356 | MPM->add(createRewriteSymbolsPass(DL)); |
357 | } |
358 | |
359 | static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) { |
360 | switch (CodeGenOpts.OptimizationLevel) { |
361 | default: |
362 | llvm_unreachable("Invalid optimization level!"); |
363 | case 0: |
364 | return CodeGenOpt::None; |
365 | case 1: |
366 | return CodeGenOpt::Less; |
367 | case 2: |
368 | return CodeGenOpt::Default; |
369 | case 3: |
370 | return CodeGenOpt::Aggressive; |
371 | } |
372 | } |
373 | |
374 | static Optional<llvm::CodeModel::Model> |
375 | getCodeModel(const CodeGenOptions &CodeGenOpts) { |
376 | unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel) |
377 | .Case("tiny", llvm::CodeModel::Tiny) |
378 | .Case("small", llvm::CodeModel::Small) |
379 | .Case("kernel", llvm::CodeModel::Kernel) |
380 | .Case("medium", llvm::CodeModel::Medium) |
381 | .Case("large", llvm::CodeModel::Large) |
382 | .Case("default", ~1u) |
383 | .Default(~0u); |
384 | (0) . __assert_fail ("CodeModel != ~0u && \"invalid code model!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 384, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(CodeModel != ~0u && "invalid code model!"); |
385 | if (CodeModel == ~1u) |
386 | return None; |
387 | return static_cast<llvm::CodeModel::Model>(CodeModel); |
388 | } |
389 | |
390 | static TargetMachine::CodeGenFileType getCodeGenFileType(BackendAction Action) { |
391 | if (Action == Backend_EmitObj) |
392 | return TargetMachine::CGFT_ObjectFile; |
393 | else if (Action == Backend_EmitMCNull) |
394 | return TargetMachine::CGFT_Null; |
395 | else { |
396 | (0) . __assert_fail ("Action == Backend_EmitAssembly && \"Invalid action!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 396, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Action == Backend_EmitAssembly && "Invalid action!"); |
397 | return TargetMachine::CGFT_AssemblyFile; |
398 | } |
399 | } |
400 | |
401 | static void (llvm::TargetOptions &Options, |
402 | const CodeGenOptions &CodeGenOpts, |
403 | const clang::TargetOptions &TargetOpts, |
404 | const LangOptions &LangOpts, |
405 | const HeaderSearchOptions &HSOpts) { |
406 | Options.ThreadModel = |
407 | llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel) |
408 | .Case("posix", llvm::ThreadModel::POSIX) |
409 | .Case("single", llvm::ThreadModel::Single); |
410 | |
411 | |
412 | (0) . __assert_fail ("(CodeGenOpts.FloatABI == \"soft\" || CodeGenOpts.FloatABI == \"softfp\" || CodeGenOpts.FloatABI == \"hard\" || CodeGenOpts.FloatABI.empty()) && \"Invalid Floating Point ABI!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 414, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" || |
413 | (0) . __assert_fail ("(CodeGenOpts.FloatABI == \"soft\" || CodeGenOpts.FloatABI == \"softfp\" || CodeGenOpts.FloatABI == \"hard\" || CodeGenOpts.FloatABI.empty()) && \"Invalid Floating Point ABI!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 414, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) && |
414 | (0) . __assert_fail ("(CodeGenOpts.FloatABI == \"soft\" || CodeGenOpts.FloatABI == \"softfp\" || CodeGenOpts.FloatABI == \"hard\" || CodeGenOpts.FloatABI.empty()) && \"Invalid Floating Point ABI!\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 414, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Invalid Floating Point ABI!"); |
415 | Options.FloatABIType = |
416 | llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI) |
417 | .Case("soft", llvm::FloatABI::Soft) |
418 | .Case("softfp", llvm::FloatABI::Soft) |
419 | .Case("hard", llvm::FloatABI::Hard) |
420 | .Default(llvm::FloatABI::Default); |
421 | |
422 | |
423 | switch (LangOpts.getDefaultFPContractMode()) { |
424 | case LangOptions::FPC_Off: |
425 | |
426 | |
427 | Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; |
428 | break; |
429 | case LangOptions::FPC_On: |
430 | Options.AllowFPOpFusion = llvm::FPOpFusion::Standard; |
431 | break; |
432 | case LangOptions::FPC_Fast: |
433 | Options.AllowFPOpFusion = llvm::FPOpFusion::Fast; |
434 | break; |
435 | } |
436 | |
437 | Options.UseInitArray = CodeGenOpts.UseInitArray; |
438 | Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS; |
439 | Options.CompressDebugSections = CodeGenOpts.getCompressDebugSections(); |
440 | Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations; |
441 | |
442 | |
443 | Options.EABIVersion = TargetOpts.EABIVersion; |
444 | |
445 | if (LangOpts.SjLjExceptions) |
446 | Options.ExceptionModel = llvm::ExceptionHandling::SjLj; |
447 | if (LangOpts.SEHExceptions) |
448 | Options.ExceptionModel = llvm::ExceptionHandling::WinEH; |
449 | if (LangOpts.DWARFExceptions) |
450 | Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI; |
451 | |
452 | Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath; |
453 | Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath; |
454 | Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS; |
455 | Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath; |
456 | Options.StackAlignmentOverride = CodeGenOpts.StackAlignment; |
457 | Options.FunctionSections = CodeGenOpts.FunctionSections; |
458 | Options.DataSections = CodeGenOpts.DataSections; |
459 | Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; |
460 | Options.EmulatedTLS = CodeGenOpts.EmulatedTLS; |
461 | Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS; |
462 | Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning(); |
463 | Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection; |
464 | Options.EmitAddrsig = CodeGenOpts.Addrsig; |
465 | |
466 | if (CodeGenOpts.getSplitDwarfMode() != CodeGenOptions::NoFission) |
467 | Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile; |
468 | Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll; |
469 | Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels; |
470 | Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm; |
471 | Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack; |
472 | Options.MCOptions.MCIncrementalLinkerCompatible = |
473 | CodeGenOpts.IncrementalLinkerCompatible; |
474 | Options.MCOptions.MCPIECopyRelocations = CodeGenOpts.PIECopyRelocations; |
475 | Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings; |
476 | Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; |
477 | Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments; |
478 | Options.MCOptions.ABIName = TargetOpts.ABI; |
479 | for (const auto &Entry : HSOpts.UserEntries) |
480 | if (!Entry.IsFramework && |
481 | (Entry.Group == frontend::IncludeDirGroup::Quoted || |
482 | Entry.Group == frontend::IncludeDirGroup::Angled || |
483 | Entry.Group == frontend::IncludeDirGroup::System)) |
484 | Options.MCOptions.IASSearchPaths.push_back( |
485 | Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path); |
486 | } |
487 | static Optional<GCOVOptions> getGCOVOptions(const CodeGenOptions &CodeGenOpts) { |
488 | if (CodeGenOpts.DisableGCov) |
489 | return None; |
490 | if (!CodeGenOpts.EmitGcovArcs && !CodeGenOpts.EmitGcovNotes) |
491 | return None; |
492 | |
493 | |
494 | GCOVOptions Options; |
495 | Options.EmitNotes = CodeGenOpts.EmitGcovNotes; |
496 | Options.EmitData = CodeGenOpts.EmitGcovArcs; |
497 | llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version)); |
498 | Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum; |
499 | Options.NoRedZone = CodeGenOpts.DisableRedZone; |
500 | Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData; |
501 | Options.Filter = CodeGenOpts.ProfileFilterFiles; |
502 | Options.Exclude = CodeGenOpts.ProfileExcludeFiles; |
503 | Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody; |
504 | return Options; |
505 | } |
506 | |
507 | void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, |
508 | legacy::FunctionPassManager &FPM) { |
509 | |
510 | |
511 | if (CodeGenOpts.DisableLLVMPasses) |
512 | return; |
513 | |
514 | |
515 | |
516 | |
517 | |
518 | Triple TargetTriple(TheModule->getTargetTriple()); |
519 | std::unique_ptr<TargetLibraryInfoImpl> TLII( |
520 | createTLII(TargetTriple, CodeGenOpts)); |
521 | |
522 | PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts); |
523 | |
524 | |
525 | |
526 | if (CodeGenOpts.OptimizationLevel <= 1) { |
527 | bool InsertLifetimeIntrinsics = (CodeGenOpts.OptimizationLevel != 0 && |
528 | !CodeGenOpts.DisableLifetimeMarkers); |
529 | PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics); |
530 | } else { |
531 | |
532 | |
533 | |
534 | PMBuilder.Inliner = createFunctionInliningPass( |
535 | CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize, |
536 | (!CodeGenOpts.SampleProfileFile.empty() && |
537 | CodeGenOpts.PrepareForThinLTO)); |
538 | } |
539 | |
540 | PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel; |
541 | PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; |
542 | PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; |
543 | PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; |
544 | |
545 | PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; |
546 | PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions; |
547 | PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO; |
548 | PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; |
549 | PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; |
550 | |
551 | MPM.add(new TargetLibraryInfoWrapperPass(*TLII)); |
552 | |
553 | if (TM) |
554 | TM->adjustPassManager(PMBuilder); |
555 | |
556 | if (CodeGenOpts.DebugInfoForProfiling || |
557 | !CodeGenOpts.SampleProfileFile.empty()) |
558 | PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, |
559 | addAddDiscriminatorsPass); |
560 | |
561 | |
562 | if (LangOpts.ObjCAutoRefCount) { |
563 | PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, |
564 | addObjCARCExpandPass); |
565 | PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, |
566 | addObjCARCAPElimPass); |
567 | PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, |
568 | addObjCARCOptPass); |
569 | } |
570 | |
571 | if (LangOpts.Coroutines) |
572 | addCoroutinePassesToExtensionPoints(PMBuilder); |
573 | |
574 | if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) { |
575 | PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, |
576 | addBoundsCheckingPass); |
577 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
578 | addBoundsCheckingPass); |
579 | } |
580 | |
581 | if (CodeGenOpts.SanitizeCoverageType || |
582 | CodeGenOpts.SanitizeCoverageIndirectCalls || |
583 | CodeGenOpts.SanitizeCoverageTraceCmp) { |
584 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
585 | addSanitizerCoveragePass); |
586 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
587 | addSanitizerCoveragePass); |
588 | } |
589 | |
590 | if (LangOpts.Sanitize.has(SanitizerKind::Address)) { |
591 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
592 | addAddressSanitizerPasses); |
593 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
594 | addAddressSanitizerPasses); |
595 | } |
596 | |
597 | if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) { |
598 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
599 | addKernelAddressSanitizerPasses); |
600 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
601 | addKernelAddressSanitizerPasses); |
602 | } |
603 | |
604 | if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) { |
605 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
606 | addHWAddressSanitizerPasses); |
607 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
608 | addHWAddressSanitizerPasses); |
609 | } |
610 | |
611 | if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) { |
612 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
613 | addKernelHWAddressSanitizerPasses); |
614 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
615 | addKernelHWAddressSanitizerPasses); |
616 | } |
617 | |
618 | if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { |
619 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
620 | addMemorySanitizerPass); |
621 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
622 | addMemorySanitizerPass); |
623 | } |
624 | |
625 | if (LangOpts.Sanitize.has(SanitizerKind::KernelMemory)) { |
626 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
627 | addKernelMemorySanitizerPass); |
628 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
629 | addKernelMemorySanitizerPass); |
630 | } |
631 | |
632 | if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { |
633 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
634 | addThreadSanitizerPass); |
635 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
636 | addThreadSanitizerPass); |
637 | } |
638 | |
639 | if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { |
640 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, |
641 | addDataFlowSanitizerPass); |
642 | PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, |
643 | addDataFlowSanitizerPass); |
644 | } |
645 | |
646 | |
647 | FPM.add(new TargetLibraryInfoWrapperPass(*TLII)); |
648 | if (CodeGenOpts.VerifyModule) |
649 | FPM.add(createVerifierPass()); |
650 | |
651 | |
652 | if (!CodeGenOpts.RewriteMapFiles.empty()) |
653 | addSymbolRewriterPass(CodeGenOpts, &MPM); |
654 | |
655 | if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts)) { |
656 | MPM.add(createGCOVProfilerPass(*Options)); |
657 | if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo) |
658 | MPM.add(createStripSymbolsPass(true)); |
659 | } |
660 | |
661 | if (CodeGenOpts.hasProfileClangInstr()) { |
662 | InstrProfOptions Options; |
663 | Options.NoRedZone = CodeGenOpts.DisableRedZone; |
664 | Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput; |
665 | |
666 | |
667 | |
668 | Options.Atomic = LangOpts.Sanitize.has(SanitizerKind::Thread); |
669 | |
670 | MPM.add(createInstrProfilingLegacyPass(Options, false)); |
671 | } |
672 | bool hasIRInstr = false; |
673 | if (CodeGenOpts.hasProfileIRInstr()) { |
674 | PMBuilder.EnablePGOInstrGen = true; |
675 | hasIRInstr = true; |
676 | } |
677 | if (CodeGenOpts.hasProfileCSIRInstr()) { |
678 | (0) . __assert_fail ("!CodeGenOpts.hasProfileCSIRUse() && \"Cannot have both CSProfileUse pass and CSProfileGen pass at the \" \"same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 680, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CodeGenOpts.hasProfileCSIRUse() && |
679 | (0) . __assert_fail ("!CodeGenOpts.hasProfileCSIRUse() && \"Cannot have both CSProfileUse pass and CSProfileGen pass at the \" \"same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 680, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot have both CSProfileUse pass and CSProfileGen pass at the " |
680 | (0) . __assert_fail ("!CodeGenOpts.hasProfileCSIRUse() && \"Cannot have both CSProfileUse pass and CSProfileGen pass at the \" \"same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 680, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "same time"); |
681 | (0) . __assert_fail ("!hasIRInstr && \"Cannot have both ProfileGen pass and CSProfileGen pass at the \" \"same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 683, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!hasIRInstr && |
682 | (0) . __assert_fail ("!hasIRInstr && \"Cannot have both ProfileGen pass and CSProfileGen pass at the \" \"same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 683, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot have both ProfileGen pass and CSProfileGen pass at the " |
683 | (0) . __assert_fail ("!hasIRInstr && \"Cannot have both ProfileGen pass and CSProfileGen pass at the \" \"same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 683, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "same time"); |
684 | PMBuilder.EnablePGOCSInstrGen = true; |
685 | hasIRInstr = true; |
686 | } |
687 | if (hasIRInstr) { |
688 | if (!CodeGenOpts.InstrProfileOutput.empty()) |
689 | PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput; |
690 | else |
691 | PMBuilder.PGOInstrGen = DefaultProfileGenName; |
692 | } |
693 | if (CodeGenOpts.hasProfileIRUse()) { |
694 | PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath; |
695 | PMBuilder.EnablePGOCSInstrUse = CodeGenOpts.hasProfileCSIRUse(); |
696 | } |
697 | |
698 | if (!CodeGenOpts.SampleProfileFile.empty()) |
699 | PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile; |
700 | |
701 | PMBuilder.populateFunctionPassManager(FPM); |
702 | PMBuilder.populateModulePassManager(MPM); |
703 | } |
704 | |
705 | static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) { |
706 | SmallVector<const char *, 16> BackendArgs; |
707 | BackendArgs.push_back("clang"); |
708 | if (!CodeGenOpts.DebugPass.empty()) { |
709 | BackendArgs.push_back("-debug-pass"); |
710 | BackendArgs.push_back(CodeGenOpts.DebugPass.c_str()); |
711 | } |
712 | if (!CodeGenOpts.LimitFloatPrecision.empty()) { |
713 | BackendArgs.push_back("-limit-float-precision"); |
714 | BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str()); |
715 | } |
716 | BackendArgs.push_back(nullptr); |
717 | llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, |
718 | BackendArgs.data()); |
719 | } |
720 | |
721 | void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { |
722 | |
723 | std::string Error; |
724 | std::string Triple = TheModule->getTargetTriple(); |
725 | const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); |
726 | if (!TheTarget) { |
727 | if (MustCreateTM) |
728 | Diags.Report(diag::err_fe_unable_to_create_target) << Error; |
729 | return; |
730 | } |
731 | |
732 | Optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts); |
733 | std::string FeaturesStr = |
734 | llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ","); |
735 | llvm::Reloc::Model RM = CodeGenOpts.RelocationModel; |
736 | CodeGenOpt::Level OptLevel = getCGOptLevel(CodeGenOpts); |
737 | |
738 | llvm::TargetOptions Options; |
739 | initTargetOptions(Options, CodeGenOpts, TargetOpts, LangOpts, HSOpts); |
740 | TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, |
741 | Options, RM, CM, OptLevel)); |
742 | } |
743 | |
744 | bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses, |
745 | BackendAction Action, |
746 | raw_pwrite_stream &OS, |
747 | raw_pwrite_stream *DwoOS) { |
748 | |
749 | llvm::Triple TargetTriple(TheModule->getTargetTriple()); |
750 | std::unique_ptr<TargetLibraryInfoImpl> TLII( |
751 | createTLII(TargetTriple, CodeGenOpts)); |
752 | CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); |
753 | |
754 | |
755 | |
756 | TargetMachine::CodeGenFileType CGFT = getCodeGenFileType(Action); |
757 | |
758 | |
759 | |
760 | |
761 | if (CodeGenOpts.OptimizationLevel > 0) |
762 | CodeGenPasses.add(createObjCARCContractPass()); |
763 | |
764 | if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT, |
765 | !CodeGenOpts.VerifyModule)) { |
766 | Diags.Report(diag::err_fe_unable_to_interface_with_target); |
767 | return false; |
768 | } |
769 | |
770 | return true; |
771 | } |
772 | |
773 | void EmitAssemblyHelper::EmitAssembly(BackendAction Action, |
774 | std::unique_ptr<raw_pwrite_stream> OS) { |
775 | TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr); |
776 | |
777 | setCommandLineOpts(CodeGenOpts); |
778 | |
779 | bool UsesCodeGen = (Action != Backend_EmitNothing && |
780 | Action != Backend_EmitBC && |
781 | Action != Backend_EmitLL); |
782 | CreateTargetMachine(UsesCodeGen); |
783 | |
784 | if (UsesCodeGen && !TM) |
785 | return; |
786 | if (TM) |
787 | TheModule->setDataLayout(TM->createDataLayout()); |
788 | |
789 | legacy::PassManager PerModulePasses; |
790 | PerModulePasses.add( |
791 | createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); |
792 | |
793 | legacy::FunctionPassManager PerFunctionPasses(TheModule); |
794 | PerFunctionPasses.add( |
795 | createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); |
796 | |
797 | CreatePasses(PerModulePasses, PerFunctionPasses); |
798 | |
799 | legacy::PassManager CodeGenPasses; |
800 | CodeGenPasses.add( |
801 | createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); |
802 | |
803 | std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS; |
804 | |
805 | switch (Action) { |
806 | case Backend_EmitNothing: |
807 | break; |
808 | |
809 | case Backend_EmitBC: |
810 | if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) { |
811 | if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) { |
812 | ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile); |
813 | if (!ThinLinkOS) |
814 | return; |
815 | } |
816 | TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", |
817 | CodeGenOpts.EnableSplitLTOUnit); |
818 | PerModulePasses.add(createWriteThinLTOBitcodePass( |
819 | *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr)); |
820 | } else { |
821 | |
822 | |
823 | bool EmitLTOSummary = |
824 | (CodeGenOpts.PrepareForLTO && |
825 | !CodeGenOpts.DisableLLVMPasses && |
826 | llvm::Triple(TheModule->getTargetTriple()).getVendor() != |
827 | llvm::Triple::Apple); |
828 | if (EmitLTOSummary) { |
829 | if (!TheModule->getModuleFlag("ThinLTO")) |
830 | TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); |
831 | TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", |
832 | CodeGenOpts.EnableSplitLTOUnit); |
833 | } |
834 | |
835 | PerModulePasses.add(createBitcodeWriterPass( |
836 | *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary)); |
837 | } |
838 | break; |
839 | |
840 | case Backend_EmitLL: |
841 | PerModulePasses.add( |
842 | createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); |
843 | break; |
844 | |
845 | default: |
846 | if (!CodeGenOpts.SplitDwarfFile.empty() && |
847 | (CodeGenOpts.getSplitDwarfMode() == CodeGenOptions::SplitFileFission)) { |
848 | DwoOS = openOutputFile(CodeGenOpts.SplitDwarfFile); |
849 | if (!DwoOS) |
850 | return; |
851 | } |
852 | if (!AddEmitPasses(CodeGenPasses, Action, *OS, |
853 | DwoOS ? &DwoOS->os() : nullptr)) |
854 | return; |
855 | } |
856 | |
857 | |
858 | cl::PrintOptionValues(); |
859 | |
860 | |
861 | |
862 | |
863 | { |
864 | PrettyStackTraceString CrashInfo("Per-function optimization"); |
865 | |
866 | PerFunctionPasses.doInitialization(); |
867 | for (Function &F : *TheModule) |
868 | if (!F.isDeclaration()) |
869 | PerFunctionPasses.run(F); |
870 | PerFunctionPasses.doFinalization(); |
871 | } |
872 | |
873 | { |
874 | PrettyStackTraceString CrashInfo("Per-module optimization passes"); |
875 | PerModulePasses.run(*TheModule); |
876 | } |
877 | |
878 | { |
879 | PrettyStackTraceString CrashInfo("Code generation"); |
880 | CodeGenPasses.run(*TheModule); |
881 | } |
882 | |
883 | if (ThinLinkOS) |
884 | ThinLinkOS->keep(); |
885 | if (DwoOS) |
886 | DwoOS->keep(); |
887 | } |
888 | |
889 | static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) { |
890 | switch (Opts.OptimizationLevel) { |
891 | default: |
892 | llvm_unreachable("Invalid optimization level!"); |
893 | |
894 | case 1: |
895 | return PassBuilder::O1; |
896 | |
897 | case 2: |
898 | switch (Opts.OptimizeSize) { |
899 | default: |
900 | llvm_unreachable("Invalid optimization level for size!"); |
901 | |
902 | case 0: |
903 | return PassBuilder::O2; |
904 | |
905 | case 1: |
906 | return PassBuilder::Os; |
907 | |
908 | case 2: |
909 | return PassBuilder::Oz; |
910 | } |
911 | |
912 | case 3: |
913 | return PassBuilder::O3; |
914 | } |
915 | } |
916 | |
917 | static void addSanitizersAtO0(ModulePassManager &MPM, |
918 | const Triple &TargetTriple, |
919 | const LangOptions &LangOpts, |
920 | const CodeGenOptions &CodeGenOpts) { |
921 | if (LangOpts.Sanitize.has(SanitizerKind::Address)) { |
922 | MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); |
923 | bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address); |
924 | MPM.addPass(createModuleToFunctionPassAdaptor( |
925 | AddressSanitizerPass(, Recover, |
926 | CodeGenOpts.SanitizeAddressUseAfterScope))); |
927 | bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); |
928 | MPM.addPass(ModuleAddressSanitizerPass( |
929 | , Recover, ModuleUseAfterScope, |
930 | CodeGenOpts.SanitizeAddressUseOdrIndicator)); |
931 | } |
932 | |
933 | if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { |
934 | MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass({}))); |
935 | } |
936 | |
937 | if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { |
938 | MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); |
939 | } |
940 | } |
941 | |
942 | |
943 | |
944 | |
945 | |
946 | |
947 | |
948 | |
949 | |
950 | void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( |
951 | BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) { |
952 | TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr); |
953 | setCommandLineOpts(CodeGenOpts); |
954 | |
955 | |
956 | |
957 | CreateTargetMachine( true); |
958 | if (!TM) |
959 | |
960 | return; |
961 | TheModule->setDataLayout(TM->createDataLayout()); |
962 | |
963 | Optional<PGOOptions> PGOOpt; |
964 | |
965 | if (CodeGenOpts.hasProfileIRInstr()) |
966 | |
967 | PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty() |
968 | ? DefaultProfileGenName |
969 | : CodeGenOpts.InstrProfileOutput, |
970 | "", "", PGOOptions::IRInstr, PGOOptions::NoCSAction, |
971 | CodeGenOpts.DebugInfoForProfiling); |
972 | else if (CodeGenOpts.hasProfileIRUse()) { |
973 | |
974 | auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse |
975 | : PGOOptions::NoCSAction; |
976 | PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "", |
977 | CodeGenOpts.ProfileRemappingFile, PGOOptions::IRUse, |
978 | CSAction, CodeGenOpts.DebugInfoForProfiling); |
979 | } else if (!CodeGenOpts.SampleProfileFile.empty()) |
980 | |
981 | PGOOpt = |
982 | PGOOptions(CodeGenOpts.SampleProfileFile, "", |
983 | CodeGenOpts.ProfileRemappingFile, PGOOptions::SampleUse, |
984 | PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling); |
985 | else if (CodeGenOpts.DebugInfoForProfiling) |
986 | |
987 | PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction, |
988 | PGOOptions::NoCSAction, true); |
989 | |
990 | |
991 | if (CodeGenOpts.hasProfileCSIRInstr()) { |
992 | (0) . __assert_fail ("!CodeGenOpts.hasProfileCSIRUse() && \"Cannot have both CSProfileUse pass and CSProfileGen pass at \" \"the same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 994, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!CodeGenOpts.hasProfileCSIRUse() && |
993 | (0) . __assert_fail ("!CodeGenOpts.hasProfileCSIRUse() && \"Cannot have both CSProfileUse pass and CSProfileGen pass at \" \"the same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 994, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot have both CSProfileUse pass and CSProfileGen pass at " |
994 | (0) . __assert_fail ("!CodeGenOpts.hasProfileCSIRUse() && \"Cannot have both CSProfileUse pass and CSProfileGen pass at \" \"the same time\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 994, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "the same time"); |
995 | if (PGOOpt.hasValue()) { |
996 | (0) . __assert_fail ("PGOOpt->Action != PGOOptions..IRInstr && PGOOpt->Action != PGOOptions..SampleUse && \"Cannot run CSProfileGen pass with ProfileGen or SampleUse \" \" pass\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 999, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(PGOOpt->Action != PGOOptions::IRInstr && |
997 | (0) . __assert_fail ("PGOOpt->Action != PGOOptions..IRInstr && PGOOpt->Action != PGOOptions..SampleUse && \"Cannot run CSProfileGen pass with ProfileGen or SampleUse \" \" pass\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 999, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> PGOOpt->Action != PGOOptions::SampleUse && |
998 | (0) . __assert_fail ("PGOOpt->Action != PGOOptions..IRInstr && PGOOpt->Action != PGOOptions..SampleUse && \"Cannot run CSProfileGen pass with ProfileGen or SampleUse \" \" pass\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 999, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "Cannot run CSProfileGen pass with ProfileGen or SampleUse " |
999 | (0) . __assert_fail ("PGOOpt->Action != PGOOptions..IRInstr && PGOOpt->Action != PGOOptions..SampleUse && \"Cannot run CSProfileGen pass with ProfileGen or SampleUse \" \" pass\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 999, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> " pass"); |
1000 | PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty() |
1001 | ? DefaultProfileGenName |
1002 | : CodeGenOpts.InstrProfileOutput; |
1003 | PGOOpt->CSAction = PGOOptions::CSIRInstr; |
1004 | } else |
1005 | PGOOpt = PGOOptions("", |
1006 | CodeGenOpts.InstrProfileOutput.empty() |
1007 | ? DefaultProfileGenName |
1008 | : CodeGenOpts.InstrProfileOutput, |
1009 | "", PGOOptions::NoAction, PGOOptions::CSIRInstr, |
1010 | CodeGenOpts.DebugInfoForProfiling); |
1011 | } |
1012 | |
1013 | PassBuilder PB(TM.get(), PGOOpt); |
1014 | |
1015 | |
1016 | for (auto &PluginFN : CodeGenOpts.PassPlugins) { |
1017 | auto PassPlugin = PassPlugin::Load(PluginFN); |
1018 | if (PassPlugin) { |
1019 | PassPlugin->registerPassBuilderCallbacks(PB); |
1020 | } else { |
1021 | Diags.Report(diag::err_fe_unable_to_load_plugin) |
1022 | << PluginFN << toString(PassPlugin.takeError()); |
1023 | } |
1024 | } |
1025 | |
1026 | LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager); |
1027 | FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager); |
1028 | CGSCCAnalysisManager CGAM(CodeGenOpts.DebugPassManager); |
1029 | ModuleAnalysisManager MAM(CodeGenOpts.DebugPassManager); |
1030 | |
1031 | |
1032 | FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); }); |
1033 | |
1034 | |
1035 | |
1036 | Triple TargetTriple(TheModule->getTargetTriple()); |
1037 | std::unique_ptr<TargetLibraryInfoImpl> TLII( |
1038 | createTLII(TargetTriple, CodeGenOpts)); |
1039 | FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); |
1040 | MAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); |
1041 | |
1042 | |
1043 | PB.registerModuleAnalyses(MAM); |
1044 | PB.registerCGSCCAnalyses(CGAM); |
1045 | PB.registerFunctionAnalyses(FAM); |
1046 | PB.registerLoopAnalyses(LAM); |
1047 | PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); |
1048 | |
1049 | ModulePassManager MPM(CodeGenOpts.DebugPassManager); |
1050 | |
1051 | if (!CodeGenOpts.DisableLLVMPasses) { |
1052 | bool IsThinLTO = CodeGenOpts.PrepareForThinLTO; |
1053 | bool IsLTO = CodeGenOpts.PrepareForLTO; |
1054 | |
1055 | if (CodeGenOpts.OptimizationLevel == 0) { |
1056 | if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts)) |
1057 | MPM.addPass(GCOVProfilerPass(*Options)); |
1058 | |
1059 | |
1060 | |
1061 | MPM.addPass(AlwaysInlinerPass()); |
1062 | |
1063 | |
1064 | if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) |
1065 | MPM.addPass(createModuleToFunctionPassAdaptor(BoundsCheckingPass())); |
1066 | |
1067 | |
1068 | if (IsLTO || IsThinLTO) { |
1069 | MPM.addPass(CanonicalizeAliasesPass()); |
1070 | MPM.addPass(NameAnonGlobalPass()); |
1071 | } |
1072 | } else { |
1073 | |
1074 | |
1075 | PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts); |
1076 | |
1077 | |
1078 | |
1079 | |
1080 | if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) |
1081 | PB.registerScalarOptimizerLateEPCallback( |
1082 | [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { |
1083 | FPM.addPass(BoundsCheckingPass()); |
1084 | }); |
1085 | if (LangOpts.Sanitize.has(SanitizerKind::Memory)) |
1086 | PB.registerOptimizerLastEPCallback( |
1087 | [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { |
1088 | FPM.addPass(MemorySanitizerPass({})); |
1089 | }); |
1090 | if (LangOpts.Sanitize.has(SanitizerKind::Thread)) |
1091 | PB.registerOptimizerLastEPCallback( |
1092 | [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { |
1093 | FPM.addPass(ThreadSanitizerPass()); |
1094 | }); |
1095 | if (LangOpts.Sanitize.has(SanitizerKind::Address)) { |
1096 | PB.registerPipelineStartEPCallback([&](ModulePassManager &MPM) { |
1097 | MPM.addPass( |
1098 | RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); |
1099 | }); |
1100 | bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address); |
1101 | bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope; |
1102 | PB.registerOptimizerLastEPCallback( |
1103 | [Recover, UseAfterScope](FunctionPassManager &FPM, |
1104 | PassBuilder::OptimizationLevel Level) { |
1105 | FPM.addPass(AddressSanitizerPass( |
1106 | , Recover, UseAfterScope)); |
1107 | }); |
1108 | bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); |
1109 | bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator; |
1110 | PB.registerPipelineStartEPCallback( |
1111 | [Recover, ModuleUseAfterScope, |
1112 | UseOdrIndicator](ModulePassManager &MPM) { |
1113 | MPM.addPass(ModuleAddressSanitizerPass( |
1114 | , Recover, ModuleUseAfterScope, |
1115 | UseOdrIndicator)); |
1116 | }); |
1117 | } |
1118 | if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts)) |
1119 | PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) { |
1120 | MPM.addPass(GCOVProfilerPass(*Options)); |
1121 | }); |
1122 | |
1123 | if (IsThinLTO) { |
1124 | MPM = PB.buildThinLTOPreLinkDefaultPipeline( |
1125 | Level, CodeGenOpts.DebugPassManager); |
1126 | MPM.addPass(CanonicalizeAliasesPass()); |
1127 | MPM.addPass(NameAnonGlobalPass()); |
1128 | } else if (IsLTO) { |
1129 | MPM = PB.buildLTOPreLinkDefaultPipeline(Level, |
1130 | CodeGenOpts.DebugPassManager); |
1131 | MPM.addPass(CanonicalizeAliasesPass()); |
1132 | MPM.addPass(NameAnonGlobalPass()); |
1133 | } else { |
1134 | MPM = PB.buildPerModuleDefaultPipeline(Level, |
1135 | CodeGenOpts.DebugPassManager); |
1136 | } |
1137 | } |
1138 | |
1139 | if (CodeGenOpts.OptimizationLevel == 0) |
1140 | addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts); |
1141 | } |
1142 | |
1143 | |
1144 | |
1145 | legacy::PassManager CodeGenPasses; |
1146 | bool NeedCodeGen = false; |
1147 | std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS; |
1148 | |
1149 | |
1150 | switch (Action) { |
1151 | case Backend_EmitNothing: |
1152 | break; |
1153 | |
1154 | case Backend_EmitBC: |
1155 | if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) { |
1156 | if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) { |
1157 | ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile); |
1158 | if (!ThinLinkOS) |
1159 | return; |
1160 | } |
1161 | TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", |
1162 | CodeGenOpts.EnableSplitLTOUnit); |
1163 | MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os() |
1164 | : nullptr)); |
1165 | } else { |
1166 | |
1167 | |
1168 | bool EmitLTOSummary = |
1169 | (CodeGenOpts.PrepareForLTO && |
1170 | !CodeGenOpts.DisableLLVMPasses && |
1171 | llvm::Triple(TheModule->getTargetTriple()).getVendor() != |
1172 | llvm::Triple::Apple); |
1173 | if (EmitLTOSummary) { |
1174 | if (!TheModule->getModuleFlag("ThinLTO")) |
1175 | TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); |
1176 | TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", |
1177 | CodeGenOpts.EnableSplitLTOUnit); |
1178 | } |
1179 | MPM.addPass( |
1180 | BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary)); |
1181 | } |
1182 | break; |
1183 | |
1184 | case Backend_EmitLL: |
1185 | MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); |
1186 | break; |
1187 | |
1188 | case Backend_EmitAssembly: |
1189 | case Backend_EmitMCNull: |
1190 | case Backend_EmitObj: |
1191 | NeedCodeGen = true; |
1192 | CodeGenPasses.add( |
1193 | createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); |
1194 | if (!CodeGenOpts.SplitDwarfFile.empty()) { |
1195 | DwoOS = openOutputFile(CodeGenOpts.SplitDwarfFile); |
1196 | if (!DwoOS) |
1197 | return; |
1198 | } |
1199 | if (!AddEmitPasses(CodeGenPasses, Action, *OS, |
1200 | DwoOS ? &DwoOS->os() : nullptr)) |
1201 | |
1202 | return; |
1203 | break; |
1204 | } |
1205 | |
1206 | |
1207 | cl::PrintOptionValues(); |
1208 | |
1209 | |
1210 | { |
1211 | PrettyStackTraceString CrashInfo("Optimizer"); |
1212 | MPM.run(*TheModule, MAM); |
1213 | } |
1214 | |
1215 | |
1216 | if (NeedCodeGen) { |
1217 | PrettyStackTraceString CrashInfo("Code generation"); |
1218 | CodeGenPasses.run(*TheModule); |
1219 | } |
1220 | |
1221 | if (ThinLinkOS) |
1222 | ThinLinkOS->keep(); |
1223 | if (DwoOS) |
1224 | DwoOS->keep(); |
1225 | } |
1226 | |
1227 | Expected<BitcodeModule> clang::FindThinLTOModule(MemoryBufferRef MBRef) { |
1228 | Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); |
1229 | if (!BMsOrErr) |
1230 | return BMsOrErr.takeError(); |
1231 | |
1232 | |
1233 | |
1234 | if (const BitcodeModule *Bm = FindThinLTOModule(*BMsOrErr)) |
1235 | return *Bm; |
1236 | |
1237 | return make_error<StringError>("Could not find module summary", |
1238 | inconvertibleErrorCode()); |
1239 | } |
1240 | |
1241 | BitcodeModule *clang::FindThinLTOModule(MutableArrayRef<BitcodeModule> BMs) { |
1242 | for (BitcodeModule &BM : BMs) { |
1243 | Expected<BitcodeLTOInfo> LTOInfo = BM.getLTOInfo(); |
1244 | if (LTOInfo && LTOInfo->IsThinLTO) |
1245 | return &BM; |
1246 | } |
1247 | return nullptr; |
1248 | } |
1249 | |
1250 | static void (ModuleSummaryIndex *CombinedIndex, Module *M, |
1251 | const HeaderSearchOptions &, |
1252 | const CodeGenOptions &CGOpts, |
1253 | const clang::TargetOptions &TOpts, |
1254 | const LangOptions &LOpts, |
1255 | std::unique_ptr<raw_pwrite_stream> OS, |
1256 | std::string SampleProfile, |
1257 | std::string ProfileRemapping, |
1258 | BackendAction Action) { |
1259 | StringMap<DenseMap<GlobalValue::GUID, GlobalValueSummary *>> |
1260 | ModuleToDefinedGVSummaries; |
1261 | CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); |
1262 | |
1263 | setCommandLineOpts(CGOpts); |
1264 | |
1265 | |
1266 | |
1267 | |
1268 | FunctionImporter::ImportMapTy ImportList; |
1269 | for (auto &GlobalList : *CombinedIndex) { |
1270 | |
1271 | if (GlobalList.second.SummaryList.empty()) |
1272 | continue; |
1273 | |
1274 | auto GUID = GlobalList.first; |
1275 | for (auto &Summary : GlobalList.second.SummaryList) { |
1276 | |
1277 | |
1278 | if (Summary->modulePath() == M->getModuleIdentifier()) |
1279 | continue; |
1280 | |
1281 | ImportList[Summary->modulePath()].insert(GUID); |
1282 | } |
1283 | } |
1284 | |
1285 | std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports; |
1286 | MapVector<llvm::StringRef, llvm::BitcodeModule> ModuleMap; |
1287 | |
1288 | for (auto &I : ImportList) { |
1289 | ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr = |
1290 | llvm::MemoryBuffer::getFile(I.first()); |
1291 | if (!MBOrErr) { |
1292 | errs() << "Error loading imported file '" << I.first() |
1293 | << "': " << MBOrErr.getError().message() << "\n"; |
1294 | return; |
1295 | } |
1296 | |
1297 | Expected<BitcodeModule> BMOrErr = FindThinLTOModule(**MBOrErr); |
1298 | if (!BMOrErr) { |
1299 | handleAllErrors(BMOrErr.takeError(), [&](ErrorInfoBase &EIB) { |
1300 | errs() << "Error loading imported file '" << I.first() |
1301 | << "': " << EIB.message() << '\n'; |
1302 | }); |
1303 | return; |
1304 | } |
1305 | ModuleMap.insert({I.first(), *BMOrErr}); |
1306 | |
1307 | OwnedImports.push_back(std::move(*MBOrErr)); |
1308 | } |
1309 | auto AddStream = [&](size_t Task) { |
1310 | return llvm::make_unique<lto::NativeObjectStream>(std::move(OS)); |
1311 | }; |
1312 | lto::Config Conf; |
1313 | if (CGOpts.SaveTempsFilePrefix != "") { |
1314 | if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".", |
1315 | false)) { |
1316 | handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { |
1317 | errs() << "Error setting up ThinLTO save-temps: " << EIB.message() |
1318 | << '\n'; |
1319 | }); |
1320 | } |
1321 | } |
1322 | Conf.CPU = TOpts.CPU; |
1323 | Conf.CodeModel = getCodeModel(CGOpts); |
1324 | Conf.MAttrs = TOpts.Features; |
1325 | Conf.RelocModel = CGOpts.RelocationModel; |
1326 | Conf.CGOptLevel = getCGOptLevel(CGOpts); |
1327 | initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts); |
1328 | Conf.SampleProfile = std::move(SampleProfile); |
1329 | |
1330 | |
1331 | if (CGOpts.hasProfileCSIRInstr()) { |
1332 | Conf.RunCSIRInstr = true; |
1333 | Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput); |
1334 | } else if (CGOpts.hasProfileCSIRUse()) { |
1335 | Conf.RunCSIRInstr = false; |
1336 | Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath); |
1337 | } |
1338 | |
1339 | Conf.ProfileRemapping = std::move(ProfileRemapping); |
1340 | Conf.UseNewPM = CGOpts.ExperimentalNewPassManager; |
1341 | Conf.DebugPassManager = CGOpts.DebugPassManager; |
1342 | Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness; |
1343 | Conf.RemarksFilename = CGOpts.OptRecordFile; |
1344 | Conf.RemarksPasses = CGOpts.OptRecordPasses; |
1345 | Conf.DwoPath = CGOpts.SplitDwarfFile; |
1346 | switch (Action) { |
1347 | case Backend_EmitNothing: |
1348 | Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) { |
1349 | return false; |
1350 | }; |
1351 | break; |
1352 | case Backend_EmitLL: |
1353 | Conf.PreCodeGenModuleHook = [&](size_t Task, const Module &Mod) { |
1354 | M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists); |
1355 | return false; |
1356 | }; |
1357 | break; |
1358 | case Backend_EmitBC: |
1359 | Conf.PreCodeGenModuleHook = [&](size_t Task, const Module &Mod) { |
1360 | WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists); |
1361 | return false; |
1362 | }; |
1363 | break; |
1364 | default: |
1365 | Conf.CGFileType = getCodeGenFileType(Action); |
1366 | break; |
1367 | } |
1368 | if (Error E = thinBackend( |
1369 | Conf, -1, AddStream, *M, *CombinedIndex, ImportList, |
1370 | ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) { |
1371 | handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { |
1372 | errs() << "Error running ThinLTO backend: " << EIB.message() << '\n'; |
1373 | }); |
1374 | } |
1375 | } |
1376 | |
1377 | void clang::(DiagnosticsEngine &Diags, |
1378 | const HeaderSearchOptions &, |
1379 | const CodeGenOptions &CGOpts, |
1380 | const clang::TargetOptions &TOpts, |
1381 | const LangOptions &LOpts, |
1382 | const llvm::DataLayout &TDesc, Module *M, |
1383 | BackendAction Action, |
1384 | std::unique_ptr<raw_pwrite_stream> OS) { |
1385 | std::unique_ptr<llvm::Module> EmptyModule; |
1386 | if (!CGOpts.ThinLTOIndexFile.empty()) { |
1387 | |
1388 | |
1389 | |
1390 | Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr = |
1391 | llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile, |
1392 | ); |
1393 | if (!IndexOrErr) { |
1394 | logAllUnhandledErrors(IndexOrErr.takeError(), errs(), |
1395 | "Error loading index file '" + |
1396 | CGOpts.ThinLTOIndexFile + "': "); |
1397 | return; |
1398 | } |
1399 | std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr); |
1400 | |
1401 | |
1402 | |
1403 | if (CombinedIndex) { |
1404 | if (!CombinedIndex->skipModuleByDistributedBackend()) { |
1405 | runThinLTOBackend(CombinedIndex.get(), M, HeaderOpts, CGOpts, TOpts, |
1406 | LOpts, std::move(OS), CGOpts.SampleProfileFile, |
1407 | CGOpts.ProfileRemappingFile, Action); |
1408 | return; |
1409 | } |
1410 | |
1411 | |
1412 | |
1413 | |
1414 | |
1415 | |
1416 | EmptyModule = llvm::make_unique<llvm::Module>("empty", M->getContext()); |
1417 | EmptyModule->setTargetTriple(M->getTargetTriple()); |
1418 | M = EmptyModule.get(); |
1419 | } |
1420 | } |
1421 | |
1422 | EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M); |
1423 | |
1424 | if (CGOpts.ExperimentalNewPassManager) |
1425 | AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS)); |
1426 | else |
1427 | AsmHelper.EmitAssembly(Action, std::move(OS)); |
1428 | |
1429 | |
1430 | |
1431 | if (AsmHelper.TM) { |
1432 | std::string DLDesc = M->getDataLayout().getStringRepresentation(); |
1433 | if (DLDesc != TDesc.getStringRepresentation()) { |
1434 | unsigned DiagID = Diags.getCustomDiagID( |
1435 | DiagnosticsEngine::Error, "backend data layout '%0' does not match " |
1436 | "expected target description '%1'"); |
1437 | Diags.Report(DiagID) << DLDesc << TDesc.getStringRepresentation(); |
1438 | } |
1439 | } |
1440 | } |
1441 | |
1442 | static const char* getSectionNameForBitcode(const Triple &T) { |
1443 | switch (T.getObjectFormat()) { |
1444 | case Triple::MachO: |
1445 | return "__LLVM,__bitcode"; |
1446 | case Triple::COFF: |
1447 | case Triple::ELF: |
1448 | case Triple::Wasm: |
1449 | case Triple::UnknownObjectFormat: |
1450 | return ".llvmbc"; |
1451 | case Triple::XCOFF: |
1452 | llvm_unreachable("XCOFF is not yet implemented"); |
1453 | break; |
1454 | } |
1455 | llvm_unreachable("Unimplemented ObjectFormatType"); |
1456 | } |
1457 | |
1458 | static const char* getSectionNameForCommandline(const Triple &T) { |
1459 | switch (T.getObjectFormat()) { |
1460 | case Triple::MachO: |
1461 | return "__LLVM,__cmdline"; |
1462 | case Triple::COFF: |
1463 | case Triple::ELF: |
1464 | case Triple::Wasm: |
1465 | case Triple::UnknownObjectFormat: |
1466 | return ".llvmcmd"; |
1467 | case Triple::XCOFF: |
1468 | llvm_unreachable("XCOFF is not yet implemented"); |
1469 | break; |
1470 | } |
1471 | llvm_unreachable("Unimplemented ObjectFormatType"); |
1472 | } |
1473 | |
1474 | |
1475 | |
1476 | void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, |
1477 | llvm::MemoryBufferRef Buf) { |
1478 | if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off) |
1479 | return; |
1480 | |
1481 | |
1482 | SmallVector<Constant*, 2> UsedArray; |
1483 | SmallPtrSet<GlobalValue*, 4> UsedGlobals; |
1484 | Type *UsedElementType = Type::getInt8Ty(M->getContext())->getPointerTo(0); |
1485 | GlobalVariable *Used = collectUsedGlobalVariables(*M, UsedGlobals, true); |
1486 | for (auto *GV : UsedGlobals) { |
1487 | if (GV->getName() != "llvm.embedded.module" && |
1488 | GV->getName() != "llvm.cmdline") |
1489 | UsedArray.push_back( |
1490 | ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); |
1491 | } |
1492 | if (Used) |
1493 | Used->eraseFromParent(); |
1494 | |
1495 | |
1496 | std::string Data; |
1497 | ArrayRef<uint8_t> ModuleData; |
1498 | Triple T(M->getTargetTriple()); |
1499 | |
1500 | |
1501 | |
1502 | if (CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker) { |
1503 | if (!isBitcode((const unsigned char *)Buf.getBufferStart(), |
1504 | (const unsigned char *)Buf.getBufferEnd())) { |
1505 | |
1506 | |
1507 | llvm::raw_string_ostream OS(Data); |
1508 | llvm::WriteBitcodeToFile(*M, OS, true); |
1509 | ModuleData = |
1510 | ArrayRef<uint8_t>((const uint8_t *)OS.str().data(), OS.str().size()); |
1511 | } else |
1512 | |
1513 | ModuleData = ArrayRef<uint8_t>((const uint8_t *)Buf.getBufferStart(), |
1514 | Buf.getBufferSize()); |
1515 | } |
1516 | llvm::Constant *ModuleConstant = |
1517 | llvm::ConstantDataArray::get(M->getContext(), ModuleData); |
1518 | llvm::GlobalVariable *GV = new llvm::GlobalVariable( |
1519 | *M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage, |
1520 | ModuleConstant); |
1521 | GV->setSection(getSectionNameForBitcode(T)); |
1522 | UsedArray.push_back( |
1523 | ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); |
1524 | if (llvm::GlobalVariable *Old = |
1525 | M->getGlobalVariable("llvm.embedded.module", true)) { |
1526 | (0) . __assert_fail ("Old->hasOneUse() && \"llvm.embedded.module can only be used once in llvm.compiler.used\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 1527, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Old->hasOneUse() && |
1527 | (0) . __assert_fail ("Old->hasOneUse() && \"llvm.embedded.module can only be used once in llvm.compiler.used\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 1527, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "llvm.embedded.module can only be used once in llvm.compiler.used"); |
1528 | GV->takeName(Old); |
1529 | Old->eraseFromParent(); |
1530 | } else { |
1531 | GV->setName("llvm.embedded.module"); |
1532 | } |
1533 | |
1534 | |
1535 | if (CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode) { |
1536 | |
1537 | ArrayRef<uint8_t> CmdData(const_cast<uint8_t *>(CGOpts.CmdArgs.data()), |
1538 | CGOpts.CmdArgs.size()); |
1539 | llvm::Constant *CmdConstant = |
1540 | llvm::ConstantDataArray::get(M->getContext(), CmdData); |
1541 | GV = new llvm::GlobalVariable(*M, CmdConstant->getType(), true, |
1542 | llvm::GlobalValue::PrivateLinkage, |
1543 | CmdConstant); |
1544 | GV->setSection(getSectionNameForCommandline(T)); |
1545 | UsedArray.push_back( |
1546 | ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType)); |
1547 | if (llvm::GlobalVariable *Old = |
1548 | M->getGlobalVariable("llvm.cmdline", true)) { |
1549 | (0) . __assert_fail ("Old->hasOneUse() && \"llvm.cmdline can only be used once in llvm.compiler.used\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 1550, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Old->hasOneUse() && |
1550 | (0) . __assert_fail ("Old->hasOneUse() && \"llvm.cmdline can only be used once in llvm.compiler.used\"", "/home/seafit/code_projects/clang_source/clang/lib/CodeGen/BackendUtil.cpp", 1550, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "llvm.cmdline can only be used once in llvm.compiler.used"); |
1551 | GV->takeName(Old); |
1552 | Old->eraseFromParent(); |
1553 | } else { |
1554 | GV->setName("llvm.cmdline"); |
1555 | } |
1556 | } |
1557 | |
1558 | if (UsedArray.empty()) |
1559 | return; |
1560 | |
1561 | |
1562 | ArrayType *ATy = ArrayType::get(UsedElementType, UsedArray.size()); |
1563 | auto *NewUsed = new GlobalVariable( |
1564 | *M, ATy, false, llvm::GlobalValue::AppendingLinkage, |
1565 | llvm::ConstantArray::get(ATy, UsedArray), "llvm.compiler.used"); |
1566 | NewUsed->setSection("llvm.metadata"); |
1567 | } |
1568 | |