blob: 41f21312bc29b311ee58480a52ab530c29dd5f23 [file] [log] [blame]
Daniel Dunbar897c6762010-06-07 23:20:08 +00001//===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Dunbar9b414d32010-06-15 17:48:49 +000010#include "clang/CodeGen/BackendUtil.h"
Daniel Dunbar897c6762010-06-07 23:20:08 +000011#include "clang/Basic/Diagnostic.h"
Dan Gohmanb18b8ad2011-07-05 22:02:36 +000012#include "clang/Basic/LangOptions.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000013#include "clang/Basic/TargetOptions.h"
Chandler Carruth06057ce2010-06-15 23:19:56 +000014#include "clang/Frontend/CodeGenOptions.h"
Daniel Dunbar897c6762010-06-07 23:20:08 +000015#include "clang/Frontend/FrontendDiagnostic.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070016#include "clang/Frontend/Utils.h"
Stephen Hines6bcf27b2014-05-29 04:14:42 -070017#include "llvm/ADT/StringSwitch.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070018#include "llvm/Bitcode/BitcodeWriterPass.h"
Daniel Dunbar897c6762010-06-07 23:20:08 +000019#include "llvm/CodeGen/RegAllocRegistry.h"
20#include "llvm/CodeGen/SchedulerRegistry.h"
Chandler Carruth3b844ba2013-01-02 11:45:17 +000021#include "llvm/IR/DataLayout.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070022#include "llvm/IR/IRPrintingPasses.h"
Chandler Carruth3b844ba2013-01-02 11:45:17 +000023#include "llvm/IR/Module.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070024#include "llvm/IR/Verifier.h"
Evan Cheng693769c2011-06-29 01:14:32 +000025#include "llvm/MC/SubtargetFeature.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000026#include "llvm/PassManager.h"
Daniel Dunbar897c6762010-06-07 23:20:08 +000027#include "llvm/Support/CommandLine.h"
28#include "llvm/Support/FormattedStream.h"
29#include "llvm/Support/PrettyStackTrace.h"
Evan Chenga6b40452011-08-24 18:09:14 +000030#include "llvm/Support/TargetRegistry.h"
Daniel Dunbar897c6762010-06-07 23:20:08 +000031#include "llvm/Support/Timer.h"
32#include "llvm/Support/raw_ostream.h"
Rafael Espindolacf565c52011-08-02 21:51:02 +000033#include "llvm/Target/TargetLibraryInfo.h"
Daniel Dunbar897c6762010-06-07 23:20:08 +000034#include "llvm/Target/TargetMachine.h"
35#include "llvm/Target/TargetOptions.h"
Stephen Hines176edba2014-12-01 14:53:08 -080036#include "llvm/Target/TargetSubtargetInfo.h"
Rafael Espindolacf565c52011-08-02 21:51:02 +000037#include "llvm/Transforms/IPO.h"
38#include "llvm/Transforms/IPO/PassManagerBuilder.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000039#include "llvm/Transforms/Instrumentation.h"
Michael Gottesman23d5b092013-01-28 01:36:00 +000040#include "llvm/Transforms/ObjCARC.h"
Rafael Espindolacf565c52011-08-02 21:51:02 +000041#include "llvm/Transforms/Scalar.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070042#include <memory>
Daniel Dunbar897c6762010-06-07 23:20:08 +000043using namespace clang;
44using namespace llvm;
45
46namespace {
47
48class EmitAssemblyHelper {
David Blaikied6471f72011-09-25 23:23:43 +000049 DiagnosticsEngine &Diags;
Daniel Dunbar897c6762010-06-07 23:20:08 +000050 const CodeGenOptions &CodeGenOpts;
Nick Lewycky3aaeccc2011-12-02 22:17:00 +000051 const clang::TargetOptions &TargetOpts;
Dan Gohmanb18b8ad2011-07-05 22:02:36 +000052 const LangOptions &LangOpts;
Daniel Dunbar897c6762010-06-07 23:20:08 +000053 Module *TheModule;
Daniel Dunbar897c6762010-06-07 23:20:08 +000054
55 Timer CodeGenerationTime;
56
Daniel Dunbardb2f2372010-09-17 07:35:16 +000057 mutable PassManager *CodeGenPasses;
Daniel Dunbar897c6762010-06-07 23:20:08 +000058 mutable PassManager *PerModulePasses;
59 mutable FunctionPassManager *PerFunctionPasses;
60
61private:
Stephen Hines651f13c2014-04-23 16:59:28 -070062 PassManager *getCodeGenPasses() const {
Daniel Dunbar897c6762010-06-07 23:20:08 +000063 if (!CodeGenPasses) {
Daniel Dunbardb2f2372010-09-17 07:35:16 +000064 CodeGenPasses = new PassManager();
Stephen Hines176edba2014-12-01 14:53:08 -080065 CodeGenPasses->add(new DataLayoutPass());
Chandler Carruthd938e872013-01-07 01:38:01 +000066 if (TM)
67 TM->addAnalysisPasses(*CodeGenPasses);
Daniel Dunbar897c6762010-06-07 23:20:08 +000068 }
69 return CodeGenPasses;
70 }
71
Stephen Hines651f13c2014-04-23 16:59:28 -070072 PassManager *getPerModulePasses() const {
Daniel Dunbar897c6762010-06-07 23:20:08 +000073 if (!PerModulePasses) {
74 PerModulePasses = new PassManager();
Stephen Hines176edba2014-12-01 14:53:08 -080075 PerModulePasses->add(new DataLayoutPass());
Chandler Carruthd938e872013-01-07 01:38:01 +000076 if (TM)
77 TM->addAnalysisPasses(*PerModulePasses);
Daniel Dunbar897c6762010-06-07 23:20:08 +000078 }
79 return PerModulePasses;
80 }
81
Stephen Hines651f13c2014-04-23 16:59:28 -070082 FunctionPassManager *getPerFunctionPasses() const {
Daniel Dunbar897c6762010-06-07 23:20:08 +000083 if (!PerFunctionPasses) {
84 PerFunctionPasses = new FunctionPassManager(TheModule);
Stephen Hines176edba2014-12-01 14:53:08 -080085 PerFunctionPasses->add(new DataLayoutPass());
Chandler Carruthd938e872013-01-07 01:38:01 +000086 if (TM)
87 TM->addAnalysisPasses(*PerFunctionPasses);
Daniel Dunbar897c6762010-06-07 23:20:08 +000088 }
89 return PerFunctionPasses;
90 }
91
Stephen Hines651f13c2014-04-23 16:59:28 -070092 void CreatePasses();
Nadav Rotemfa60be02012-10-24 00:53:38 +000093
Nadav Rotem129369d2012-10-24 03:52:31 +000094 /// CreateTargetMachine - Generates the TargetMachine.
95 /// Returns Null if it is unable to create the target machine.
96 /// Some of our clang tests specify triples which are not built
97 /// into clang. This is okay because these tests check the generated
98 /// IR, and they require DataLayout which depends on the triple.
99 /// In this case, we allow this method to fail and not report an error.
100 /// When MustCreateTM is used, we print an error if we are unable to load
101 /// the requested target.
102 TargetMachine *CreateTargetMachine(bool MustCreateTM);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000103
104 /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
105 ///
106 /// \return True on success.
Stephen Hines651f13c2014-04-23 16:59:28 -0700107 bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000108
109public:
David Blaikied6471f72011-09-25 23:23:43 +0000110 EmitAssemblyHelper(DiagnosticsEngine &_Diags,
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000111 const CodeGenOptions &CGOpts,
112 const clang::TargetOptions &TOpts,
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000113 const LangOptions &LOpts,
Daniel Dunbar05a7f3d2010-06-07 23:21:04 +0000114 Module *M)
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000115 : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
Daniel Dunbar05a7f3d2010-06-07 23:21:04 +0000116 TheModule(M), CodeGenerationTime("Code Generation Time"),
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700117 CodeGenPasses(nullptr), PerModulePasses(nullptr),
118 PerFunctionPasses(nullptr) {}
Daniel Dunbar897c6762010-06-07 23:20:08 +0000119
120 ~EmitAssemblyHelper() {
121 delete CodeGenPasses;
122 delete PerModulePasses;
123 delete PerFunctionPasses;
Stephen Hines651f13c2014-04-23 16:59:28 -0700124 if (CodeGenOpts.DisableFree)
Stephen Hines176edba2014-12-01 14:53:08 -0800125 BuryPointer(std::move(TM));
Daniel Dunbar897c6762010-06-07 23:20:08 +0000126 }
127
Stephen Hines651f13c2014-04-23 16:59:28 -0700128 std::unique_ptr<TargetMachine> TM;
129
Daniel Dunbar897c6762010-06-07 23:20:08 +0000130 void EmitAssembly(BackendAction Action, raw_ostream *OS);
131};
132
Alexey Samsonove8c03222012-12-28 09:31:34 +0000133// We need this wrapper to access LangOpts and CGOpts from extension functions
134// that we add to the PassManagerBuilder.
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000135class PassManagerBuilderWrapper : public PassManagerBuilder {
136public:
Alexey Samsonov91ecfa62012-12-03 19:12:58 +0000137 PassManagerBuilderWrapper(const CodeGenOptions &CGOpts,
138 const LangOptions &LangOpts)
139 : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
140 const CodeGenOptions &getCGOpts() const { return CGOpts; }
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000141 const LangOptions &getLangOpts() const { return LangOpts; }
142private:
Alexey Samsonov91ecfa62012-12-03 19:12:58 +0000143 const CodeGenOptions &CGOpts;
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000144 const LangOptions &LangOpts;
145};
146
Daniel Dunbar897c6762010-06-07 23:20:08 +0000147}
148
Dan Gohmana8398ea2012-01-17 20:54:51 +0000149static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
150 if (Builder.OptLevel > 0)
151 PM.add(createObjCARCAPElimPass());
152}
153
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000154static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
155 if (Builder.OptLevel > 0)
156 PM.add(createObjCARCExpandPass());
157}
158
159static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
160 if (Builder.OptLevel > 0)
161 PM.add(createObjCARCOptPass());
162}
163
Diego Novillob85a9ec2013-11-13 12:22:39 +0000164static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder,
165 PassManagerBase &PM) {
166 const PassManagerBuilderWrapper &BuilderWrapper =
167 static_cast<const PassManagerBuilderWrapper &>(Builder);
168 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
169 PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile));
170}
171
Stephen Hines651f13c2014-04-23 16:59:28 -0700172static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder,
173 PassManagerBase &PM) {
174 PM.add(createAddDiscriminatorsPass());
175}
176
Nuno Lopesdef18492012-05-22 17:19:45 +0000177static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
178 PassManagerBase &PM) {
Joey Gouly85489082012-11-23 10:39:49 +0000179 PM.add(createBoundsCheckingPass());
Nuno Lopesdef18492012-05-22 17:19:45 +0000180}
181
Stephen Hines176edba2014-12-01 14:53:08 -0800182static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
183 PassManagerBase &PM) {
184 const PassManagerBuilderWrapper &BuilderWrapper =
185 static_cast<const PassManagerBuilderWrapper&>(Builder);
186 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
187 PM.add(createSanitizerCoverageModulePass(CGOpts.SanitizeCoverage));
188}
189
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000190static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
191 PassManagerBase &PM) {
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700192 PM.add(createAddressSanitizerFunctionPass());
193 PM.add(createAddressSanitizerModulePass());
Kostya Serebryany1b4eca62011-11-16 17:34:26 +0000194}
195
Evgeniy Stepanov09ccf392012-12-03 13:20:43 +0000196static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
197 PassManagerBase &PM) {
Evgeniy Stepanov34ef11b2012-12-24 08:42:34 +0000198 const PassManagerBuilderWrapper &BuilderWrapper =
199 static_cast<const PassManagerBuilderWrapper&>(Builder);
200 const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700201 PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins));
Evgeniy Stepanova8d39042013-01-31 09:53:29 +0000202
203 // MemorySanitizer inserts complex instrumentation that mostly follows
204 // the logic of the original code, but operates on "shadow" values.
205 // It can benefit from re-running some general purpose optimization passes.
206 if (Builder.OptLevel > 0) {
207 PM.add(createEarlyCSEPass());
208 PM.add(createReassociatePass());
209 PM.add(createLICMPass());
210 PM.add(createGVNPass());
211 PM.add(createInstructionCombiningPass());
212 PM.add(createDeadStoreEliminationPass());
213 }
Evgeniy Stepanov09ccf392012-12-03 13:20:43 +0000214}
215
Kostya Serebryany3c931222012-03-01 22:27:08 +0000216static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
217 PassManagerBase &PM) {
Stephen Hinesc568f1e2014-07-21 00:47:37 -0700218 PM.add(createThreadSanitizerPass());
Kostya Serebryany3c931222012-03-01 22:27:08 +0000219}
220
Peter Collingbourne2eeed712013-08-07 22:47:34 +0000221static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
222 PassManagerBase &PM) {
Peter Collingbourne5d27a512013-08-14 18:54:18 +0000223 const PassManagerBuilderWrapper &BuilderWrapper =
224 static_cast<const PassManagerBuilderWrapper&>(Builder);
Stephen Hines176edba2014-12-01 14:53:08 -0800225 const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
226 PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFile));
227}
228
229static TargetLibraryInfo *createTLI(llvm::Triple &TargetTriple,
230 const CodeGenOptions &CodeGenOpts) {
231 TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
232 if (!CodeGenOpts.SimplifyLibCalls)
233 TLI->disableAllFunctions();
234 return TLI;
Peter Collingbourne2eeed712013-08-07 22:47:34 +0000235}
236
Stephen Hines651f13c2014-04-23 16:59:28 -0700237void EmitAssemblyHelper::CreatePasses() {
Daniel Dunbar897c6762010-06-07 23:20:08 +0000238 unsigned OptLevel = CodeGenOpts.OptimizationLevel;
Douglas Gregor4cdad312012-10-23 20:05:01 +0000239 CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
Daniel Dunbar897c6762010-06-07 23:20:08 +0000240
241 // Handle disabling of LLVM optimization, where we want to preserve the
242 // internal module before any optimization.
243 if (CodeGenOpts.DisableLLVMOpts) {
244 OptLevel = 0;
245 Inlining = CodeGenOpts.NoInlining;
246 }
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000247
Alexey Samsonov91ecfa62012-12-03 19:12:58 +0000248 PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
Chris Lattner9ca02e52011-05-21 23:50:44 +0000249 PMBuilder.OptLevel = OptLevel;
250 PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
Nick Lewyckyfdf137b2013-06-25 01:49:44 +0000251 PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
252 PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
253 PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
Andrew Trick6445d622011-04-05 18:49:32 +0000254
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700255 PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls;
Chris Lattner9ca02e52011-05-21 23:50:44 +0000256 PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
257 PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
Stephen Hines176edba2014-12-01 14:53:08 -0800258 PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
Hal Finkelce5b5f12013-11-17 16:03:29 +0000259 PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000260
Stephen Hines651f13c2014-04-23 16:59:28 -0700261 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
262 addAddDiscriminatorsPass);
263
Diego Novillob85a9ec2013-11-13 12:22:39 +0000264 if (!CodeGenOpts.SampleProfileFile.empty())
265 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
266 addSampleProfileLoaderPass);
267
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000268 // In ObjC ARC mode, add the main ARC optimization passes.
269 if (LangOpts.ObjCAutoRefCount) {
270 PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
271 addObjCARCExpandPass);
Dan Gohmana8398ea2012-01-17 20:54:51 +0000272 PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
273 addObjCARCAPElimPass);
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000274 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
275 addObjCARCOptPass);
276 }
Kostya Serebryany1b4eca62011-11-16 17:34:26 +0000277
Stephen Hines176edba2014-12-01 14:53:08 -0800278 if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
Nuno Lopesdef18492012-05-22 17:19:45 +0000279 PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
280 addBoundsCheckingPass);
281 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
282 addBoundsCheckingPass);
283 }
284
Stephen Hines176edba2014-12-01 14:53:08 -0800285 if (CodeGenOpts.SanitizeCoverage) {
286 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
287 addSanitizerCoveragePass);
288 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
289 addSanitizerCoveragePass);
290 }
291
292 if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
Kostya Serebryanyba1f0402012-10-15 14:22:56 +0000293 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000294 addAddressSanitizerPasses);
Kostya Serebryanye5dd2ea2011-11-30 22:20:21 +0000295 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
Alexey Samsonov4d1a6e42012-11-29 22:36:21 +0000296 addAddressSanitizerPasses);
Kostya Serebryany1b4eca62011-11-16 17:34:26 +0000297 }
Kostya Serebryany3c931222012-03-01 22:27:08 +0000298
Stephen Hines176edba2014-12-01 14:53:08 -0800299 if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
Evgeniy Stepanov09ccf392012-12-03 13:20:43 +0000300 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
301 addMemorySanitizerPass);
302 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
303 addMemorySanitizerPass);
304 }
305
Stephen Hines176edba2014-12-01 14:53:08 -0800306 if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
Kostya Serebryanye78ec3e2012-03-23 23:25:23 +0000307 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
Kostya Serebryany3c931222012-03-01 22:27:08 +0000308 addThreadSanitizerPass);
309 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
310 addThreadSanitizerPass);
311 }
312
Stephen Hines176edba2014-12-01 14:53:08 -0800313 if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
Peter Collingbourne2eeed712013-08-07 22:47:34 +0000314 PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
315 addDataFlowSanitizerPass);
316 PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
317 addDataFlowSanitizerPass);
318 }
319
Chris Lattner33c09d52011-05-21 20:40:11 +0000320 // Figure out TargetLibraryInfo.
Bill Wendling3621b312011-05-17 23:06:23 +0000321 Triple TargetTriple(TheModule->getTargetTriple());
Stephen Hines176edba2014-12-01 14:53:08 -0800322 PMBuilder.LibraryInfo = createTLI(TargetTriple, CodeGenOpts);
Stephen Hines651f13c2014-04-23 16:59:28 -0700323
Daniel Dunbar897c6762010-06-07 23:20:08 +0000324 switch (Inlining) {
325 case CodeGenOptions::NoInlining: break;
326 case CodeGenOptions::NormalInlining: {
Stephen Hines651f13c2014-04-23 16:59:28 -0700327 PMBuilder.Inliner =
328 createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000329 break;
330 }
331 case CodeGenOptions::OnlyAlwaysInlining:
Chris Lattner33c09d52011-05-21 20:40:11 +0000332 // Respect always_inline.
Chad Rosier98759622012-02-25 02:56:13 +0000333 if (OptLevel == 0)
334 // Do not insert lifetime intrinsics at -O0.
335 PMBuilder.Inliner = createAlwaysInlinerPass(false);
336 else
337 PMBuilder.Inliner = createAlwaysInlinerPass();
Daniel Dunbar897c6762010-06-07 23:20:08 +0000338 break;
339 }
340
Chris Lattner33c09d52011-05-21 20:40:11 +0000341 // Set up the per-function pass manager.
Stephen Hines651f13c2014-04-23 16:59:28 -0700342 FunctionPassManager *FPM = getPerFunctionPasses();
Chris Lattner33c09d52011-05-21 20:40:11 +0000343 if (CodeGenOpts.VerifyModule)
344 FPM->add(createVerifierPass());
345 PMBuilder.populateFunctionPassManager(*FPM);
Andrew Trick6445d622011-04-05 18:49:32 +0000346
Chris Lattner33c09d52011-05-21 20:40:11 +0000347 // Set up the per-module pass manager.
Stephen Hines651f13c2014-04-23 16:59:28 -0700348 PassManager *MPM = getPerModulePasses();
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700349 if (CodeGenOpts.VerifyModule)
350 MPM->add(createDebugInfoVerifierPass());
Chris Lattnerdf619762011-02-18 22:20:38 +0000351
Nick Lewyckyf2b5e072013-03-20 01:38:16 +0000352 if (!CodeGenOpts.DisableGCov &&
353 (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
Nick Lewyckyc3ae5832013-03-14 05:14:01 +0000354 // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
355 // LLVM's -default-gcov-version flag is set to something invalid.
356 GCOVOptions Options;
357 Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
358 Options.EmitData = CodeGenOpts.EmitGcovArcs;
359 memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
360 Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
361 Options.NoRedZone = CodeGenOpts.DisableRedZone;
Nick Lewyckyc3ae5832013-03-14 05:14:01 +0000362 Options.FunctionNamesInData =
Nick Lewycky83c546a2013-03-20 02:14:38 +0000363 !CodeGenOpts.CoverageNoFunctionNamesInData;
Nick Lewyckyc3ae5832013-03-14 05:14:01 +0000364 MPM->add(createGCOVProfilerPass(Options));
Douglas Gregor4cdad312012-10-23 20:05:01 +0000365 if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
Nick Lewyckye8ba8d72011-04-21 23:44:07 +0000366 MPM->add(createStripSymbolsPass(true));
367 }
Nadav Rotem129369d2012-10-24 03:52:31 +0000368
Chris Lattner33c09d52011-05-21 20:40:11 +0000369 PMBuilder.populateModulePassManager(*MPM);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000370}
371
Nadav Rotem129369d2012-10-24 03:52:31 +0000372TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Daniel Dunbar897c6762010-06-07 23:20:08 +0000373 // Create the TargetMachine for generating code.
374 std::string Error;
375 std::string Triple = TheModule->getTargetTriple();
376 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
377 if (!TheTarget) {
Nadav Rotem129369d2012-10-24 03:52:31 +0000378 if (MustCreateTM)
Chad Rosiera03fc6e2013-03-27 00:14:35 +0000379 Diags.Report(diag::err_fe_unable_to_create_target) << Error;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700380 return nullptr;
Daniel Dunbar897c6762010-06-07 23:20:08 +0000381 }
382
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700383 unsigned CodeModel =
384 llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
385 .Case("small", llvm::CodeModel::Small)
386 .Case("kernel", llvm::CodeModel::Kernel)
387 .Case("medium", llvm::CodeModel::Medium)
388 .Case("large", llvm::CodeModel::Large)
389 .Case("default", llvm::CodeModel::Default)
390 .Default(~0u);
391 assert(CodeModel != ~0u && "invalid code model!");
392 llvm::CodeModel::Model CM = static_cast<llvm::CodeModel::Model>(CodeModel);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000393
David Blaikie6bd17d22012-02-07 19:36:38 +0000394 SmallVector<const char *, 16> BackendArgs;
Daniel Dunbar897c6762010-06-07 23:20:08 +0000395 BackendArgs.push_back("clang"); // Fake program name.
396 if (!CodeGenOpts.DebugPass.empty()) {
397 BackendArgs.push_back("-debug-pass");
398 BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
399 }
400 if (!CodeGenOpts.LimitFloatPrecision.empty()) {
401 BackendArgs.push_back("-limit-float-precision");
402 BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
403 }
404 if (llvm::TimePassesIsEnabled)
405 BackendArgs.push_back("-time-passes");
Daniel Dunbar3c66d302011-03-22 16:48:17 +0000406 for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
407 BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
Chad Rosier1b906052011-08-26 00:26:29 +0000408 if (CodeGenOpts.NoGlobalMerge)
Stephen Hines176edba2014-12-01 14:53:08 -0800409 BackendArgs.push_back("-enable-global-merge=false");
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700410 BackendArgs.push_back(nullptr);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000411 llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
David Blaikie6bd17d22012-02-07 19:36:38 +0000412 BackendArgs.data());
Daniel Dunbar897c6762010-06-07 23:20:08 +0000413
414 std::string FeaturesStr;
Evan Cheng368691e2011-06-30 02:06:32 +0000415 if (TargetOpts.Features.size()) {
Daniel Dunbar897c6762010-06-07 23:20:08 +0000416 SubtargetFeatures Features;
Daniel Dunbar897c6762010-06-07 23:20:08 +0000417 for (std::vector<std::string>::const_iterator
418 it = TargetOpts.Features.begin(),
419 ie = TargetOpts.Features.end(); it != ie; ++it)
420 Features.AddFeature(*it);
421 FeaturesStr = Features.getString();
422 }
Evan Cheng2860e302011-07-19 06:37:41 +0000423
424 llvm::Reloc::Model RM = llvm::Reloc::Default;
425 if (CodeGenOpts.RelocationModel == "static") {
426 RM = llvm::Reloc::Static;
427 } else if (CodeGenOpts.RelocationModel == "pic") {
428 RM = llvm::Reloc::PIC_;
429 } else {
430 assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
431 "Invalid PIC model!");
432 RM = llvm::Reloc::DynamicNoPIC;
433 }
434
Evan Cheng9254bf72011-11-16 08:38:55 +0000435 CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
436 switch (CodeGenOpts.OptimizationLevel) {
437 default: break;
438 case 0: OptLevel = CodeGenOpt::None; break;
439 case 3: OptLevel = CodeGenOpt::Aggressive; break;
440 }
441
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000442 llvm::TargetOptions Options;
443
Stephen Hines176edba2014-12-01 14:53:08 -0800444 Options.ThreadModel =
445 llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel)
446 .Case("posix", llvm::ThreadModel::POSIX)
447 .Case("single", llvm::ThreadModel::Single);
448
Stephen Hines651f13c2014-04-23 16:59:28 -0700449 if (CodeGenOpts.DisableIntegratedAS)
450 Options.DisableIntegratedAS = true;
451
452 if (CodeGenOpts.CompressDebugSections)
453 Options.CompressDebugSections = true;
454
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000455 // Set frame pointer elimination mode.
456 if (!CodeGenOpts.DisableFPElim) {
457 Options.NoFramePointerElim = false;
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000458 } else if (CodeGenOpts.OmitLeafFramePointer) {
459 Options.NoFramePointerElim = false;
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000460 } else {
461 Options.NoFramePointerElim = true;
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000462 }
463
Rafael Espindola8af669f2012-06-19 01:26:10 +0000464 if (CodeGenOpts.UseInitArray)
465 Options.UseInitArray = true;
466
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000467 // Set float ABI type.
468 if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp")
469 Options.FloatABIType = llvm::FloatABI::Soft;
470 else if (CodeGenOpts.FloatABI == "hard")
471 Options.FloatABIType = llvm::FloatABI::Hard;
472 else {
473 assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
474 Options.FloatABIType = llvm::FloatABI::Default;
475 }
476
Lang Hamesc9686712012-07-06 00:59:19 +0000477 // Set FP fusion mode.
Lang Hames931c0832012-11-15 07:51:26 +0000478 switch (CodeGenOpts.getFPContractMode()) {
479 case CodeGenOptions::FPC_Off:
Lang Hamesc9686712012-07-06 00:59:19 +0000480 Options.AllowFPOpFusion = llvm::FPOpFusion::Strict;
481 break;
Lang Hames931c0832012-11-15 07:51:26 +0000482 case CodeGenOptions::FPC_On:
Lang Hamesc9686712012-07-06 00:59:19 +0000483 Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
484 break;
Lang Hames931c0832012-11-15 07:51:26 +0000485 case CodeGenOptions::FPC_Fast:
Lang Hamesc9686712012-07-06 00:59:19 +0000486 Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
Nadav Rotem25030c42012-10-19 04:15:32 +0000487 break;
Lang Hamesc9686712012-07-06 00:59:19 +0000488 }
489
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000490 Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;
491 Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
492 Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
493 Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
494 Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
495 Options.UseSoftFloat = CodeGenOpts.SoftFloat;
Nick Lewycky4e785c92011-12-06 03:33:03 +0000496 Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
Nick Lewycky1db772b2012-01-23 08:29:12 +0000497 Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;
Bob Wilson71fd6cc2012-02-03 06:27:22 +0000498 Options.TrapFuncName = CodeGenOpts.TrapFuncName;
Chandler Carruth5081de52012-04-08 21:09:51 +0000499 Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700500 Options.FunctionSections = CodeGenOpts.FunctionSections;
501 Options.DataSections = CodeGenOpts.DataSections;
502
503 Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
504 Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
505 Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
506 Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
Stephen Hines176edba2014-12-01 14:53:08 -0800507 Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700508 Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000509
Evan Cheng368691e2011-06-30 02:06:32 +0000510 TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000511 FeaturesStr, Options,
512 RM, CM, OptLevel);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000513
Nadav Rotemfa60be02012-10-24 00:53:38 +0000514 return TM;
515}
516
517bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
Stephen Hines651f13c2014-04-23 16:59:28 -0700518 formatted_raw_ostream &OS) {
Nadav Rotemfa60be02012-10-24 00:53:38 +0000519
Daniel Dunbar897c6762010-06-07 23:20:08 +0000520 // Create the code generator passes.
Stephen Hines651f13c2014-04-23 16:59:28 -0700521 PassManager *PM = getCodeGenPasses();
Daniel Dunbar897c6762010-06-07 23:20:08 +0000522
Chad Rosier3f3335d2012-02-29 20:14:59 +0000523 // Add LibraryInfo.
Daniel Dunbarcbbe2c02012-10-19 20:10:10 +0000524 llvm::Triple TargetTriple(TheModule->getTargetTriple());
Stephen Hines176edba2014-12-01 14:53:08 -0800525 PM->add(createTLI(TargetTriple, CodeGenOpts));
Chad Rosier3f3335d2012-02-29 20:14:59 +0000526
Chandler Carruthd938e872013-01-07 01:38:01 +0000527 // Add Target specific analysis passes.
528 TM->addAnalysisPasses(*PM);
Nadav Rotem25030c42012-10-19 04:15:32 +0000529
Daniel Dunbar897c6762010-06-07 23:20:08 +0000530 // Normal mode, emit a .s or .o file by running the code generator. Note,
531 // this also adds codegenerator level optimization passes.
532 TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
533 if (Action == Backend_EmitObj)
534 CGFT = TargetMachine::CGFT_ObjectFile;
535 else if (Action == Backend_EmitMCNull)
536 CGFT = TargetMachine::CGFT_Null;
537 else
538 assert(Action == Backend_EmitAssembly && "Invalid action!");
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000539
540 // Add ObjC ARC final-cleanup optimizations. This is done as part of the
541 // "codegen" passes so that it isn't run multiple times when there is
542 // inlining happening.
Dan Gohman465a8992012-04-04 21:04:56 +0000543 if (LangOpts.ObjCAutoRefCount &&
544 CodeGenOpts.OptimizationLevel > 0)
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000545 PM->add(createObjCARCContractPass());
546
Evan Cheng9254bf72011-11-16 08:38:55 +0000547 if (TM->addPassesToEmitFile(*PM, OS, CGFT,
Daniel Dunbar897c6762010-06-07 23:20:08 +0000548 /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
549 Diags.Report(diag::err_fe_unable_to_interface_with_target);
550 return false;
551 }
552
553 return true;
554}
555
556void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -0700557 TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000558 llvm::formatted_raw_ostream FormattedOS;
559
Nadav Rotem129369d2012-10-24 03:52:31 +0000560 bool UsesCodeGen = (Action != Backend_EmitNothing &&
561 Action != Backend_EmitBC &&
562 Action != Backend_EmitLL);
Stephen Hines651f13c2014-04-23 16:59:28 -0700563 if (!TM)
564 TM.reset(CreateTargetMachine(UsesCodeGen));
565
Chad Rosiera03fc6e2013-03-27 00:14:35 +0000566 if (UsesCodeGen && !TM) return;
Stephen Hines651f13c2014-04-23 16:59:28 -0700567 CreatePasses();
Nadav Rotemfa60be02012-10-24 00:53:38 +0000568
Daniel Dunbar897c6762010-06-07 23:20:08 +0000569 switch (Action) {
570 case Backend_EmitNothing:
571 break;
572
573 case Backend_EmitBC:
Stephen Hines651f13c2014-04-23 16:59:28 -0700574 getPerModulePasses()->add(createBitcodeWriterPass(*OS));
Daniel Dunbar897c6762010-06-07 23:20:08 +0000575 break;
576
577 case Backend_EmitLL:
578 FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
Stephen Hines651f13c2014-04-23 16:59:28 -0700579 getPerModulePasses()->add(createPrintModulePass(FormattedOS));
Daniel Dunbar897c6762010-06-07 23:20:08 +0000580 break;
581
582 default:
583 FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
Stephen Hines651f13c2014-04-23 16:59:28 -0700584 if (!AddEmitPasses(Action, FormattedOS))
Daniel Dunbar897c6762010-06-07 23:20:08 +0000585 return;
586 }
587
Andrew Trick92b5d942011-04-05 18:56:55 +0000588 // Before executing passes, print the final values of the LLVM options.
589 cl::PrintOptionValues();
590
Daniel Dunbar897c6762010-06-07 23:20:08 +0000591 // Run passes. For now we do all passes at once, but eventually we
592 // would like to have the option of streaming code generation.
593
594 if (PerFunctionPasses) {
595 PrettyStackTraceString CrashInfo("Per-function optimization");
596
597 PerFunctionPasses->doInitialization();
598 for (Module::iterator I = TheModule->begin(),
599 E = TheModule->end(); I != E; ++I)
600 if (!I->isDeclaration())
601 PerFunctionPasses->run(*I);
602 PerFunctionPasses->doFinalization();
603 }
604
605 if (PerModulePasses) {
606 PrettyStackTraceString CrashInfo("Per-module optimization passes");
607 PerModulePasses->run(*TheModule);
608 }
609
610 if (CodeGenPasses) {
611 PrettyStackTraceString CrashInfo("Code generation");
Daniel Dunbardb2f2372010-09-17 07:35:16 +0000612 CodeGenPasses->run(*TheModule);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000613 }
614}
615
David Blaikied6471f72011-09-25 23:23:43 +0000616void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
617 const CodeGenOptions &CGOpts,
Nick Lewycky3aaeccc2011-12-02 22:17:00 +0000618 const clang::TargetOptions &TOpts,
Stephen Hines651f13c2014-04-23 16:59:28 -0700619 const LangOptions &LOpts, StringRef TDesc,
620 Module *M, BackendAction Action,
621 raw_ostream *OS) {
Dan Gohmanb18b8ad2011-07-05 22:02:36 +0000622 EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
Daniel Dunbar897c6762010-06-07 23:20:08 +0000623
624 AsmHelper.EmitAssembly(Action, OS);
Stephen Hines651f13c2014-04-23 16:59:28 -0700625
626 // If an optional clang TargetInfo description string was passed in, use it to
627 // verify the LLVM TargetMachine's DataLayout.
628 if (AsmHelper.TM && !TDesc.empty()) {
Stephen Hines176edba2014-12-01 14:53:08 -0800629 std::string DLDesc = AsmHelper.TM->getSubtargetImpl()
630 ->getDataLayout()
631 ->getStringRepresentation();
Stephen Hines651f13c2014-04-23 16:59:28 -0700632 if (DLDesc != TDesc) {
633 unsigned DiagID = Diags.getCustomDiagID(
634 DiagnosticsEngine::Error, "backend data layout '%0' does not match "
635 "expected target description '%1'");
636 Diags.Report(DiagID) << DLDesc << TDesc;
637 }
638 }
Daniel Dunbar897c6762010-06-07 23:20:08 +0000639}