blob: ba61a93a4d1a0c4493c2362ab98936b2d60a4367 [file] [log] [blame]
Daniel Dunbarf976d1b2010-06-07 23:20:08 +00001//===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Daniel Dunbarf976d1b2010-06-07 23:20:08 +00006//
7//===----------------------------------------------------------------------===//
8
Daniel Dunbarc1b17292010-06-15 17:48:49 +00009#include "clang/CodeGen/BackendUtil.h"
Richard Trieu63688182018-12-11 03:18:39 +000010#include "clang/Basic/CodeGenOptions.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000011#include "clang/Basic/Diagnostic.h"
Dan Gohmanfec0ff82011-07-05 22:02:36 +000012#include "clang/Basic/LangOptions.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000013#include "clang/Basic/TargetOptions.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000014#include "clang/Frontend/FrontendDiagnostic.h"
Kostya Serebryanyce2c7262013-12-27 08:11:08 +000015#include "clang/Frontend/Utils.h"
Saleem Abdulrasool888e2892017-01-05 16:02:32 +000016#include "clang/Lex/HeaderSearchOptions.h"
Hal Finkel1a328f52016-12-15 02:19:17 +000017#include "llvm/ADT/SmallSet.h"
Eric Christopher583a1f72015-09-26 01:25:08 +000018#include "llvm/ADT/StringExtras.h"
Saleem Abdulrasool62849c62014-05-08 02:28:32 +000019#include "llvm/ADT/StringSwitch.h"
Steven Wu27fb5222016-05-11 16:26:03 +000020#include "llvm/ADT/Triple.h"
Evgenii Stepanov2a3723e2020-02-27 15:43:53 -080021#include "llvm/Analysis/StackSafetyAnalysis.h"
Chandler Carruth418bd1a2015-01-15 02:16:55 +000022#include "llvm/Analysis/TargetLibraryInfo.h"
Chandler Carruthaab5ec02015-01-31 11:18:46 +000023#include "llvm/Analysis/TargetTransformInfo.h"
Teresa Johnsonffc4e242016-11-11 05:35:12 +000024#include "llvm/Bitcode/BitcodeReader.h"
Chandler Carruth50f9e892016-12-23 20:44:01 +000025#include "llvm/Bitcode/BitcodeWriter.h"
26#include "llvm/Bitcode/BitcodeWriterPass.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000027#include "llvm/CodeGen/RegAllocRegistry.h"
28#include "llvm/CodeGen/SchedulerRegistry.h"
David Blaikie7a4f7f52018-01-09 22:03:47 +000029#include "llvm/CodeGen/TargetSubtargetInfo.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000030#include "llvm/IR/DataLayout.h"
Chandler Carruth0a50c492014-01-12 11:11:50 +000031#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth9828e692015-02-13 09:57:03 +000032#include "llvm/IR/LegacyPassManager.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000033#include "llvm/IR/Module.h"
Chandler Carruth50f9e892016-12-23 20:44:01 +000034#include "llvm/IR/ModuleSummaryIndex.h"
Chandler Carruthca884742014-01-13 09:26:48 +000035#include "llvm/IR/Verifier.h"
Teresa Johnson9e3f4742016-08-12 18:12:08 +000036#include "llvm/LTO/LTOBackend.h"
Saleem Abdulrasool888e2892017-01-05 16:02:32 +000037#include "llvm/MC/MCAsmInfo.h"
Evan Chengeeb486d2011-06-29 01:14:32 +000038#include "llvm/MC/SubtargetFeature.h"
Chandler Carruth50f9e892016-12-23 20:44:01 +000039#include "llvm/Passes/PassBuilder.h"
Philip Pfaffee3f105c2019-02-02 23:19:32 +000040#include "llvm/Passes/PassPlugin.h"
Taewook Ohd4c50f72019-08-14 07:11:09 +000041#include "llvm/Passes/StandardInstrumentations.h"
David Blaikie9941da42018-11-17 18:04:13 +000042#include "llvm/Support/BuryPointer.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000043#include "llvm/Support/CommandLine.h"
Teresa Johnson9e3f4742016-08-12 18:12:08 +000044#include "llvm/Support/MemoryBuffer.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000045#include "llvm/Support/PrettyStackTrace.h"
Evan Cheng494eb062011-08-24 18:09:14 +000046#include "llvm/Support/TargetRegistry.h"
Anton Afanasyevd880de22019-03-30 08:42:48 +000047#include "llvm/Support/TimeProfiler.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000048#include "llvm/Support/Timer.h"
49#include "llvm/Support/raw_ostream.h"
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000050#include "llvm/Target/TargetMachine.h"
51#include "llvm/Target/TargetOptions.h"
Gor Nishanov97e3b6d2016-10-03 22:44:48 +000052#include "llvm/Transforms/Coroutines.h"
Brian Gesiak048239e2019-12-26 08:00:00 -050053#include "llvm/Transforms/Coroutines/CoroCleanup.h"
54#include "llvm/Transforms/Coroutines/CoroEarly.h"
55#include "llvm/Transforms/Coroutines/CoroElide.h"
56#include "llvm/Transforms/Coroutines/CoroSplit.h"
Rafael Espindola56a7dab02011-08-02 21:51:02 +000057#include "llvm/Transforms/IPO.h"
Chandler Carruthb72c19f2016-08-17 03:09:11 +000058#include "llvm/Transforms/IPO/AlwaysInliner.h"
Teresa Johnson2f63d542020-01-24 12:24:18 -080059#include "llvm/Transforms/IPO/LowerTypeTests.h"
Rafael Espindola56a7dab02011-08-02 21:51:02 +000060#include "llvm/Transforms/IPO/PassManagerBuilder.h"
Tim Shen50fedec2017-06-01 23:27:51 +000061#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
David Blaikied2a572202018-04-24 00:59:22 +000062#include "llvm/Transforms/InstCombine/InstCombine.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000063#include "llvm/Transforms/Instrumentation.h"
Leonard Chan436fb2b2019-02-13 22:22:48 +000064#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
Chandler Carruthafce4492017-11-14 01:47:24 +000065#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
David Blaikie4e1ae832018-03-23 22:16:59 +000066#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
Leonard Chan0cdd3b12019-05-14 21:17:21 +000067#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
Rong Xu4059e142019-04-25 17:52:43 +000068#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
Philip Pfaffe685c76d2019-01-16 09:28:01 +000069#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
Leonard Chan007f6742019-07-25 20:53:15 +000070#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
Philip Pfaffe685c76d2019-01-16 09:28:01 +000071#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
Michael Gottesman90cae772013-01-28 01:36:00 +000072#include "llvm/Transforms/ObjCARC.h"
Rafael Espindola56a7dab02011-08-02 21:51:02 +000073#include "llvm/Transforms/Scalar.h"
Chandler Carruth4ddaadc2016-03-11 09:02:43 +000074#include "llvm/Transforms/Scalar/GVN.h"
David Blaikiec133b1e2018-03-28 17:45:10 +000075#include "llvm/Transforms/Utils.h"
Teresa Johnson6ed79132019-01-04 19:05:01 +000076#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
Leonard Chanb2065132019-06-20 19:35:25 +000077#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"
Tim Shen66470692017-06-29 23:08:38 +000078#include "llvm/Transforms/Utils/NameAnonGlobals.h"
Saleem Abdulrasool76a4b952015-01-09 05:10:20 +000079#include "llvm/Transforms/Utils/SymbolRewriter.h"
Sriraman Tallame8147ad2020-05-07 18:18:37 -070080#include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h"
Ahmed Charlesdfca6f92014-03-09 11:36:40 +000081#include <memory>
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000082using namespace clang;
83using namespace llvm;
84
serge_sans_paille24ab9b52019-06-08 17:37:47 +020085#define HANDLE_EXTENSION(Ext) \
86 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
87#include "llvm/Support/Extension.def"
88
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000089namespace {
90
Davide Italiano945de432017-02-13 16:07:05 +000091// Default filename used for profile generation.
92static constexpr StringLiteral DefaultProfileGenName = "default_%m.profraw";
93
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000094class EmitAssemblyHelper {
David Blaikie9c902b52011-09-25 23:23:43 +000095 DiagnosticsEngine &Diags;
Saleem Abdulrasool888e2892017-01-05 16:02:32 +000096 const HeaderSearchOptions &HSOpts;
Daniel Dunbarf976d1b2010-06-07 23:20:08 +000097 const CodeGenOptions &CodeGenOpts;
Nick Lewycky432add52011-12-02 22:17:00 +000098 const clang::TargetOptions &TargetOpts;
Dan Gohmanfec0ff82011-07-05 22:02:36 +000099 const LangOptions &LangOpts;
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000100 Module *TheModule;
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000101
102 Timer CodeGenerationTime;
103
Peter Collingbourne03f89072016-07-15 00:55:40 +0000104 std::unique_ptr<raw_pwrite_stream> OS;
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000105
Chandler Carruthd294bdb2015-02-01 12:26:23 +0000106 TargetIRAnalysis getTargetIRAnalysis() const {
Chandler Carruthaab5ec02015-01-31 11:18:46 +0000107 if (TM)
Chandler Carruthd294bdb2015-02-01 12:26:23 +0000108 return TM->getTargetIRAnalysis();
Chandler Carruthaab5ec02015-01-31 11:18:46 +0000109
Chandler Carruthd294bdb2015-02-01 12:26:23 +0000110 return TargetIRAnalysis();
Chandler Carruthaab5ec02015-01-31 11:18:46 +0000111 }
112
Teresa Johnson9e3f4742016-08-12 18:12:08 +0000113 void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
Nadav Rotemec57ab32012-10-24 00:53:38 +0000114
Rafael Espindola2f16bc12015-04-14 15:15:49 +0000115 /// Generates the TargetMachine.
Peter Collingbourne03f89072016-07-15 00:55:40 +0000116 /// Leaves TM unchanged if it is unable to create the target machine.
Nadav Rotemdc06b2d2012-10-24 03:52:31 +0000117 /// Some of our clang tests specify triples which are not built
118 /// into clang. This is okay because these tests check the generated
119 /// IR, and they require DataLayout which depends on the triple.
120 /// In this case, we allow this method to fail and not report an error.
121 /// When MustCreateTM is used, we print an error if we are unable to load
122 /// the requested target.
Peter Collingbourne03f89072016-07-15 00:55:40 +0000123 void CreateTargetMachine(bool MustCreateTM);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000124
Rafael Espindola2f16bc12015-04-14 15:15:49 +0000125 /// Add passes necessary to emit assembly or LLVM IR.
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000126 ///
127 /// \return True on success.
Peter Collingbourne03f89072016-07-15 00:55:40 +0000128 bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
Peter Collingbourne91d02842018-05-22 18:52:37 +0000129 raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
130
131 std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
132 std::error_code EC;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000133 auto F = std::make_unique<llvm::ToolOutputFile>(Path, EC,
Fangrui Songd9b948b2019-08-05 05:43:48 +0000134 llvm::sys::fs::OF_None);
Peter Collingbourne91d02842018-05-22 18:52:37 +0000135 if (EC) {
136 Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message();
137 F.reset();
138 }
139 return F;
140 }
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000141
142public:
Saleem Abdulrasool888e2892017-01-05 16:02:32 +0000143 EmitAssemblyHelper(DiagnosticsEngine &_Diags,
144 const HeaderSearchOptions &HeaderSearchOpts,
145 const CodeGenOptions &CGOpts,
Nick Lewycky432add52011-12-02 22:17:00 +0000146 const clang::TargetOptions &TOpts,
Teresa Johnson4b4f4b92016-01-08 17:04:29 +0000147 const LangOptions &LOpts, Module *M)
Saleem Abdulrasool888e2892017-01-05 16:02:32 +0000148 : Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
149 TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
150 CodeGenerationTime("codegen", "Code Generation Time") {}
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000151
152 ~EmitAssemblyHelper() {
Alp Tokerf4e22382013-12-20 20:26:53 +0000153 if (CodeGenOpts.DisableFree)
David Blaikiea97eaa12014-08-29 16:53:14 +0000154 BuryPointer(std::move(TM));
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000155 }
156
Ahmed Charlesb8984322014-03-07 20:03:18 +0000157 std::unique_ptr<TargetMachine> TM;
Alp Tokerf4e22382013-12-20 20:26:53 +0000158
Peter Collingbourne03f89072016-07-15 00:55:40 +0000159 void EmitAssembly(BackendAction Action,
160 std::unique_ptr<raw_pwrite_stream> OS);
Chandler Carruth50f9e892016-12-23 20:44:01 +0000161
162 void EmitAssemblyWithNewPassManager(BackendAction Action,
163 std::unique_ptr<raw_pwrite_stream> OS);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000164};
165
Alexey Samsonovc6515b62012-12-28 09:31:34 +0000166// We need this wrapper to access LangOpts and CGOpts from extension functions
167// that we add to the PassManagerBuilder.
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000168class PassManagerBuilderWrapper : public PassManagerBuilder {
169public:
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000170 PassManagerBuilderWrapper(const Triple &TargetTriple,
171 const CodeGenOptions &CGOpts,
Alexey Samsonov9ab73622012-12-03 19:12:58 +0000172 const LangOptions &LangOpts)
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000173 : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
174 LangOpts(LangOpts) {}
175 const Triple &getTargetTriple() const { return TargetTriple; }
Alexey Samsonov9ab73622012-12-03 19:12:58 +0000176 const CodeGenOptions &getCGOpts() const { return CGOpts; }
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000177 const LangOptions &getLangOpts() const { return LangOpts; }
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000178
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000179private:
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000180 const Triple &TargetTriple;
Alexey Samsonov9ab73622012-12-03 19:12:58 +0000181 const CodeGenOptions &CGOpts;
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000182 const LangOptions &LangOpts;
183};
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000184}
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000185
Dan Gohman5932ce22012-01-17 20:54:51 +0000186static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
187 if (Builder.OptLevel > 0)
188 PM.add(createObjCARCAPElimPass());
189}
190
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000191static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
192 if (Builder.OptLevel > 0)
193 PM.add(createObjCARCExpandPass());
194}
195
196static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
197 if (Builder.OptLevel > 0)
198 PM.add(createObjCARCOptPass());
199}
200
Diego Novillob56be642014-03-03 20:06:18 +0000201static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder,
Chandler Carruth8f4f5092015-02-13 09:47:49 +0000202 legacy::PassManagerBase &PM) {
Diego Novillob56be642014-03-03 20:06:18 +0000203 PM.add(createAddDiscriminatorsPass());
204}
205
Nuno Lopesa4255892012-05-22 17:19:45 +0000206static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
Vitaly Buka9d4eb6f2016-06-02 00:24:20 +0000207 legacy::PassManagerBase &PM) {
Chandler Carruth00a301d2017-11-14 01:30:04 +0000208 PM.add(createBoundsCheckingLegacyPass());
Nuno Lopesa4255892012-05-22 17:19:45 +0000209}
210
Leonard Chan007f6742019-07-25 20:53:15 +0000211static SanitizerCoverageOptions
212getSancovOptsFromCGOpts(const CodeGenOptions &CGOpts) {
Alexey Samsonov3f3b3ab2015-05-07 18:31:29 +0000213 SanitizerCoverageOptions Opts;
214 Opts.CoverageType =
215 static_cast<SanitizerCoverageOptions::Type>(CGOpts.SanitizeCoverageType);
216 Opts.IndirectCalls = CGOpts.SanitizeCoverageIndirectCalls;
217 Opts.TraceBB = CGOpts.SanitizeCoverageTraceBB;
218 Opts.TraceCmp = CGOpts.SanitizeCoverageTraceCmp;
Kostya Serebryany3b419712016-08-30 01:27:03 +0000219 Opts.TraceDiv = CGOpts.SanitizeCoverageTraceDiv;
220 Opts.TraceGep = CGOpts.SanitizeCoverageTraceGep;
Alexey Samsonov3f3b3ab2015-05-07 18:31:29 +0000221 Opts.Use8bitCounters = CGOpts.SanitizeCoverage8bitCounters;
Kostya Serebryanyd4590c72016-02-17 21:34:43 +0000222 Opts.TracePC = CGOpts.SanitizeCoverageTracePC;
Kostya Serebryany60cdd612016-09-14 01:39:49 +0000223 Opts.TracePCGuard = CGOpts.SanitizeCoverageTracePCGuard;
Kostya Serebryany50fb6182017-05-05 23:28:18 +0000224 Opts.NoPrune = CGOpts.SanitizeCoverageNoPrune;
Kostya Serebryany2c2fb882017-06-08 22:58:19 +0000225 Opts.Inline8bitCounters = CGOpts.SanitizeCoverageInline8bitCounters;
Pratyai Mazumderced398f2020-04-09 02:33:36 -0700226 Opts.InlineBoolFlag = CGOpts.SanitizeCoverageInlineBoolFlag;
Kostya Serebryany61457762017-07-28 00:10:10 +0000227 Opts.PCTable = CGOpts.SanitizeCoveragePCTable;
Matt Morehouse5c7fc762017-08-18 18:43:30 +0000228 Opts.StackDepth = CGOpts.SanitizeCoverageStackDepth;
Leonard Chan007f6742019-07-25 20:53:15 +0000229 return Opts;
230}
231
232static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
233 legacy::PassManagerBase &PM) {
234 const PassManagerBuilderWrapper &BuilderWrapper =
235 static_cast<const PassManagerBuilderWrapper &>(Builder);
236 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
237 auto Opts = getSancovOptsFromCGOpts(CGOpts);
Matt Morehousebef187c2020-04-10 10:42:41 -0700238 PM.add(createModuleSanitizerCoverageLegacyPassPass(
239 Opts, CGOpts.SanitizeCoverageWhitelistFiles,
240 CGOpts.SanitizeCoverageBlacklistFiles));
Kostya Serebryany75b4f9e2014-11-11 22:15:07 +0000241}
242
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000243// Check if ASan should use GC-friendly instrumentation for globals.
244// First of all, there is no point if -fdata-sections is off (expect for MachO,
245// where this is not a factor). Also, on ELF this feature requires an assembler
246// extension that only works with -integrated-as at the moment.
247static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
Evgeniy Stepanovd991cdd2017-05-09 21:57:43 +0000248 if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
249 return false;
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000250 switch (T.getObjectFormat()) {
251 case Triple::MachO:
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000252 case Triple::COFF:
Evgeniy Stepanovc7b90942017-04-26 00:51:06 +0000253 return true;
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000254 case Triple::ELF:
255 return CGOpts.DataSections && !CGOpts.DisableIntegratedAS;
Hubert Tong2711e162019-07-19 08:46:18 +0000256 case Triple::XCOFF:
257 llvm::report_fatal_error("ASan not implemented for XCOFF.");
258 case Triple::Wasm:
259 case Triple::UnknownObjectFormat:
260 break;
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000261 }
Hubert Tong2711e162019-07-19 08:46:18 +0000262 return false;
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000263}
264
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000265static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
Chandler Carruth8f4f5092015-02-13 09:47:49 +0000266 legacy::PassManagerBase &PM) {
Yury Gribov5bfeca12015-11-11 10:45:48 +0000267 const PassManagerBuilderWrapper &BuilderWrapper =
268 static_cast<const PassManagerBuilderWrapper&>(Builder);
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000269 const Triple &T = BuilderWrapper.getTargetTriple();
Yury Gribov5bfeca12015-11-11 10:45:48 +0000270 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
271 bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address);
Vitaly Buka9d4eb6f2016-06-02 00:24:20 +0000272 bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope;
Vitaly Buka8076c572018-12-05 01:44:31 +0000273 bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator;
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000274 bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts);
Vitaly Buka9d4eb6f2016-06-02 00:24:20 +0000275 PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover,
276 UseAfterScope));
Leonard Chan436fb2b2019-02-13 22:22:48 +0000277 PM.add(createModuleAddressSanitizerLegacyPassPass(
278 /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator));
Alexander Potapenkob9b73ef2015-06-19 12:19:07 +0000279}
280
281static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder,
282 legacy::PassManagerBase &PM) {
Vitaly Buka9d4eb6f2016-06-02 00:24:20 +0000283 PM.add(createAddressSanitizerFunctionPass(
Andrey Konovalov1ba9d9c2018-04-13 18:05:21 +0000284 /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false));
Leonard Chan436fb2b2019-02-13 22:22:48 +0000285 PM.add(createModuleAddressSanitizerLegacyPassPass(
Vitaly Buka8076c572018-12-05 01:44:31 +0000286 /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true,
287 /*UseOdrIndicator*/ false));
Kostya Serebryany8855ff62011-11-16 17:34:26 +0000288}
289
Evgeniy Stepanov12817e52017-12-09 01:32:07 +0000290static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
291 legacy::PassManagerBase &PM) {
Evgeniy Stepanov3fd1b1a2017-12-20 19:05:44 +0000292 const PassManagerBuilderWrapper &BuilderWrapper =
293 static_cast<const PassManagerBuilderWrapper &>(Builder);
294 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
295 bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
Leonard Chan0cdd3b12019-05-14 21:17:21 +0000296 PM.add(
297 createHWAddressSanitizerLegacyPassPass(/*CompileKernel*/ false, Recover));
Andrey Konovalov1ba9d9c2018-04-13 18:05:21 +0000298}
299
300static void addKernelHWAddressSanitizerPasses(const PassManagerBuilder &Builder,
301 legacy::PassManagerBase &PM) {
Leonard Chan0cdd3b12019-05-14 21:17:21 +0000302 PM.add(createHWAddressSanitizerLegacyPassPass(
Andrey Konovalov1ba9d9c2018-04-13 18:05:21 +0000303 /*CompileKernel*/ true, /*Recover*/ true));
Evgeniy Stepanov12817e52017-12-09 01:32:07 +0000304}
305
Alexander Potapenkod49c32c2018-09-07 09:21:09 +0000306static void addGeneralOptsForMemorySanitizer(const PassManagerBuilder &Builder,
307 legacy::PassManagerBase &PM,
308 bool CompileKernel) {
Evgeniy Stepanovad8ab3d2012-12-24 08:42:34 +0000309 const PassManagerBuilderWrapper &BuilderWrapper =
310 static_cast<const PassManagerBuilderWrapper&>(Builder);
311 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
Evgeniy Stepanov5b5370a2016-11-07 21:02:11 +0000312 int TrackOrigins = CGOpts.SanitizeMemoryTrackOrigins;
313 bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Memory);
Philip Pfaffe0ee6a932019-02-04 21:02:49 +0000314 PM.add(createMemorySanitizerLegacyPassPass(
315 MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
Evgeniy Stepanov10284672013-01-31 09:53:29 +0000316
317 // MemorySanitizer inserts complex instrumentation that mostly follows
318 // the logic of the original code, but operates on "shadow" values.
319 // It can benefit from re-running some general purpose optimization passes.
320 if (Builder.OptLevel > 0) {
321 PM.add(createEarlyCSEPass());
322 PM.add(createReassociatePass());
323 PM.add(createLICMPass());
324 PM.add(createGVNPass());
325 PM.add(createInstructionCombiningPass());
326 PM.add(createDeadStoreEliminationPass());
327 }
Evgeniy Stepanovaea92e52012-12-03 13:20:43 +0000328}
329
Alexander Potapenkod49c32c2018-09-07 09:21:09 +0000330static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
331 legacy::PassManagerBase &PM) {
332 addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ false);
333}
334
335static void addKernelMemorySanitizerPass(const PassManagerBuilder &Builder,
336 legacy::PassManagerBase &PM) {
337 addGeneralOptsForMemorySanitizer(Builder, PM, /*CompileKernel*/ true);
338}
339
Kostya Serebryany28a7a112012-03-01 22:27:08 +0000340static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
Chandler Carruth8f4f5092015-02-13 09:47:49 +0000341 legacy::PassManagerBase &PM) {
Philip Pfaffe685c76d2019-01-16 09:28:01 +0000342 PM.add(createThreadSanitizerLegacyPassPass());
Kostya Serebryany28a7a112012-03-01 22:27:08 +0000343}
344
Peter Collingbournec3772752013-08-07 22:47:34 +0000345static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
Chandler Carruth8f4f5092015-02-13 09:47:49 +0000346 legacy::PassManagerBase &PM) {
Peter Collingbourne276be3c2013-08-14 18:54:18 +0000347 const PassManagerBuilderWrapper &BuilderWrapper =
348 static_cast<const PassManagerBuilderWrapper&>(Builder);
Alexey Samsonovae5804f2014-10-15 20:22:54 +0000349 const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
Alexey Samsonova511cdd2015-02-04 17:40:08 +0000350 PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFiles));
Peter Collingbournec3772752013-08-07 22:47:34 +0000351}
352
Evgenii Stepanov2a3723e2020-02-27 15:43:53 -0800353static void addMemTagOptimizationPasses(const PassManagerBuilder &Builder,
354 legacy::PassManagerBase &PM) {
355 PM.add(createStackSafetyGlobalInfoWrapperPass(/*SetMetadata=*/true));
356}
357
Mehdi Aminied03d942020-04-11 01:00:58 +0000358static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
359 const CodeGenOptions &CodeGenOpts) {
360 TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple);
361
362 switch (CodeGenOpts.getVecLib()) {
363 case CodeGenOptions::Accelerate:
364 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::Accelerate);
365 break;
366 case CodeGenOptions::MASSV:
367 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::MASSV);
368 break;
369 case CodeGenOptions::SVML:
370 TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML);
371 break;
372 default:
373 break;
374 }
375 return TLII;
Rafael Espindolab8a71c52014-08-21 17:58:42 +0000376}
377
Saleem Abdulrasool76a4b952015-01-09 05:10:20 +0000378static void addSymbolRewriterPass(const CodeGenOptions &Opts,
Chandler Carruth8f4f5092015-02-13 09:47:49 +0000379 legacy::PassManager *MPM) {
Saleem Abdulrasool76a4b952015-01-09 05:10:20 +0000380 llvm::SymbolRewriter::RewriteDescriptorList DL;
381
382 llvm::SymbolRewriter::RewriteMapParser MapParser;
383 for (const auto &MapFile : Opts.RewriteMapFiles)
384 MapParser.parse(MapFile, &DL);
385
386 MPM->add(createRewriteSymbolsPass(DL));
387}
388
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000389static CodeGenOpt::Level getCGOptLevel(const CodeGenOptions &CodeGenOpts) {
390 switch (CodeGenOpts.OptimizationLevel) {
391 default:
392 llvm_unreachable("Invalid optimization level!");
393 case 0:
394 return CodeGenOpt::None;
395 case 1:
396 return CodeGenOpt::Less;
397 case 2:
398 return CodeGenOpt::Default; // O2/Os/Oz
399 case 3:
400 return CodeGenOpt::Aggressive;
401 }
402}
403
Rafael Espindolaaa0226e2017-08-03 02:16:28 +0000404static Optional<llvm::CodeModel::Model>
405getCodeModel(const CodeGenOptions &CodeGenOpts) {
406 unsigned CodeModel = llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
David Greenecc69872018-08-22 11:34:28 +0000407 .Case("tiny", llvm::CodeModel::Tiny)
Rafael Espindolaaa0226e2017-08-03 02:16:28 +0000408 .Case("small", llvm::CodeModel::Small)
409 .Case("kernel", llvm::CodeModel::Kernel)
410 .Case("medium", llvm::CodeModel::Medium)
411 .Case("large", llvm::CodeModel::Large)
412 .Case("default", ~1u)
413 .Default(~0u);
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000414 assert(CodeModel != ~0u && "invalid code model!");
Rafael Espindolaaa0226e2017-08-03 02:16:28 +0000415 if (CodeModel == ~1u)
416 return None;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000417 return static_cast<llvm::CodeModel::Model>(CodeModel);
418}
419
Reid Kleckner1dfede32019-11-13 15:17:46 -0800420static CodeGenFileType getCodeGenFileType(BackendAction Action) {
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000421 if (Action == Backend_EmitObj)
Reid Kleckner1dfede32019-11-13 15:17:46 -0800422 return CGFT_ObjectFile;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000423 else if (Action == Backend_EmitMCNull)
Reid Kleckner1dfede32019-11-13 15:17:46 -0800424 return CGFT_Null;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000425 else {
426 assert(Action == Backend_EmitAssembly && "Invalid action!");
Reid Kleckner1dfede32019-11-13 15:17:46 -0800427 return CGFT_AssemblyFile;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000428 }
429}
430
431static void initTargetOptions(llvm::TargetOptions &Options,
432 const CodeGenOptions &CodeGenOpts,
433 const clang::TargetOptions &TargetOpts,
434 const LangOptions &LangOpts,
435 const HeaderSearchOptions &HSOpts) {
436 Options.ThreadModel =
437 llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel)
438 .Case("posix", llvm::ThreadModel::POSIX)
439 .Case("single", llvm::ThreadModel::Single);
440
441 // Set float ABI type.
442 assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" ||
443 CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) &&
444 "Invalid Floating Point ABI!");
445 Options.FloatABIType =
446 llvm::StringSwitch<llvm::FloatABI::ABIType>(CodeGenOpts.FloatABI)
447 .Case("soft", llvm::FloatABI::Soft)
448 .Case("softfp", llvm::FloatABI::Soft)
449 .Case("hard", llvm::FloatABI::Hard)
450 .Default(llvm::FloatABI::Default);
451
452 // Set FP fusion mode.
453 switch (LangOpts.getDefaultFPContractMode()) {
Melanie Blowerc355bec2020-05-04 10:48:12 -0700454 case LangOptions::FPM_Off:
Adam Nemet03af4242017-04-20 17:09:35 +0000455 // Preserve any contraction performed by the front-end. (Strict performs
Raphael Isemannb23ccec2018-12-10 12:37:46 +0000456 // splitting of the muladd intrinsic in the backend.)
Adam Nemet03af4242017-04-20 17:09:35 +0000457 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000458 break;
Melanie Blowerc355bec2020-05-04 10:48:12 -0700459 case LangOptions::FPM_On:
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000460 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
461 break;
Melanie Blowerc355bec2020-05-04 10:48:12 -0700462 case LangOptions::FPM_Fast:
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000463 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
464 break;
465 }
466
467 Options.UseInitArray = CodeGenOpts.UseInitArray;
468 Options.DisableIntegratedAS = CodeGenOpts.DisableIntegratedAS;
Saleem Abdulrasool54448902017-06-09 00:40:30 +0000469 Options.CompressDebugSections = CodeGenOpts.getCompressDebugSections();
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000470 Options.RelaxELFRelocations = CodeGenOpts.RelaxELFRelocations;
471
472 // Set EABI version.
Yuka Takahashidc771502017-07-01 07:57:23 +0000473 Options.EABIVersion = TargetOpts.EABIVersion;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000474
475 if (LangOpts.SjLjExceptions)
476 Options.ExceptionModel = llvm::ExceptionHandling::SjLj;
Martell Malonec950c652017-11-29 07:25:12 +0000477 if (LangOpts.SEHExceptions)
478 Options.ExceptionModel = llvm::ExceptionHandling::WinEH;
479 if (LangOpts.DWARFExceptions)
480 Options.ExceptionModel = llvm::ExceptionHandling::DwarfCFI;
Heejin Ahne8b2b882019-09-12 04:01:37 +0000481 if (LangOpts.WasmExceptions)
482 Options.ExceptionModel = llvm::ExceptionHandling::Wasm;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000483
484 Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
485 Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
486 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
487 Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
488 Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
489 Options.FunctionSections = CodeGenOpts.FunctionSections;
490 Options.DataSections = CodeGenOpts.DataSections;
491 Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
KAWASHIMA Takahiro10c11e42020-01-13 09:28:02 +0000492 Options.TLSSize = CodeGenOpts.TLSSize;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000493 Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
Chih-Hung Hsiehca552b82018-03-01 22:26:19 +0000494 Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000495 Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
Sean Eveson5110d4f2018-01-08 13:42:26 +0000496 Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
Peter Collingbourne14b468b2018-07-18 00:27:07 +0000497 Options.EmitAddrsig = CodeGenOpts.Addrsig;
David Candler92aa0c22019-10-31 08:55:57 +0000498 Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection;
Djordje Todorovicc15c68a2020-03-09 11:02:35 +0100499 Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000500
Aaron Puchertb207bae2019-06-26 21:36:35 +0000501 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000502 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
503 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
504 Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
505 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
506 Options.MCOptions.MCIncrementalLinkerCompatible =
507 CodeGenOpts.IncrementalLinkerCompatible;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000508 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
Brian Cain7b953b62019-08-08 19:19:20 +0000509 Options.MCOptions.MCNoWarn = CodeGenOpts.NoWarn;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000510 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
511 Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
512 Options.MCOptions.ABIName = TargetOpts.ABI;
513 for (const auto &Entry : HSOpts.UserEntries)
514 if (!Entry.IsFramework &&
515 (Entry.Group == frontend::IncludeDirGroup::Quoted ||
516 Entry.Group == frontend::IncludeDirGroup::Angled ||
517 Entry.Group == frontend::IncludeDirGroup::System))
518 Options.MCOptions.IASSearchPaths.push_back(
519 Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
520}
David Blaikie7a4f7f52018-01-09 22:03:47 +0000521static Optional<GCOVOptions> getGCOVOptions(const CodeGenOptions &CodeGenOpts) {
522 if (CodeGenOpts.DisableGCov)
523 return None;
524 if (!CodeGenOpts.EmitGcovArcs && !CodeGenOpts.EmitGcovNotes)
525 return None;
526 // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
527 // LLVM's -default-gcov-version flag is set to something invalid.
528 GCOVOptions Options;
529 Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
530 Options.EmitData = CodeGenOpts.EmitGcovArcs;
531 llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));
532 Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
533 Options.NoRedZone = CodeGenOpts.DisableRedZone;
534 Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData;
Calixte Denizetf4bf6712018-11-17 19:41:39 +0000535 Options.Filter = CodeGenOpts.ProfileFilterFiles;
536 Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
David Blaikie7a4f7f52018-01-09 22:03:47 +0000537 Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody;
538 return Options;
539}
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000540
Rong Xu4059e142019-04-25 17:52:43 +0000541static Optional<InstrProfOptions>
542getInstrProfOptions(const CodeGenOptions &CodeGenOpts,
543 const LangOptions &LangOpts) {
544 if (!CodeGenOpts.hasProfileClangInstr())
545 return None;
546 InstrProfOptions Options;
547 Options.NoRedZone = CodeGenOpts.DisableRedZone;
548 Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
549
550 // TODO: Surface the option to emit atomic profile counter increments at
551 // the driver level.
552 Options.Atomic = LangOpts.Sanitize.has(SanitizerKind::Thread);
553 return Options;
554}
555
Peter Collingbourne03f89072016-07-15 00:55:40 +0000556void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
Teresa Johnson9e3f4742016-08-12 18:12:08 +0000557 legacy::FunctionPassManager &FPM) {
Chandler Carruth93786da2016-12-23 00:23:01 +0000558 // Handle disabling of all LLVM passes, where we want to preserve the
559 // internal module before any optimization.
Steven Wu546a1962015-07-17 20:09:56 +0000560 if (CodeGenOpts.DisableLLVMPasses)
561 return;
562
Marcin Koscielnicki9a063e72016-11-22 20:03:35 +0000563 // Figure out TargetLibraryInfo. This needs to be added to MPM and FPM
564 // manually (and not via PMBuilder), since some passes (eg. InstrProfiling)
565 // are inserted before PMBuilder ones - they'd get the default-constructed
566 // TLI with an unknown target otherwise.
Teresa Johnsonaff22322015-12-07 19:21:34 +0000567 Triple TargetTriple(TheModule->getTargetTriple());
Mehdi Aminied03d942020-04-11 01:00:58 +0000568 std::unique_ptr<TargetLibraryInfoImpl> TLII(
569 createTLII(TargetTriple, CodeGenOpts));
Teresa Johnsonaff22322015-12-07 19:21:34 +0000570
Teresa Johnson2f63d542020-01-24 12:24:18 -0800571 // If we reached here with a non-empty index file name, then the index file
572 // was empty and we are not performing ThinLTO backend compilation (used in
573 // testing in a distributed build environment). Drop any the type test
574 // assume sequences inserted for whole program vtables so that codegen doesn't
575 // complain.
576 if (!CodeGenOpts.ThinLTOIndexFile.empty())
577 MPM.add(createLowerTypeTestsPass(/*ExportSummary=*/nullptr,
578 /*ImportSummary=*/nullptr,
579 /*DropTypeTests=*/true));
580
Evgeniy Stepanovdf217a22017-04-24 19:34:12 +0000581 PassManagerBuilderWrapper PMBuilder(TargetTriple, CodeGenOpts, LangOpts);
582
Chandler Carruthfcd33142016-12-23 01:24:49 +0000583 // At O0 and O1 we only run the always inliner which is more efficient. At
584 // higher optimization levels we run the normal inliner.
585 if (CodeGenOpts.OptimizationLevel <= 1) {
Jun Mad0f4af82020-03-13 15:27:45 +0800586 bool InsertLifetimeIntrinsics = ((CodeGenOpts.OptimizationLevel != 0 &&
587 !CodeGenOpts.DisableLifetimeMarkers) ||
588 LangOpts.Coroutines);
Chandler Carruthfcd33142016-12-23 01:24:49 +0000589 PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
590 } else {
Dehao Chence39fdd2017-03-21 19:55:46 +0000591 // We do not want to inline hot callsites for SamplePGO module-summary build
592 // because profile annotation will happen again in ThinLTO backend, and we
593 // want the IR of the hot path to match the profile.
Chandler Carruthfcd33142016-12-23 01:24:49 +0000594 PMBuilder.Inliner = createFunctionInliningPass(
Dehao Chence39fdd2017-03-21 19:55:46 +0000595 CodeGenOpts.OptimizationLevel, CodeGenOpts.OptimizeSize,
596 (!CodeGenOpts.SampleProfileFile.empty() &&
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +0000597 CodeGenOpts.PrepareForThinLTO));
Teresa Johnsonaff22322015-12-07 19:21:34 +0000598 }
599
Chandler Carruthfcd33142016-12-23 01:24:49 +0000600 PMBuilder.OptLevel = CodeGenOpts.OptimizationLevel;
Chris Lattnerecf0ba52011-05-21 23:50:44 +0000601 PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
Nick Lewyckyd3f3e4f2013-06-25 01:49:44 +0000602 PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
603 PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
Andrew Trickb2a84722011-04-05 18:49:32 +0000604
Chris Lattnerecf0ba52011-05-21 23:50:44 +0000605 PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
Alina Sbirleaa9b9ab82019-04-30 21:29:23 +0000606 // Loop interleaving in the loop vectorizer has historically been set to be
607 // enabled when loop unrolling is enabled.
608 PMBuilder.LoopsInterleaved = CodeGenOpts.UnrollLoops;
Nick Lewyckyf04f2372014-10-24 00:49:29 +0000609 PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +0000610 PMBuilder.PrepareForThinLTO = CodeGenOpts.PrepareForThinLTO;
Teresa Johnson8749d8042015-07-06 16:23:00 +0000611 PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
Hal Finkelce0697f2013-11-17 16:03:29 +0000612 PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000613
Marcin Koscielnicki9a063e72016-11-22 20:03:35 +0000614 MPM.add(new TargetLibraryInfoWrapperPass(*TLII));
615
Justin Lebar5a7df9c2016-04-27 19:12:56 +0000616 if (TM)
Stanislav Mekhanoshin61da0672017-01-26 16:49:21 +0000617 TM->adjustPassManager(PMBuilder);
Justin Lebar5a7df9c2016-04-27 19:12:56 +0000618
Dehao Chen7810d4f2017-02-21 20:36:21 +0000619 if (CodeGenOpts.DebugInfoForProfiling ||
620 !CodeGenOpts.SampleProfileFile.empty())
621 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
622 addAddDiscriminatorsPass);
Diego Novillob56be642014-03-03 20:06:18 +0000623
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000624 // In ObjC ARC mode, add the main ARC optimization passes.
625 if (LangOpts.ObjCAutoRefCount) {
626 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
627 addObjCARCExpandPass);
Dan Gohman5932ce22012-01-17 20:54:51 +0000628 PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
629 addObjCARCAPElimPass);
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000630 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
631 addObjCARCOptPass);
632 }
Kostya Serebryany8855ff62011-11-16 17:34:26 +0000633
Richard Smith10ab78e2019-02-23 21:06:26 +0000634 if (LangOpts.Coroutines)
Brian Gesiak91a4b5a2018-04-01 23:55:21 +0000635 addCoroutinePassesToExtensionPoints(PMBuilder);
636
Alexey Samsonovedf99a92014-11-07 22:29:38 +0000637 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
Nuno Lopesa4255892012-05-22 17:19:45 +0000638 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
639 addBoundsCheckingPass);
640 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
641 addBoundsCheckingPass);
642 }
643
Alexey Samsonovdfa908c2015-05-07 22:34:06 +0000644 if (CodeGenOpts.SanitizeCoverageType ||
645 CodeGenOpts.SanitizeCoverageIndirectCalls ||
646 CodeGenOpts.SanitizeCoverageTraceCmp) {
Kostya Serebryany75b4f9e2014-11-11 22:15:07 +0000647 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
648 addSanitizerCoveragePass);
649 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
650 addSanitizerCoveragePass);
651 }
652
Alexey Samsonovedf99a92014-11-07 22:29:38 +0000653 if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
Kostya Serebryany7e247f22012-10-15 14:22:56 +0000654 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000655 addAddressSanitizerPasses);
Kostya Serebryanyd4768572011-11-30 22:20:21 +0000656 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
Alexey Samsonov0e96bec2012-11-29 22:36:21 +0000657 addAddressSanitizerPasses);
Kostya Serebryany8855ff62011-11-16 17:34:26 +0000658 }
Kostya Serebryany28a7a112012-03-01 22:27:08 +0000659
Alexander Potapenkob9b73ef2015-06-19 12:19:07 +0000660 if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) {
661 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
662 addKernelAddressSanitizerPasses);
663 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
664 addKernelAddressSanitizerPasses);
665 }
666
Evgeniy Stepanov12817e52017-12-09 01:32:07 +0000667 if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) {
668 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
669 addHWAddressSanitizerPasses);
670 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
671 addHWAddressSanitizerPasses);
672 }
673
Andrey Konovalov1ba9d9c2018-04-13 18:05:21 +0000674 if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) {
675 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
676 addKernelHWAddressSanitizerPasses);
677 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
678 addKernelHWAddressSanitizerPasses);
679 }
680
Alexey Samsonovedf99a92014-11-07 22:29:38 +0000681 if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
Evgeniy Stepanovaea92e52012-12-03 13:20:43 +0000682 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
683 addMemorySanitizerPass);
684 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
685 addMemorySanitizerPass);
686 }
687
Alexander Potapenkod49c32c2018-09-07 09:21:09 +0000688 if (LangOpts.Sanitize.has(SanitizerKind::KernelMemory)) {
689 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
690 addKernelMemorySanitizerPass);
691 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
692 addKernelMemorySanitizerPass);
693 }
694
Alexey Samsonovedf99a92014-11-07 22:29:38 +0000695 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
Kostya Serebryanyd18cb502012-03-23 23:25:23 +0000696 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
Kostya Serebryany28a7a112012-03-01 22:27:08 +0000697 addThreadSanitizerPass);
698 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
699 addThreadSanitizerPass);
700 }
701
Alexey Samsonovedf99a92014-11-07 22:29:38 +0000702 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
Peter Collingbournec3772752013-08-07 22:47:34 +0000703 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
704 addDataFlowSanitizerPass);
705 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
706 addDataFlowSanitizerPass);
707 }
708
Evgenii Stepanov2a3723e2020-02-27 15:43:53 -0800709 if (LangOpts.Sanitize.has(SanitizerKind::MemTag)) {
710 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
711 addMemTagOptimizationPasses);
712 }
713
Chris Lattner5c123672011-05-21 20:40:11 +0000714 // Set up the per-function pass manager.
Marcin Koscielnicki9a063e72016-11-22 20:03:35 +0000715 FPM.add(new TargetLibraryInfoWrapperPass(*TLII));
Chris Lattner5c123672011-05-21 20:40:11 +0000716 if (CodeGenOpts.VerifyModule)
Peter Collingbourne03f89072016-07-15 00:55:40 +0000717 FPM.add(createVerifierPass());
Andrew Trickb2a84722011-04-05 18:49:32 +0000718
Chris Lattner5c123672011-05-21 20:40:11 +0000719 // Set up the per-module pass manager.
Saleem Abdulrasool76a4b952015-01-09 05:10:20 +0000720 if (!CodeGenOpts.RewriteMapFiles.empty())
Peter Collingbourne03f89072016-07-15 00:55:40 +0000721 addSymbolRewriterPass(CodeGenOpts, &MPM);
Chris Lattnerd98cec52011-02-18 22:20:38 +0000722
Sriraman Tallame8147ad2020-05-07 18:18:37 -0700723 // Add UniqueInternalLinkageNames Pass which renames internal linkage symbols
724 // with unique names.
725 if (CodeGenOpts.UniqueInternalLinkageNames) {
726 MPM.add(createUniqueInternalLinkageNamesPass());
727 }
728
David Blaikie7a4f7f52018-01-09 22:03:47 +0000729 if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts)) {
730 MPM.add(createGCOVProfilerPass(*Options));
Benjamin Kramer8c305922016-02-02 11:06:51 +0000731 if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo)
Peter Collingbourne03f89072016-07-15 00:55:40 +0000732 MPM.add(createStripSymbolsPass(true));
Nick Lewycky207bce32011-04-21 23:44:07 +0000733 }
Nadav Rotemdc06b2d2012-10-24 03:52:31 +0000734
Rong Xu4059e142019-04-25 17:52:43 +0000735 if (Optional<InstrProfOptions> Options =
736 getInstrProfOptions(CodeGenOpts, LangOpts))
737 MPM.add(createInstrProfilingLegacyPass(*Options, false));
Vedant Kumaree6c2332018-08-16 22:24:47 +0000738
Rong Xua4a09b22019-03-04 20:21:31 +0000739 bool hasIRInstr = false;
Rong Xu522b5cb2016-02-29 18:54:59 +0000740 if (CodeGenOpts.hasProfileIRInstr()) {
Xinliang David Lib65f8ae2016-07-23 04:28:59 +0000741 PMBuilder.EnablePGOInstrGen = true;
Rong Xua4a09b22019-03-04 20:21:31 +0000742 hasIRInstr = true;
743 }
744 if (CodeGenOpts.hasProfileCSIRInstr()) {
745 assert(!CodeGenOpts.hasProfileCSIRUse() &&
746 "Cannot have both CSProfileUse pass and CSProfileGen pass at the "
747 "same time");
748 assert(!hasIRInstr &&
749 "Cannot have both ProfileGen pass and CSProfileGen pass at the "
750 "same time");
751 PMBuilder.EnablePGOCSInstrGen = true;
752 hasIRInstr = true;
753 }
754 if (hasIRInstr) {
Rong Xu522b5cb2016-02-29 18:54:59 +0000755 if (!CodeGenOpts.InstrProfileOutput.empty())
756 PMBuilder.PGOInstrGen = CodeGenOpts.InstrProfileOutput;
757 else
Benjamin Krameradcd0262020-01-28 20:23:46 +0100758 PMBuilder.PGOInstrGen = std::string(DefaultProfileGenName);
Rong Xu522b5cb2016-02-29 18:54:59 +0000759 }
Rong Xua4a09b22019-03-04 20:21:31 +0000760 if (CodeGenOpts.hasProfileIRUse()) {
Rong Xu9c6f1532016-03-02 20:59:36 +0000761 PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
Rong Xua4a09b22019-03-04 20:21:31 +0000762 PMBuilder.EnablePGOCSInstrUse = CodeGenOpts.hasProfileCSIRUse();
763 }
Justin Bogner970ac602014-12-08 19:04:51 +0000764
Dehao Chen5717aff2016-12-14 21:41:04 +0000765 if (!CodeGenOpts.SampleProfileFile.empty())
766 PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile;
Diego Novillod3ef1082015-08-25 15:25:13 +0000767
Peter Collingbourne03f89072016-07-15 00:55:40 +0000768 PMBuilder.populateFunctionPassManager(FPM);
769 PMBuilder.populateModulePassManager(MPM);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000770}
771
David Blaikie6e2ec5f2017-04-19 20:08:21 +0000772static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
Yaxun Liub5e80c32016-04-12 20:22:32 +0000773 SmallVector<const char *, 16> BackendArgs;
774 BackendArgs.push_back("clang"); // Fake program name.
775 if (!CodeGenOpts.DebugPass.empty()) {
776 BackendArgs.push_back("-debug-pass");
777 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
778 }
779 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
780 BackendArgs.push_back("-limit-float-precision");
781 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
782 }
Yaxun Liub5e80c32016-04-12 20:22:32 +0000783 BackendArgs.push_back(nullptr);
784 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
785 BackendArgs.data());
786}
787
Peter Collingbourne03f89072016-07-15 00:55:40 +0000788void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000789 // Create the TargetMachine for generating code.
790 std::string Error;
791 std::string Triple = TheModule->getTargetTriple();
792 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
793 if (!TheTarget) {
Nadav Rotemdc06b2d2012-10-24 03:52:31 +0000794 if (MustCreateTM)
Chad Rosierecafbe62013-03-27 00:14:35 +0000795 Diags.Report(diag::err_fe_unable_to_create_target) << Error;
Peter Collingbourne03f89072016-07-15 00:55:40 +0000796 return;
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000797 }
798
Rafael Espindolaaa0226e2017-08-03 02:16:28 +0000799 Optional<llvm::CodeModel::Model> CM = getCodeModel(CodeGenOpts);
Eric Christopher583a1f72015-09-26 01:25:08 +0000800 std::string FeaturesStr =
801 llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ",");
Rafael Espindolae1d70532018-01-18 00:20:03 +0000802 llvm::Reloc::Model RM = CodeGenOpts.RelocationModel;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000803 CodeGenOpt::Level OptLevel = getCGOptLevel(CodeGenOpts);
Evan Chengdd286bc2011-11-16 08:38:55 +0000804
Nick Lewycky432add52011-12-02 22:17:00 +0000805 llvm::TargetOptions Options;
Teresa Johnson5ed6c102017-03-31 02:05:15 +0000806 initTargetOptions(Options, CodeGenOpts, TargetOpts, LangOpts, HSOpts);
Peter Collingbourne03f89072016-07-15 00:55:40 +0000807 TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
808 Options, RM, CM, OptLevel));
Nadav Rotemec57ab32012-10-24 00:53:38 +0000809}
810
Peter Collingbourne03f89072016-07-15 00:55:40 +0000811bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
812 BackendAction Action,
Peter Collingbourne91d02842018-05-22 18:52:37 +0000813 raw_pwrite_stream &OS,
814 raw_pwrite_stream *DwoOS) {
Chad Rosierb1cfc682012-02-29 20:14:59 +0000815 // Add LibraryInfo.
Daniel Dunbaraa437df2012-10-19 20:10:10 +0000816 llvm::Triple TargetTriple(TheModule->getTargetTriple());
Mehdi Aminied03d942020-04-11 01:00:58 +0000817 std::unique_ptr<TargetLibraryInfoImpl> TLII(
818 createTLII(TargetTriple, CodeGenOpts));
Peter Collingbourne03f89072016-07-15 00:55:40 +0000819 CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
Chad Rosierb1cfc682012-02-29 20:14:59 +0000820
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000821 // Normal mode, emit a .s or .o file by running the code generator. Note,
822 // this also adds codegenerator level optimization passes.
Reid Kleckner1dfede32019-11-13 15:17:46 -0800823 CodeGenFileType CGFT = getCodeGenFileType(Action);
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000824
825 // Add ObjC ARC final-cleanup optimizations. This is done as part of the
826 // "codegen" passes so that it isn't run multiple times when there is
827 // inlining happening.
Steven Wu1d56be82015-05-02 00:56:15 +0000828 if (CodeGenOpts.OptimizationLevel > 0)
Peter Collingbourne03f89072016-07-15 00:55:40 +0000829 CodeGenPasses.add(createObjCARCContractPass());
Dan Gohmanfec0ff82011-07-05 22:02:36 +0000830
Peter Collingbourne91d02842018-05-22 18:52:37 +0000831 if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000832 /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
833 Diags.Report(diag::err_fe_unable_to_interface_with_target);
834 return false;
835 }
836
837 return true;
838}
839
Rafael Espindola2f16bc12015-04-14 15:15:49 +0000840void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
Peter Collingbourne03f89072016-07-15 00:55:40 +0000841 std::unique_ptr<raw_pwrite_stream> OS) {
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +0000842 TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000843
David Blaikie6e2ec5f2017-04-19 20:08:21 +0000844 setCommandLineOpts(CodeGenOpts);
Yaxun Liub5e80c32016-04-12 20:22:32 +0000845
Nadav Rotemdc06b2d2012-10-24 03:52:31 +0000846 bool UsesCodeGen = (Action != Backend_EmitNothing &&
847 Action != Backend_EmitBC &&
848 Action != Backend_EmitLL);
Peter Collingbourne03f89072016-07-15 00:55:40 +0000849 CreateTargetMachine(UsesCodeGen);
Alp Tokerf4e22382013-12-20 20:26:53 +0000850
Rafael Espindolab633d202015-06-23 13:59:36 +0000851 if (UsesCodeGen && !TM)
852 return;
853 if (TM)
Mehdi Aminica3cf9e2015-07-24 16:04:29 +0000854 TheModule->setDataLayout(TM->createDataLayout());
Teresa Johnson4b4f4b92016-01-08 17:04:29 +0000855
Peter Collingbourne03f89072016-07-15 00:55:40 +0000856 legacy::PassManager PerModulePasses;
857 PerModulePasses.add(
858 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
859
860 legacy::FunctionPassManager PerFunctionPasses(TheModule);
861 PerFunctionPasses.add(
862 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
863
Teresa Johnson9e3f4742016-08-12 18:12:08 +0000864 CreatePasses(PerModulePasses, PerFunctionPasses);
Peter Collingbourne03f89072016-07-15 00:55:40 +0000865
866 legacy::PassManager CodeGenPasses;
867 CodeGenPasses.add(
868 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
Nadav Rotemec57ab32012-10-24 00:53:38 +0000869
Peter Collingbourne91d02842018-05-22 18:52:37 +0000870 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
Teresa Johnson488d1dc2017-03-23 19:47:49 +0000871
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000872 switch (Action) {
873 case Backend_EmitNothing:
874 break;
875
876 case Backend_EmitBC:
Eli Friedman53591232018-08-24 19:31:52 +0000877 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
Teresa Johnson488d1dc2017-03-23 19:47:49 +0000878 if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
Peter Collingbourne91d02842018-05-22 18:52:37 +0000879 ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
880 if (!ThinLinkOS)
Teresa Johnson488d1dc2017-03-23 19:47:49 +0000881 return;
Teresa Johnson488d1dc2017-03-23 19:47:49 +0000882 }
Teresa Johnson84cecfc2019-01-11 18:32:07 +0000883 TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
884 CodeGenOpts.EnableSplitLTOUnit);
Peter Collingbourne91d02842018-05-22 18:52:37 +0000885 PerModulePasses.add(createWriteThinLTOBitcodePass(
886 *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +0000887 } else {
888 // Emit a module summary by default for Regular LTO except for ld64
889 // targets
890 bool EmitLTOSummary =
891 (CodeGenOpts.PrepareForLTO &&
Eli Friedman53591232018-08-24 19:31:52 +0000892 !CodeGenOpts.DisableLLVMPasses &&
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +0000893 llvm::Triple(TheModule->getTargetTriple()).getVendor() !=
894 llvm::Triple::Apple);
Teresa Johnson84cecfc2019-01-11 18:32:07 +0000895 if (EmitLTOSummary) {
896 if (!TheModule->getModuleFlag("ThinLTO"))
897 TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
898 TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
Teresa Johnson604f8022019-07-19 23:02:58 +0000899 uint32_t(1));
Teresa Johnson84cecfc2019-01-11 18:32:07 +0000900 }
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +0000901
Teresa Johnson84cecfc2019-01-11 18:32:07 +0000902 PerModulePasses.add(createBitcodeWriterPass(
903 *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +0000904 }
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000905 break;
906
907 case Backend_EmitLL:
Peter Collingbourne03f89072016-07-15 00:55:40 +0000908 PerModulePasses.add(
Duncan P. N. Exon Smithbb9cadf2015-04-15 02:45:28 +0000909 createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000910 break;
911
912 default:
Aaron Puchertb207bae2019-06-26 21:36:35 +0000913 if (!CodeGenOpts.SplitDwarfOutput.empty()) {
Aaron Puchert922759a2019-06-15 14:07:43 +0000914 DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
Peter Collingbourne91d02842018-05-22 18:52:37 +0000915 if (!DwoOS)
916 return;
917 }
918 if (!AddEmitPasses(CodeGenPasses, Action, *OS,
919 DwoOS ? &DwoOS->os() : nullptr))
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000920 return;
921 }
922
Andrew Trick15e36e82011-04-05 18:56:55 +0000923 // Before executing passes, print the final values of the LLVM options.
924 cl::PrintOptionValues();
925
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000926 // Run passes. For now we do all passes at once, but eventually we
927 // would like to have the option of streaming code generation.
928
Peter Collingbourne03f89072016-07-15 00:55:40 +0000929 {
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000930 PrettyStackTraceString CrashInfo("Per-function optimization");
Russell Gallopdf494f72019-12-11 11:49:42 +0000931 llvm::TimeTraceScope TimeScope("PerFunctionPasses");
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000932
Peter Collingbourne03f89072016-07-15 00:55:40 +0000933 PerFunctionPasses.doInitialization();
Yaron Keren10d6d162015-06-05 09:40:53 +0000934 for (Function &F : *TheModule)
935 if (!F.isDeclaration())
Peter Collingbourne03f89072016-07-15 00:55:40 +0000936 PerFunctionPasses.run(F);
937 PerFunctionPasses.doFinalization();
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000938 }
939
Peter Collingbourne03f89072016-07-15 00:55:40 +0000940 {
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000941 PrettyStackTraceString CrashInfo("Per-module optimization passes");
Russell Gallopdf494f72019-12-11 11:49:42 +0000942 llvm::TimeTraceScope TimeScope("PerModulePasses");
Peter Collingbourne03f89072016-07-15 00:55:40 +0000943 PerModulePasses.run(*TheModule);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000944 }
945
Peter Collingbourne03f89072016-07-15 00:55:40 +0000946 {
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000947 PrettyStackTraceString CrashInfo("Code generation");
Russell Gallopdf494f72019-12-11 11:49:42 +0000948 llvm::TimeTraceScope TimeScope("CodeGenPasses");
Peter Collingbourne03f89072016-07-15 00:55:40 +0000949 CodeGenPasses.run(*TheModule);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000950 }
Peter Collingbourne91d02842018-05-22 18:52:37 +0000951
952 if (ThinLinkOS)
953 ThinLinkOS->keep();
954 if (DwoOS)
955 DwoOS->keep();
Daniel Dunbarf976d1b2010-06-07 23:20:08 +0000956}
957
Chandler Carruth50f9e892016-12-23 20:44:01 +0000958static PassBuilder::OptimizationLevel mapToLevel(const CodeGenOptions &Opts) {
959 switch (Opts.OptimizationLevel) {
960 default:
961 llvm_unreachable("Invalid optimization level!");
962
963 case 1:
Mircea Trofin7acfda62020-01-16 08:51:50 -0800964 return PassBuilder::OptimizationLevel::O1;
Chandler Carruth50f9e892016-12-23 20:44:01 +0000965
966 case 2:
967 switch (Opts.OptimizeSize) {
968 default:
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +0000969 llvm_unreachable("Invalid optimization level for size!");
Chandler Carruth50f9e892016-12-23 20:44:01 +0000970
971 case 0:
Mircea Trofin7acfda62020-01-16 08:51:50 -0800972 return PassBuilder::OptimizationLevel::O2;
Chandler Carruth50f9e892016-12-23 20:44:01 +0000973
974 case 1:
Mircea Trofin7acfda62020-01-16 08:51:50 -0800975 return PassBuilder::OptimizationLevel::Os;
Chandler Carruth50f9e892016-12-23 20:44:01 +0000976
977 case 2:
Mircea Trofin7acfda62020-01-16 08:51:50 -0800978 return PassBuilder::OptimizationLevel::Oz;
Chandler Carruth50f9e892016-12-23 20:44:01 +0000979 }
980
981 case 3:
Mircea Trofin7acfda62020-01-16 08:51:50 -0800982 return PassBuilder::OptimizationLevel::O3;
Chandler Carruth50f9e892016-12-23 20:44:01 +0000983 }
984}
985
Brian Gesiak048239e2019-12-26 08:00:00 -0500986static void addCoroutinePassesAtO0(ModulePassManager &MPM,
987 const LangOptions &LangOpts,
988 const CodeGenOptions &CodeGenOpts) {
989 if (!LangOpts.Coroutines)
990 return;
991
992 MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass()));
993
994 CGSCCPassManager CGPM(CodeGenOpts.DebugPassManager);
995 CGPM.addPass(CoroSplitPass());
996 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CoroElidePass()));
997 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
998
999 MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass()));
1000}
1001
Benjamin Kramerba2ea932019-03-28 17:18:42 +00001002static void addSanitizersAtO0(ModulePassManager &MPM,
1003 const Triple &TargetTriple,
1004 const LangOptions &LangOpts,
1005 const CodeGenOptions &CodeGenOpts) {
Petr Hosek366cda02019-05-09 06:09:35 +00001006 auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
Leonard Chan436fb2b2019-02-13 22:22:48 +00001007 MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
Petr Hosek366cda02019-05-09 06:09:35 +00001008 bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
1009 MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
1010 CompileKernel, Recover, CodeGenOpts.SanitizeAddressUseAfterScope)));
Leonard Chan436fb2b2019-02-13 22:22:48 +00001011 bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
Petr Hosek366cda02019-05-09 06:09:35 +00001012 MPM.addPass(
1013 ModuleAddressSanitizerPass(CompileKernel, Recover, ModuleUseAfterScope,
1014 CodeGenOpts.SanitizeAddressUseOdrIndicator));
1015 };
1016
1017 if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
1018 ASanPass(SanitizerKind::Address, /*CompileKernel=*/false);
1019 }
1020
1021 if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) {
1022 ASanPass(SanitizerKind::KernelAddress, /*CompileKernel=*/true);
Leonard Chan436fb2b2019-02-13 22:22:48 +00001023 }
Leonard Chan1a240ed2019-02-20 03:50:11 +00001024
1025 if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
Arthur Eubanks48451ee2020-05-05 13:33:13 -07001026 bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Memory);
1027 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
1028 MPM.addPass(MemorySanitizerPass({TrackOrigins, Recover, false}));
1029 MPM.addPass(createModuleToFunctionPassAdaptor(
1030 MemorySanitizerPass({TrackOrigins, Recover, false})));
Leonard Chan1a240ed2019-02-20 03:50:11 +00001031 }
1032
Petr Hosek366cda02019-05-09 06:09:35 +00001033 if (LangOpts.Sanitize.has(SanitizerKind::KernelMemory)) {
1034 MPM.addPass(createModuleToFunctionPassAdaptor(
1035 MemorySanitizerPass({0, false, /*Kernel=*/true})));
1036 }
1037
Leonard Chan1a240ed2019-02-20 03:50:11 +00001038 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
Vitaly Bukab46dd6e2019-10-11 08:47:03 +00001039 MPM.addPass(ThreadSanitizerPass());
Leonard Chan1a240ed2019-02-20 03:50:11 +00001040 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
1041 }
Leonard Chan436fb2b2019-02-13 22:22:48 +00001042}
1043
Chandler Carruth50f9e892016-12-23 20:44:01 +00001044/// A clean version of `EmitAssembly` that uses the new pass manager.
1045///
1046/// Not all features are currently supported in this system, but where
1047/// necessary it falls back to the legacy pass manager to at least provide
1048/// basic functionality.
1049///
1050/// This API is planned to have its functionality finished and then to replace
1051/// `EmitAssembly` at some point in the future when the default switches.
1052void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
1053 BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) {
Andrew V. Tischenko8ab2c9c2018-04-23 09:22:30 +00001054 TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
David Blaikie6e2ec5f2017-04-19 20:08:21 +00001055 setCommandLineOpts(CodeGenOpts);
Chandler Carruth50f9e892016-12-23 20:44:01 +00001056
Petr Hosek5f2e10e2019-05-06 23:24:17 +00001057 bool RequiresCodeGen = (Action != Backend_EmitNothing &&
1058 Action != Backend_EmitBC &&
1059 Action != Backend_EmitLL);
1060 CreateTargetMachine(RequiresCodeGen);
1061
1062 if (RequiresCodeGen && !TM)
Chandler Carruth50f9e892016-12-23 20:44:01 +00001063 return;
Petr Hosek5f2e10e2019-05-06 23:24:17 +00001064 if (TM)
1065 TheModule->setDataLayout(TM->createDataLayout());
Chandler Carruth50f9e892016-12-23 20:44:01 +00001066
Dehao Chenc76a27e2017-07-27 15:29:53 +00001067 Optional<PGOOptions> PGOOpt;
Davide Italiano945de432017-02-13 16:07:05 +00001068
Dehao Chenc76a27e2017-07-27 15:29:53 +00001069 if (CodeGenOpts.hasProfileIRInstr())
1070 // -fprofile-generate.
1071 PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty()
Benjamin Krameradcd0262020-01-28 20:23:46 +01001072 ? std::string(DefaultProfileGenName)
Dehao Chenc76a27e2017-07-27 15:29:53 +00001073 : CodeGenOpts.InstrProfileOutput,
Rong Xua4a09b22019-03-04 20:21:31 +00001074 "", "", PGOOptions::IRInstr, PGOOptions::NoCSAction,
Richard Smith8654ae52018-10-10 23:13:35 +00001075 CodeGenOpts.DebugInfoForProfiling);
Rong Xua4a09b22019-03-04 20:21:31 +00001076 else if (CodeGenOpts.hasProfileIRUse()) {
Dehao Chenc76a27e2017-07-27 15:29:53 +00001077 // -fprofile-use.
Rong Xua4a09b22019-03-04 20:21:31 +00001078 auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
1079 : PGOOptions::NoCSAction;
1080 PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "",
1081 CodeGenOpts.ProfileRemappingFile, PGOOptions::IRUse,
1082 CSAction, CodeGenOpts.DebugInfoForProfiling);
1083 } else if (!CodeGenOpts.SampleProfileFile.empty())
Dehao Chenc76a27e2017-07-27 15:29:53 +00001084 // -fprofile-sample-use
Rong Xua4a09b22019-03-04 20:21:31 +00001085 PGOOpt =
1086 PGOOptions(CodeGenOpts.SampleProfileFile, "",
1087 CodeGenOpts.ProfileRemappingFile, PGOOptions::SampleUse,
1088 PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling);
Dehao Chenc76a27e2017-07-27 15:29:53 +00001089 else if (CodeGenOpts.DebugInfoForProfiling)
1090 // -fdebug-info-for-profiling
Rong Xua4a09b22019-03-04 20:21:31 +00001091 PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
1092 PGOOptions::NoCSAction, true);
1093
1094 // Check to see if we want to generate a CS profile.
1095 if (CodeGenOpts.hasProfileCSIRInstr()) {
1096 assert(!CodeGenOpts.hasProfileCSIRUse() &&
1097 "Cannot have both CSProfileUse pass and CSProfileGen pass at "
1098 "the same time");
1099 if (PGOOpt.hasValue()) {
1100 assert(PGOOpt->Action != PGOOptions::IRInstr &&
1101 PGOOpt->Action != PGOOptions::SampleUse &&
1102 "Cannot run CSProfileGen pass with ProfileGen or SampleUse "
1103 " pass");
1104 PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
Benjamin Krameradcd0262020-01-28 20:23:46 +01001105 ? std::string(DefaultProfileGenName)
Rong Xua4a09b22019-03-04 20:21:31 +00001106 : CodeGenOpts.InstrProfileOutput;
1107 PGOOpt->CSAction = PGOOptions::CSIRInstr;
1108 } else
1109 PGOOpt = PGOOptions("",
1110 CodeGenOpts.InstrProfileOutput.empty()
Benjamin Krameradcd0262020-01-28 20:23:46 +01001111 ? std::string(DefaultProfileGenName)
Rong Xua4a09b22019-03-04 20:21:31 +00001112 : CodeGenOpts.InstrProfileOutput,
1113 "", PGOOptions::NoAction, PGOOptions::CSIRInstr,
1114 CodeGenOpts.DebugInfoForProfiling);
1115 }
Davide Italiano945de432017-02-13 16:07:05 +00001116
Alina Sbirlea267ac922019-05-23 18:51:02 +00001117 PipelineTuningOptions PTO;
Alina Sbirlea21efe2a2019-05-24 17:40:52 +00001118 PTO.LoopUnrolling = CodeGenOpts.UnrollLoops;
Alina Sbirlea267ac922019-05-23 18:51:02 +00001119 // For historical reasons, loop interleaving is set to mirror setting for loop
1120 // unrolling.
1121 PTO.LoopInterleaving = CodeGenOpts.UnrollLoops;
1122 PTO.LoopVectorization = CodeGenOpts.VectorizeLoop;
1123 PTO.SLPVectorization = CodeGenOpts.VectorizeSLP;
zhizhouy94d91222020-03-31 10:23:17 -07001124 PTO.CallGraphProfile = CodeGenOpts.CallGraphProfile;
Brian Gesiak048239e2019-12-26 08:00:00 -05001125 PTO.Coroutines = LangOpts.Coroutines;
Alina Sbirlea267ac922019-05-23 18:51:02 +00001126
Taewook Ohd4c50f72019-08-14 07:11:09 +00001127 PassInstrumentationCallbacks PIC;
1128 StandardInstrumentations SI;
1129 SI.registerCallbacks(PIC);
1130 PassBuilder PB(TM.get(), PTO, PGOOpt, &PIC);
Chandler Carruth50f9e892016-12-23 20:44:01 +00001131
Philip Pfaffee3f105c2019-02-02 23:19:32 +00001132 // Attempt to load pass plugins and register their callbacks with PB.
1133 for (auto &PluginFN : CodeGenOpts.PassPlugins) {
1134 auto PassPlugin = PassPlugin::Load(PluginFN);
1135 if (PassPlugin) {
1136 PassPlugin->registerPassBuilderCallbacks(PB);
1137 } else {
1138 Diags.Report(diag::err_fe_unable_to_load_plugin)
1139 << PluginFN << toString(PassPlugin.takeError());
1140 }
1141 }
serge_sans_paille24ab9b52019-06-08 17:37:47 +02001142#define HANDLE_EXTENSION(Ext) \
1143 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
1144#include "llvm/Support/Extension.def"
Philip Pfaffee3f105c2019-02-02 23:19:32 +00001145
Craig Topper926b95c2017-11-14 08:48:28 +00001146 LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager);
1147 FunctionAnalysisManager FAM(CodeGenOpts.DebugPassManager);
1148 CGSCCAnalysisManager CGAM(CodeGenOpts.DebugPassManager);
1149 ModuleAnalysisManager MAM(CodeGenOpts.DebugPassManager);
Chandler Carruth50f9e892016-12-23 20:44:01 +00001150
1151 // Register the AA manager first so that our version is the one used.
1152 FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
1153
Chandler Carruth9fdd5fa2017-07-25 10:46:07 +00001154 // Register the target library analysis directly and give it a customized
1155 // preset TLI.
1156 Triple TargetTriple(TheModule->getTargetTriple());
Mehdi Aminied03d942020-04-11 01:00:58 +00001157 std::unique_ptr<TargetLibraryInfoImpl> TLII(
1158 createTLII(TargetTriple, CodeGenOpts));
Chandler Carruth9fdd5fa2017-07-25 10:46:07 +00001159 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
Chandler Carruth9fdd5fa2017-07-25 10:46:07 +00001160
Chandler Carruth50f9e892016-12-23 20:44:01 +00001161 // Register all the basic analyses with the managers.
1162 PB.registerModuleAnalyses(MAM);
1163 PB.registerCGSCCAnalyses(CGAM);
1164 PB.registerFunctionAnalyses(FAM);
1165 PB.registerLoopAnalyses(LAM);
1166 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1167
Tim Shenb13eebe2017-06-29 23:10:13 +00001168 ModulePassManager MPM(CodeGenOpts.DebugPassManager);
Chandler Carruth50f9e892016-12-23 20:44:01 +00001169
Chandler Carruth6d1b83e2016-12-27 00:13:09 +00001170 if (!CodeGenOpts.DisableLLVMPasses) {
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +00001171 bool IsThinLTO = CodeGenOpts.PrepareForThinLTO;
Tim Shen66470692017-06-29 23:08:38 +00001172 bool IsLTO = CodeGenOpts.PrepareForLTO;
1173
Chandler Carruth6d1b83e2016-12-27 00:13:09 +00001174 if (CodeGenOpts.OptimizationLevel == 0) {
Teresa Johnson2f63d542020-01-24 12:24:18 -08001175 // If we reached here with a non-empty index file name, then the index
1176 // file was empty and we are not performing ThinLTO backend compilation
1177 // (used in testing in a distributed build environment). Drop any the type
1178 // test assume sequences inserted for whole program vtables so that
1179 // codegen doesn't complain.
1180 if (!CodeGenOpts.ThinLTOIndexFile.empty())
1181 MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
1182 /*ImportSummary=*/nullptr,
1183 /*DropTypeTests=*/true));
David Blaikieac904d02018-01-23 01:25:24 +00001184 if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts))
1185 MPM.addPass(GCOVProfilerPass(*Options));
Rong Xu4059e142019-04-25 17:52:43 +00001186 if (Optional<InstrProfOptions> Options =
1187 getInstrProfOptions(CodeGenOpts, LangOpts))
1188 MPM.addPass(InstrProfiling(*Options, false));
David Blaikieac904d02018-01-23 01:25:24 +00001189
Chandler Carruth6d1b83e2016-12-27 00:13:09 +00001190 // Build a minimal pipeline based on the semantics required by Clang,
Leonard Chan587497b2019-06-13 16:45:29 +00001191 // which is just that always inlining occurs. Further, disable generating
1192 // lifetime intrinsics to avoid enabling further optimizations during
1193 // code generation.
Jun Mad0f4af82020-03-13 15:27:45 +08001194 // However, we need to insert lifetime intrinsics to avoid invalid access
1195 // caused by multithreaded coroutines.
1196 MPM.addPass(
1197 AlwaysInlinerPass(/*InsertLifetimeIntrinsics=*/LangOpts.Coroutines));
Chandler Carrutha8bd4e32017-11-14 01:59:18 +00001198
Rong Xuca161fa2019-08-01 22:36:34 +00001199 // At -O0, we can still do PGO. Add all the requested passes for
1200 // instrumentation PGO, if requested.
1201 if (PGOOpt && (PGOOpt->Action == PGOOptions::IRInstr ||
1202 PGOOpt->Action == PGOOptions::IRUse))
1203 PB.addPGOInstrPassesForO0(
1204 MPM, CodeGenOpts.DebugPassManager,
1205 /* RunProfileGen */ (PGOOpt->Action == PGOOptions::IRInstr),
1206 /* IsCS */ false, PGOOpt->ProfileFile,
1207 PGOOpt->ProfileRemappingFile);
1208
Chandler Carrutha8bd4e32017-11-14 01:59:18 +00001209 // At -O0 we directly run necessary sanitizer passes.
1210 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1211 MPM.addPass(createModuleToFunctionPassAdaptor(BoundsCheckingPass()));
1212
Sriraman Tallame8147ad2020-05-07 18:18:37 -07001213 // Add UniqueInternalLinkageNames Pass which renames internal linkage
1214 // symbols with unique names.
1215 if (CodeGenOpts.UniqueInternalLinkageNames) {
1216 MPM.addPass(UniqueInternalLinkageNamesPass());
1217 }
1218
Teresa Johnson6ed79132019-01-04 19:05:01 +00001219 // Lastly, add semantically necessary passes for LTO.
1220 if (IsLTO || IsThinLTO) {
1221 MPM.addPass(CanonicalizeAliasesPass());
Tim Shen66470692017-06-29 23:08:38 +00001222 MPM.addPass(NameAnonGlobalPass());
Teresa Johnson6ed79132019-01-04 19:05:01 +00001223 }
Chandler Carruth6d1b83e2016-12-27 00:13:09 +00001224 } else {
Tim Shen66470692017-06-29 23:08:38 +00001225 // Map our optimization levels into one of the distinct levels used to
1226 // configure the pipeline.
Chandler Carruth6d1b83e2016-12-27 00:13:09 +00001227 PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
1228
Teresa Johnson2f63d542020-01-24 12:24:18 -08001229 // If we reached here with a non-empty index file name, then the index
1230 // file was empty and we are not performing ThinLTO backend compilation
1231 // (used in testing in a distributed build environment). Drop any the type
1232 // test assume sequences inserted for whole program vtables so that
1233 // codegen doesn't complain.
1234 if (!CodeGenOpts.ThinLTOIndexFile.empty())
1235 PB.registerPipelineStartEPCallback([](ModulePassManager &MPM) {
1236 MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
1237 /*ImportSummary=*/nullptr,
1238 /*DropTypeTests=*/true));
1239 });
1240
Leonard Chanb2065132019-06-20 19:35:25 +00001241 PB.registerPipelineStartEPCallback([](ModulePassManager &MPM) {
1242 MPM.addPass(createModuleToFunctionPassAdaptor(
1243 EntryExitInstrumenterPass(/*PostInlining=*/false)));
1244 });
1245
Chandler Carrutha8bd4e32017-11-14 01:59:18 +00001246 // Register callbacks to schedule sanitizer passes at the appropriate part of
1247 // the pipeline.
Philip Pfaffe88a13b92019-01-17 10:10:47 +00001248 // FIXME: either handle asan/the remaining sanitizers or error out
Chandler Carrutha8bd4e32017-11-14 01:59:18 +00001249 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1250 PB.registerScalarOptimizerLateEPCallback(
1251 [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
1252 FPM.addPass(BoundsCheckingPass());
1253 });
Vitaly Bukab46dd6e2019-10-11 08:47:03 +00001254 if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
Arthur Eubanks48451ee2020-05-05 13:33:13 -07001255 int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
1256 bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Memory);
1257 PB.registerPipelineStartEPCallback(
1258 [TrackOrigins, Recover](ModulePassManager &MPM) {
1259 MPM.addPass(MemorySanitizerPass({TrackOrigins, Recover, false}));
1260 });
Philip Pfaffe88a13b92019-01-17 10:10:47 +00001261 PB.registerOptimizerLastEPCallback(
Arthur Eubanks48451ee2020-05-05 13:33:13 -07001262 [TrackOrigins, Recover](FunctionPassManager &FPM,
1263 PassBuilder::OptimizationLevel Level) {
1264 FPM.addPass(MemorySanitizerPass({TrackOrigins, Recover, false}));
Philip Pfaffe88a13b92019-01-17 10:10:47 +00001265 });
Vitaly Bukab46dd6e2019-10-11 08:47:03 +00001266 }
1267 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
1268 PB.registerPipelineStartEPCallback(
1269 [](ModulePassManager &MPM) { MPM.addPass(ThreadSanitizerPass()); });
Philip Pfaffe88a13b92019-01-17 10:10:47 +00001270 PB.registerOptimizerLastEPCallback(
1271 [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
1272 FPM.addPass(ThreadSanitizerPass());
1273 });
Vitaly Bukab46dd6e2019-10-11 08:47:03 +00001274 }
Leonard Chan436fb2b2019-02-13 22:22:48 +00001275 if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
1276 PB.registerPipelineStartEPCallback([&](ModulePassManager &MPM) {
1277 MPM.addPass(
1278 RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
1279 });
1280 bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address);
Leonard Chan619b6d52019-02-14 01:07:47 +00001281 bool UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
Leonard Chan436fb2b2019-02-13 22:22:48 +00001282 PB.registerOptimizerLastEPCallback(
Leonard Chan619b6d52019-02-14 01:07:47 +00001283 [Recover, UseAfterScope](FunctionPassManager &FPM,
1284 PassBuilder::OptimizationLevel Level) {
Leonard Chan436fb2b2019-02-13 22:22:48 +00001285 FPM.addPass(AddressSanitizerPass(
Leonard Chan619b6d52019-02-14 01:07:47 +00001286 /*CompileKernel=*/false, Recover, UseAfterScope));
Leonard Chan436fb2b2019-02-13 22:22:48 +00001287 });
1288 bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
Leonard Chan619b6d52019-02-14 01:07:47 +00001289 bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
1290 PB.registerPipelineStartEPCallback(
1291 [Recover, ModuleUseAfterScope,
1292 UseOdrIndicator](ModulePassManager &MPM) {
1293 MPM.addPass(ModuleAddressSanitizerPass(
1294 /*CompileKernel=*/false, Recover, ModuleUseAfterScope,
1295 UseOdrIndicator));
1296 });
Leonard Chan436fb2b2019-02-13 22:22:48 +00001297 }
David Blaikieac904d02018-01-23 01:25:24 +00001298 if (Optional<GCOVOptions> Options = getGCOVOptions(CodeGenOpts))
1299 PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) {
1300 MPM.addPass(GCOVProfilerPass(*Options));
1301 });
Rong Xu4059e142019-04-25 17:52:43 +00001302 if (Optional<InstrProfOptions> Options =
1303 getInstrProfOptions(CodeGenOpts, LangOpts))
1304 PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) {
1305 MPM.addPass(InstrProfiling(*Options, false));
1306 });
Chandler Carrutha8bd4e32017-11-14 01:59:18 +00001307
Sriraman Tallame8147ad2020-05-07 18:18:37 -07001308 // Add UniqueInternalLinkageNames Pass which renames internal linkage
1309 // symbols with unique names.
1310 if (CodeGenOpts.UniqueInternalLinkageNames) {
1311 MPM.addPass(UniqueInternalLinkageNamesPass());
1312 }
1313
Tim Shen66470692017-06-29 23:08:38 +00001314 if (IsThinLTO) {
Tim Shenb13eebe2017-06-29 23:10:13 +00001315 MPM = PB.buildThinLTOPreLinkDefaultPipeline(
1316 Level, CodeGenOpts.DebugPassManager);
Teresa Johnson6ed79132019-01-04 19:05:01 +00001317 MPM.addPass(CanonicalizeAliasesPass());
Tim Shen66470692017-06-29 23:08:38 +00001318 MPM.addPass(NameAnonGlobalPass());
1319 } else if (IsLTO) {
Tim Shenb13eebe2017-06-29 23:10:13 +00001320 MPM = PB.buildLTOPreLinkDefaultPipeline(Level,
1321 CodeGenOpts.DebugPassManager);
Teresa Johnson6ed79132019-01-04 19:05:01 +00001322 MPM.addPass(CanonicalizeAliasesPass());
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +00001323 MPM.addPass(NameAnonGlobalPass());
Tim Shen66470692017-06-29 23:08:38 +00001324 } else {
Tim Shenb13eebe2017-06-29 23:10:13 +00001325 MPM = PB.buildPerModuleDefaultPipeline(Level,
1326 CodeGenOpts.DebugPassManager);
Tim Shen66470692017-06-29 23:08:38 +00001327 }
Chandler Carruth6d1b83e2016-12-27 00:13:09 +00001328 }
Leonard Chan436fb2b2019-02-13 22:22:48 +00001329
Leonard Chan486b1732019-09-08 07:30:17 +00001330 if (CodeGenOpts.SanitizeCoverageType ||
1331 CodeGenOpts.SanitizeCoverageIndirectCalls ||
1332 CodeGenOpts.SanitizeCoverageTraceCmp) {
1333 auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
1334 MPM.addPass(ModuleSanitizerCoveragePass(SancovOpts));
1335 }
1336
Peter Collingbourne3b82b922019-07-17 21:45:19 +00001337 if (LangOpts.Sanitize.has(SanitizerKind::HWAddress)) {
1338 bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::HWAddress);
1339 MPM.addPass(HWAddressSanitizerPass(
1340 /*CompileKernel=*/false, Recover));
1341 }
1342 if (LangOpts.Sanitize.has(SanitizerKind::KernelHWAddress)) {
1343 MPM.addPass(HWAddressSanitizerPass(
1344 /*CompileKernel=*/true, /*Recover=*/true));
1345 }
1346
Evgenii Stepanov2a3723e2020-02-27 15:43:53 -08001347 if (CodeGenOpts.OptimizationLevel > 0 &&
1348 LangOpts.Sanitize.has(SanitizerKind::MemTag)) {
1349 MPM.addPass(StackSafetyGlobalAnnotatorPass());
1350 }
1351
Leonard Chan007f6742019-07-25 20:53:15 +00001352 if (CodeGenOpts.OptimizationLevel == 0) {
Brian Gesiak048239e2019-12-26 08:00:00 -05001353 addCoroutinePassesAtO0(MPM, LangOpts, CodeGenOpts);
Leonard Chan436fb2b2019-02-13 22:22:48 +00001354 addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts);
Leonard Chan007f6742019-07-25 20:53:15 +00001355 }
Chandler Carruth50f9e892016-12-23 20:44:01 +00001356 }
1357
1358 // FIXME: We still use the legacy pass manager to do code generation. We
1359 // create that pass manager here and use it as needed below.
1360 legacy::PassManager CodeGenPasses;
1361 bool NeedCodeGen = false;
Peter Collingbourne91d02842018-05-22 18:52:37 +00001362 std::unique_ptr<llvm::ToolOutputFile> ThinLinkOS, DwoOS;
Chandler Carruth50f9e892016-12-23 20:44:01 +00001363
1364 // Append any output we need to the pass manager.
1365 switch (Action) {
1366 case Backend_EmitNothing:
1367 break;
1368
1369 case Backend_EmitBC:
Eli Friedman53591232018-08-24 19:31:52 +00001370 if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
Tim Shen50fedec2017-06-01 23:27:51 +00001371 if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
Peter Collingbourne91d02842018-05-22 18:52:37 +00001372 ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
1373 if (!ThinLinkOS)
Tim Shen50fedec2017-06-01 23:27:51 +00001374 return;
Tim Shen50fedec2017-06-01 23:27:51 +00001375 }
Teresa Johnson84cecfc2019-01-11 18:32:07 +00001376 TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
1377 CodeGenOpts.EnableSplitLTOUnit);
Peter Collingbourne91d02842018-05-22 18:52:37 +00001378 MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os()
1379 : nullptr));
Tim Shen50fedec2017-06-01 23:27:51 +00001380 } else {
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +00001381 // Emit a module summary by default for Regular LTO except for ld64
1382 // targets
1383 bool EmitLTOSummary =
1384 (CodeGenOpts.PrepareForLTO &&
Eli Friedman53591232018-08-24 19:31:52 +00001385 !CodeGenOpts.DisableLLVMPasses &&
Tobias Edler von Koch7609cb82018-06-22 20:23:21 +00001386 llvm::Triple(TheModule->getTargetTriple()).getVendor() !=
1387 llvm::Triple::Apple);
Teresa Johnson84cecfc2019-01-11 18:32:07 +00001388 if (EmitLTOSummary) {
1389 if (!TheModule->getModuleFlag("ThinLTO"))
1390 TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
1391 TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
Leonard Chan19ec31d2019-08-21 17:24:14 +00001392 uint32_t(1));
Teresa Johnson84cecfc2019-01-11 18:32:07 +00001393 }
1394 MPM.addPass(
1395 BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
Tim Shen50fedec2017-06-01 23:27:51 +00001396 }
Chandler Carruth50f9e892016-12-23 20:44:01 +00001397 break;
1398
1399 case Backend_EmitLL:
1400 MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
1401 break;
1402
1403 case Backend_EmitAssembly:
1404 case Backend_EmitMCNull:
1405 case Backend_EmitObj:
1406 NeedCodeGen = true;
1407 CodeGenPasses.add(
1408 createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
Aaron Puchertb207bae2019-06-26 21:36:35 +00001409 if (!CodeGenOpts.SplitDwarfOutput.empty()) {
Aaron Puchert922759a2019-06-15 14:07:43 +00001410 DwoOS = openOutputFile(CodeGenOpts.SplitDwarfOutput);
Peter Collingbourne91d02842018-05-22 18:52:37 +00001411 if (!DwoOS)
1412 return;
1413 }
1414 if (!AddEmitPasses(CodeGenPasses, Action, *OS,
1415 DwoOS ? &DwoOS->os() : nullptr))
Chandler Carruth50f9e892016-12-23 20:44:01 +00001416 // FIXME: Should we handle this error differently?
1417 return;
1418 break;
1419 }
1420
1421 // Before executing passes, print the final values of the LLVM options.
1422 cl::PrintOptionValues();
1423
1424 // Now that we have all of the passes ready, run them.
1425 {
1426 PrettyStackTraceString CrashInfo("Optimizer");
1427 MPM.run(*TheModule, MAM);
1428 }
1429
1430 // Now if needed, run the legacy PM for codegen.
1431 if (NeedCodeGen) {
1432 PrettyStackTraceString CrashInfo("Code generation");
1433 CodeGenPasses.run(*TheModule);
1434 }
Peter Collingbourne91d02842018-05-22 18:52:37 +00001435
1436 if (ThinLinkOS)
1437 ThinLinkOS->keep();
1438 if (DwoOS)
1439 DwoOS->keep();
Chandler Carruth50f9e892016-12-23 20:44:01 +00001440}
1441
Peter Collingbourne47d23642017-01-24 19:54:37 +00001442Expected<BitcodeModule> clang::FindThinLTOModule(MemoryBufferRef MBRef) {
1443 Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
1444 if (!BMsOrErr)
1445 return BMsOrErr.takeError();
1446
Peter Collingbournedbd2fed2017-06-15 17:26:13 +00001447 // The bitcode file may contain multiple modules, we want the one that is
1448 // marked as being the ThinLTO module.
Vitaly Bukac35ff822018-02-16 23:34:16 +00001449 if (const BitcodeModule *Bm = FindThinLTOModule(*BMsOrErr))
1450 return *Bm;
Peter Collingbourne47d23642017-01-24 19:54:37 +00001451
1452 return make_error<StringError>("Could not find module summary",
1453 inconvertibleErrorCode());
1454}
1455
Vitaly Bukac35ff822018-02-16 23:34:16 +00001456BitcodeModule *clang::FindThinLTOModule(MutableArrayRef<BitcodeModule> BMs) {
1457 for (BitcodeModule &BM : BMs) {
1458 Expected<BitcodeLTOInfo> LTOInfo = BM.getLTOInfo();
1459 if (LTOInfo && LTOInfo->IsThinLTO)
1460 return &BM;
1461 }
1462 return nullptr;
1463}
1464
Teresa Johnsoncffeb542017-01-06 23:37:33 +00001465static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
Teresa Johnson5ed6c102017-03-31 02:05:15 +00001466 const HeaderSearchOptions &HeaderOpts,
1467 const CodeGenOptions &CGOpts,
1468 const clang::TargetOptions &TOpts,
1469 const LangOptions &LOpts,
Dehao Chena1bd2d62017-01-13 00:51:55 +00001470 std::unique_ptr<raw_pwrite_stream> OS,
Teresa Johnson5ed6c102017-03-31 02:05:15 +00001471 std::string SampleProfile,
Richard Smith8654ae52018-10-10 23:13:35 +00001472 std::string ProfileRemapping,
Teresa Johnson5ed6c102017-03-31 02:05:15 +00001473 BackendAction Action) {
Dehao Chen5f83d0e2017-07-10 20:31:37 +00001474 StringMap<DenseMap<GlobalValue::GUID, GlobalValueSummary *>>
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001475 ModuleToDefinedGVSummaries;
1476 CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1477
David Blaikie6e2ec5f2017-04-19 20:08:21 +00001478 setCommandLineOpts(CGOpts);
1479
Teresa Johnsonf9b17d42016-12-28 18:00:08 +00001480 // We can simply import the values mentioned in the combined index, since
1481 // we should only invoke this using the individual indexes written out
1482 // via a WriteIndexesThinBackend.
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001483 FunctionImporter::ImportMapTy ImportList;
Teresa Johnsonf9b17d42016-12-28 18:00:08 +00001484 for (auto &GlobalList : *CombinedIndex) {
Peter Collingbourne9667b912017-05-04 18:03:25 +00001485 // Ignore entries for undefined references.
1486 if (GlobalList.second.SummaryList.empty())
1487 continue;
1488
Teresa Johnsonf9b17d42016-12-28 18:00:08 +00001489 auto GUID = GlobalList.first;
Teresa Johnson5ed8b002018-11-29 17:02:59 +00001490 for (auto &Summary : GlobalList.second.SummaryList) {
1491 // Skip the summaries for the importing module. These are included to
1492 // e.g. record required linkage changes.
1493 if (Summary->modulePath() == M->getModuleIdentifier())
1494 continue;
1495 // Add an entry to provoke importing by thinBackend.
1496 ImportList[Summary->modulePath()].insert(GUID);
1497 }
Teresa Johnsonf9b17d42016-12-28 18:00:08 +00001498 }
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001499
1500 std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports;
Peter Collingbourne1a0720e2016-12-14 01:17:59 +00001501 MapVector<llvm::StringRef, llvm::BitcodeModule> ModuleMap;
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001502
1503 for (auto &I : ImportList) {
1504 ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr =
1505 llvm::MemoryBuffer::getFile(I.first());
1506 if (!MBOrErr) {
1507 errs() << "Error loading imported file '" << I.first()
1508 << "': " << MBOrErr.getError().message() << "\n";
1509 return;
1510 }
Peter Collingbourne1a0720e2016-12-14 01:17:59 +00001511
Peter Collingbourne47d23642017-01-24 19:54:37 +00001512 Expected<BitcodeModule> BMOrErr = FindThinLTOModule(**MBOrErr);
1513 if (!BMOrErr) {
1514 handleAllErrors(BMOrErr.takeError(), [&](ErrorInfoBase &EIB) {
Peter Collingbourne1a0720e2016-12-14 01:17:59 +00001515 errs() << "Error loading imported file '" << I.first()
1516 << "': " << EIB.message() << '\n';
1517 });
1518 return;
1519 }
Peter Collingbourne47d23642017-01-24 19:54:37 +00001520 ModuleMap.insert({I.first(), *BMOrErr});
Peter Collingbourne1a0720e2016-12-14 01:17:59 +00001521
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001522 OwnedImports.push_back(std::move(*MBOrErr));
1523 }
Peter Collingbourne2d3a26f2016-09-23 21:43:51 +00001524 auto AddStream = [&](size_t Task) {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00001525 return std::make_unique<lto::NativeObjectStream>(std::move(OS));
Mehdi Amini406aa222016-08-17 06:23:08 +00001526 };
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001527 lto::Config Conf;
Teresa Johnson9e4321c2018-04-17 16:39:25 +00001528 if (CGOpts.SaveTempsFilePrefix != "") {
1529 if (Error E = Conf.addSaveTemps(CGOpts.SaveTempsFilePrefix + ".",
1530 /* UseInputModulePath */ false)) {
1531 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1532 errs() << "Error setting up ThinLTO save-temps: " << EIB.message()
1533 << '\n';
1534 });
1535 }
1536 }
Teresa Johnson5ed6c102017-03-31 02:05:15 +00001537 Conf.CPU = TOpts.CPU;
1538 Conf.CodeModel = getCodeModel(CGOpts);
1539 Conf.MAttrs = TOpts.Features;
Rafael Espindolae1d70532018-01-18 00:20:03 +00001540 Conf.RelocModel = CGOpts.RelocationModel;
Teresa Johnson5ed6c102017-03-31 02:05:15 +00001541 Conf.CGOptLevel = getCGOptLevel(CGOpts);
Teresa Johnson867bc392019-04-23 18:56:19 +00001542 Conf.OptLevel = CGOpts.OptimizationLevel;
Teresa Johnson5ed6c102017-03-31 02:05:15 +00001543 initTargetOptions(Conf.Options, CGOpts, TOpts, LOpts, HeaderOpts);
Benjamin Kramerf6021ec2017-03-21 21:35:04 +00001544 Conf.SampleProfile = std::move(SampleProfile);
Wei Mi21a47102020-01-09 20:58:31 -08001545 Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops;
1546 // For historical reasons, loop interleaving is set to mirror setting for loop
1547 // unrolling.
1548 Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops;
1549 Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop;
1550 Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP;
zhizhouy94d91222020-03-31 10:23:17 -07001551 Conf.PTO.CallGraphProfile = CGOpts.CallGraphProfile;
Rong Xua4a09b22019-03-04 20:21:31 +00001552
1553 // Context sensitive profile.
1554 if (CGOpts.hasProfileCSIRInstr()) {
1555 Conf.RunCSIRInstr = true;
1556 Conf.CSIRProfile = std::move(CGOpts.InstrProfileOutput);
1557 } else if (CGOpts.hasProfileCSIRUse()) {
1558 Conf.RunCSIRInstr = false;
1559 Conf.CSIRProfile = std::move(CGOpts.ProfileInstrumentUsePath);
1560 }
1561
Richard Smith8654ae52018-10-10 23:13:35 +00001562 Conf.ProfileRemapping = std::move(ProfileRemapping);
Tim Shen50fedec2017-06-01 23:27:51 +00001563 Conf.UseNewPM = CGOpts.ExperimentalNewPassManager;
Teresa Johnson4cd016ab2017-11-13 15:38:33 +00001564 Conf.DebugPassManager = CGOpts.DebugPassManager;
Teresa Johnson66744f82018-05-05 14:37:29 +00001565 Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
1566 Conf.RemarksFilename = CGOpts.OptRecordFile;
Francis Visoiu Mistrihdd422362019-03-12 21:22:27 +00001567 Conf.RemarksPasses = CGOpts.OptRecordPasses;
Francis Visoiu Mistrih34667512019-06-17 16:06:00 +00001568 Conf.RemarksFormat = CGOpts.OptRecordFormat;
Aaron Pucherte1dc4952019-06-15 15:38:51 +00001569 Conf.SplitDwarfFile = CGOpts.SplitDwarfFile;
1570 Conf.SplitDwarfOutput = CGOpts.SplitDwarfOutput;
Teresa Johnsonb637cb02017-03-31 22:35:47 +00001571 switch (Action) {
1572 case Backend_EmitNothing:
1573 Conf.PreCodeGenModuleHook = [](size_t Task, const Module &Mod) {
1574 return false;
1575 };
1576 break;
1577 case Backend_EmitLL:
1578 Conf.PreCodeGenModuleHook = [&](size_t Task, const Module &Mod) {
1579 M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
1580 return false;
1581 };
1582 break;
1583 case Backend_EmitBC:
1584 Conf.PreCodeGenModuleHook = [&](size_t Task, const Module &Mod) {
Rafael Espindola76c8f822018-02-14 19:11:37 +00001585 WriteBitcodeToFile(*M, *OS, CGOpts.EmitLLVMUseLists);
Teresa Johnsonb637cb02017-03-31 22:35:47 +00001586 return false;
1587 };
1588 break;
1589 default:
1590 Conf.CGFileType = getCodeGenFileType(Action);
1591 break;
1592 }
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001593 if (Error E = thinBackend(
Teresa Johnson66744f82018-05-05 14:37:29 +00001594 Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001595 ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) {
1596 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
1597 errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
1598 });
1599 }
1600}
1601
David Blaikie9c902b52011-09-25 23:23:43 +00001602void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
Saleem Abdulrasool888e2892017-01-05 16:02:32 +00001603 const HeaderSearchOptions &HeaderOpts,
David Blaikie9c902b52011-09-25 23:23:43 +00001604 const CodeGenOptions &CGOpts,
Nick Lewycky432add52011-12-02 22:17:00 +00001605 const clang::TargetOptions &TOpts,
Saleem Abdulrasool888e2892017-01-05 16:02:32 +00001606 const LangOptions &LOpts,
1607 const llvm::DataLayout &TDesc, Module *M,
1608 BackendAction Action,
Peter Collingbourne03f89072016-07-15 00:55:40 +00001609 std::unique_ptr<raw_pwrite_stream> OS) {
Anton Afanasyevd880de22019-03-30 08:42:48 +00001610
Russell Gallopdf494f72019-12-11 11:49:42 +00001611 llvm::TimeTraceScope TimeScope("Backend");
Anton Afanasyevd880de22019-03-30 08:42:48 +00001612
Vitaly Buka769134d2018-02-16 23:38:22 +00001613 std::unique_ptr<llvm::Module> EmptyModule;
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001614 if (!CGOpts.ThinLTOIndexFile.empty()) {
Teresa Johnsoncffeb542017-01-06 23:37:33 +00001615 // If we are performing a ThinLTO importing compile, load the function index
1616 // into memory and pass it into runThinLTOBackend, which will run the
1617 // function importer and invoke LTO passes.
1618 Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
Teresa Johnson517729f2017-05-12 19:32:17 +00001619 llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile,
1620 /*IgnoreEmptyThinLTOIndexFile*/true);
Teresa Johnsoncffeb542017-01-06 23:37:33 +00001621 if (!IndexOrErr) {
1622 logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
1623 "Error loading index file '" +
1624 CGOpts.ThinLTOIndexFile + "': ");
1625 return;
1626 }
1627 std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
1628 // A null CombinedIndex means we should skip ThinLTO compilation
1629 // (LLVM will optionally ignore empty index files, returning null instead
1630 // of an error).
Vitaly Buka769134d2018-02-16 23:38:22 +00001631 if (CombinedIndex) {
1632 if (!CombinedIndex->skipModuleByDistributedBackend()) {
1633 runThinLTOBackend(CombinedIndex.get(), M, HeaderOpts, CGOpts, TOpts,
1634 LOpts, std::move(OS), CGOpts.SampleProfileFile,
Richard Smith8654ae52018-10-10 23:13:35 +00001635 CGOpts.ProfileRemappingFile, Action);
Vitaly Buka769134d2018-02-16 23:38:22 +00001636 return;
1637 }
1638 // Distributed indexing detected that nothing from the module is needed
1639 // for the final linking. So we can skip the compilation. We sill need to
1640 // output an empty object file to make sure that a linker does not fail
1641 // trying to read it. Also for some features, like CFI, we must skip
1642 // the compilation as CombinedIndex does not contain all required
1643 // information.
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00001644 EmptyModule = std::make_unique<llvm::Module>("empty", M->getContext());
Vitaly Buka769134d2018-02-16 23:38:22 +00001645 EmptyModule->setTargetTriple(M->getTargetTriple());
1646 M = EmptyModule.get();
Teresa Johnsoncffeb542017-01-06 23:37:33 +00001647 }
Teresa Johnson9e3f4742016-08-12 18:12:08 +00001648 }
1649
Saleem Abdulrasool888e2892017-01-05 16:02:32 +00001650 EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);
Daniel Dunbarf976d1b2010-06-07 23:20:08 +00001651
Chandler Carruth50f9e892016-12-23 20:44:01 +00001652 if (CGOpts.ExperimentalNewPassManager)
1653 AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
1654 else
1655 AsmHelper.EmitAssembly(Action, std::move(OS));
Alp Tokere83b9062014-01-02 15:08:04 +00001656
James Y Knightb214cbc2016-03-04 19:00:41 +00001657 // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
1658 // DataLayout.
1659 if (AsmHelper.TM) {
Mehdi Aminica3cf9e2015-07-24 16:04:29 +00001660 std::string DLDesc = M->getDataLayout().getStringRepresentation();
James Y Knightb214cbc2016-03-04 19:00:41 +00001661 if (DLDesc != TDesc.getStringRepresentation()) {
Alp Tokere83b9062014-01-02 15:08:04 +00001662 unsigned DiagID = Diags.getCustomDiagID(
1663 DiagnosticsEngine::Error, "backend data layout '%0' does not match "
1664 "expected target description '%1'");
James Y Knightb214cbc2016-03-04 19:00:41 +00001665 Diags.Report(DiagID) << DLDesc << TDesc.getStringRepresentation();
Alp Tokere83b9062014-01-02 15:08:04 +00001666 }
1667 }
Daniel Dunbarf976d1b2010-06-07 23:20:08 +00001668}
Steven Wu27fb5222016-05-11 16:26:03 +00001669
Steven Wu27fb5222016-05-11 16:26:03 +00001670// With -fembed-bitcode, save a copy of the llvm IR as data in the
1671// __LLVM,__bitcode section.
1672void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
1673 llvm::MemoryBufferRef Buf) {
1674 if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
1675 return;
Teresa Johnsonc8e0bb32019-12-12 11:59:36 -08001676 llvm::EmbedBitcodeInModule(
1677 *M, Buf, CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Marker,
1678 CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode,
1679 &CGOpts.CmdArgs);
Steven Wu27fb5222016-05-11 16:26:03 +00001680}