xref: /minix3/external/bsd/llvm/dist/clang/lib/CodeGen/BackendUtil.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- BackendUtil.cpp - LLVM Backend Utilities -------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "clang/CodeGen/BackendUtil.h"
11f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
12f4a2713aSLionel Sambuc #include "clang/Basic/LangOptions.h"
13f4a2713aSLionel Sambuc #include "clang/Basic/TargetOptions.h"
14f4a2713aSLionel Sambuc #include "clang/Frontend/CodeGenOptions.h"
15f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendDiagnostic.h"
16*0a6a1f1dSLionel Sambuc #include "clang/Frontend/Utils.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
18*0a6a1f1dSLionel Sambuc #include "llvm/Bitcode/BitcodeWriterPass.h"
19f4a2713aSLionel Sambuc #include "llvm/CodeGen/RegAllocRegistry.h"
20f4a2713aSLionel Sambuc #include "llvm/CodeGen/SchedulerRegistry.h"
21f4a2713aSLionel Sambuc #include "llvm/IR/DataLayout.h"
22*0a6a1f1dSLionel Sambuc #include "llvm/IR/IRPrintingPasses.h"
23f4a2713aSLionel Sambuc #include "llvm/IR/Module.h"
24*0a6a1f1dSLionel Sambuc #include "llvm/IR/Verifier.h"
25f4a2713aSLionel Sambuc #include "llvm/MC/SubtargetFeature.h"
26f4a2713aSLionel Sambuc #include "llvm/PassManager.h"
27f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
28f4a2713aSLionel Sambuc #include "llvm/Support/FormattedStream.h"
29f4a2713aSLionel Sambuc #include "llvm/Support/PrettyStackTrace.h"
30f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
31f4a2713aSLionel Sambuc #include "llvm/Support/Timer.h"
32f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
33f4a2713aSLionel Sambuc #include "llvm/Target/TargetLibraryInfo.h"
34f4a2713aSLionel Sambuc #include "llvm/Target/TargetMachine.h"
35f4a2713aSLionel Sambuc #include "llvm/Target/TargetOptions.h"
36*0a6a1f1dSLionel Sambuc #include "llvm/Target/TargetSubtargetInfo.h"
37f4a2713aSLionel Sambuc #include "llvm/Transforms/IPO.h"
38f4a2713aSLionel Sambuc #include "llvm/Transforms/IPO/PassManagerBuilder.h"
39f4a2713aSLionel Sambuc #include "llvm/Transforms/Instrumentation.h"
40f4a2713aSLionel Sambuc #include "llvm/Transforms/ObjCARC.h"
41f4a2713aSLionel Sambuc #include "llvm/Transforms/Scalar.h"
42*0a6a1f1dSLionel Sambuc #include "llvm/Transforms/Utils/SymbolRewriter.h"
43*0a6a1f1dSLionel Sambuc #include <memory>
44f4a2713aSLionel Sambuc using namespace clang;
45f4a2713aSLionel Sambuc using namespace llvm;
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc namespace {
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc class EmitAssemblyHelper {
50f4a2713aSLionel Sambuc   DiagnosticsEngine &Diags;
51f4a2713aSLionel Sambuc   const CodeGenOptions &CodeGenOpts;
52f4a2713aSLionel Sambuc   const clang::TargetOptions &TargetOpts;
53f4a2713aSLionel Sambuc   const LangOptions &LangOpts;
54f4a2713aSLionel Sambuc   Module *TheModule;
55f4a2713aSLionel Sambuc 
56f4a2713aSLionel Sambuc   Timer CodeGenerationTime;
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc   mutable PassManager *CodeGenPasses;
59f4a2713aSLionel Sambuc   mutable PassManager *PerModulePasses;
60f4a2713aSLionel Sambuc   mutable FunctionPassManager *PerFunctionPasses;
61f4a2713aSLionel Sambuc 
62f4a2713aSLionel Sambuc private:
getCodeGenPasses() const63*0a6a1f1dSLionel Sambuc   PassManager *getCodeGenPasses() const {
64f4a2713aSLionel Sambuc     if (!CodeGenPasses) {
65f4a2713aSLionel Sambuc       CodeGenPasses = new PassManager();
66*0a6a1f1dSLionel Sambuc       CodeGenPasses->add(new DataLayoutPass());
67f4a2713aSLionel Sambuc       if (TM)
68f4a2713aSLionel Sambuc         TM->addAnalysisPasses(*CodeGenPasses);
69f4a2713aSLionel Sambuc     }
70f4a2713aSLionel Sambuc     return CodeGenPasses;
71f4a2713aSLionel Sambuc   }
72f4a2713aSLionel Sambuc 
getPerModulePasses() const73*0a6a1f1dSLionel Sambuc   PassManager *getPerModulePasses() const {
74f4a2713aSLionel Sambuc     if (!PerModulePasses) {
75f4a2713aSLionel Sambuc       PerModulePasses = new PassManager();
76*0a6a1f1dSLionel Sambuc       PerModulePasses->add(new DataLayoutPass());
77f4a2713aSLionel Sambuc       if (TM)
78f4a2713aSLionel Sambuc         TM->addAnalysisPasses(*PerModulePasses);
79f4a2713aSLionel Sambuc     }
80f4a2713aSLionel Sambuc     return PerModulePasses;
81f4a2713aSLionel Sambuc   }
82f4a2713aSLionel Sambuc 
getPerFunctionPasses() const83*0a6a1f1dSLionel Sambuc   FunctionPassManager *getPerFunctionPasses() const {
84f4a2713aSLionel Sambuc     if (!PerFunctionPasses) {
85f4a2713aSLionel Sambuc       PerFunctionPasses = new FunctionPassManager(TheModule);
86*0a6a1f1dSLionel Sambuc       PerFunctionPasses->add(new DataLayoutPass());
87f4a2713aSLionel Sambuc       if (TM)
88f4a2713aSLionel Sambuc         TM->addAnalysisPasses(*PerFunctionPasses);
89f4a2713aSLionel Sambuc     }
90f4a2713aSLionel Sambuc     return PerFunctionPasses;
91f4a2713aSLionel Sambuc   }
92f4a2713aSLionel Sambuc 
93*0a6a1f1dSLionel Sambuc   void CreatePasses();
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc   /// CreateTargetMachine - Generates the TargetMachine.
96f4a2713aSLionel Sambuc   /// Returns Null if it is unable to create the target machine.
97f4a2713aSLionel Sambuc   /// Some of our clang tests specify triples which are not built
98f4a2713aSLionel Sambuc   /// into clang. This is okay because these tests check the generated
99f4a2713aSLionel Sambuc   /// IR, and they require DataLayout which depends on the triple.
100f4a2713aSLionel Sambuc   /// In this case, we allow this method to fail and not report an error.
101f4a2713aSLionel Sambuc   /// When MustCreateTM is used, we print an error if we are unable to load
102f4a2713aSLionel Sambuc   /// the requested target.
103f4a2713aSLionel Sambuc   TargetMachine *CreateTargetMachine(bool MustCreateTM);
104f4a2713aSLionel Sambuc 
105f4a2713aSLionel Sambuc   /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
106f4a2713aSLionel Sambuc   ///
107f4a2713aSLionel Sambuc   /// \return True on success.
108*0a6a1f1dSLionel Sambuc   bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
109f4a2713aSLionel Sambuc 
110f4a2713aSLionel Sambuc public:
EmitAssemblyHelper(DiagnosticsEngine & _Diags,const CodeGenOptions & CGOpts,const clang::TargetOptions & TOpts,const LangOptions & LOpts,Module * M)111f4a2713aSLionel Sambuc   EmitAssemblyHelper(DiagnosticsEngine &_Diags,
112f4a2713aSLionel Sambuc                      const CodeGenOptions &CGOpts,
113f4a2713aSLionel Sambuc                      const clang::TargetOptions &TOpts,
114f4a2713aSLionel Sambuc                      const LangOptions &LOpts,
115f4a2713aSLionel Sambuc                      Module *M)
116f4a2713aSLionel Sambuc     : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
117f4a2713aSLionel Sambuc       TheModule(M), CodeGenerationTime("Code Generation Time"),
118*0a6a1f1dSLionel Sambuc       CodeGenPasses(nullptr), PerModulePasses(nullptr),
119*0a6a1f1dSLionel Sambuc       PerFunctionPasses(nullptr) {}
120f4a2713aSLionel Sambuc 
~EmitAssemblyHelper()121f4a2713aSLionel Sambuc   ~EmitAssemblyHelper() {
122f4a2713aSLionel Sambuc     delete CodeGenPasses;
123f4a2713aSLionel Sambuc     delete PerModulePasses;
124f4a2713aSLionel Sambuc     delete PerFunctionPasses;
125*0a6a1f1dSLionel Sambuc     if (CodeGenOpts.DisableFree)
126*0a6a1f1dSLionel Sambuc       BuryPointer(std::move(TM));
127f4a2713aSLionel Sambuc   }
128f4a2713aSLionel Sambuc 
129*0a6a1f1dSLionel Sambuc   std::unique_ptr<TargetMachine> TM;
130*0a6a1f1dSLionel Sambuc 
131f4a2713aSLionel Sambuc   void EmitAssembly(BackendAction Action, raw_ostream *OS);
132f4a2713aSLionel Sambuc };
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc // We need this wrapper to access LangOpts and CGOpts from extension functions
135f4a2713aSLionel Sambuc // that we add to the PassManagerBuilder.
136f4a2713aSLionel Sambuc class PassManagerBuilderWrapper : public PassManagerBuilder {
137f4a2713aSLionel Sambuc public:
PassManagerBuilderWrapper(const CodeGenOptions & CGOpts,const LangOptions & LangOpts)138f4a2713aSLionel Sambuc   PassManagerBuilderWrapper(const CodeGenOptions &CGOpts,
139f4a2713aSLionel Sambuc                             const LangOptions &LangOpts)
140f4a2713aSLionel Sambuc       : PassManagerBuilder(), CGOpts(CGOpts), LangOpts(LangOpts) {}
getCGOpts() const141f4a2713aSLionel Sambuc   const CodeGenOptions &getCGOpts() const { return CGOpts; }
getLangOpts() const142f4a2713aSLionel Sambuc   const LangOptions &getLangOpts() const { return LangOpts; }
143f4a2713aSLionel Sambuc private:
144f4a2713aSLionel Sambuc   const CodeGenOptions &CGOpts;
145f4a2713aSLionel Sambuc   const LangOptions &LangOpts;
146f4a2713aSLionel Sambuc };
147f4a2713aSLionel Sambuc 
148f4a2713aSLionel Sambuc }
149f4a2713aSLionel Sambuc 
addObjCARCAPElimPass(const PassManagerBuilder & Builder,PassManagerBase & PM)150f4a2713aSLionel Sambuc static void addObjCARCAPElimPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
151f4a2713aSLionel Sambuc   if (Builder.OptLevel > 0)
152f4a2713aSLionel Sambuc     PM.add(createObjCARCAPElimPass());
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc 
addObjCARCExpandPass(const PassManagerBuilder & Builder,PassManagerBase & PM)155f4a2713aSLionel Sambuc static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
156f4a2713aSLionel Sambuc   if (Builder.OptLevel > 0)
157f4a2713aSLionel Sambuc     PM.add(createObjCARCExpandPass());
158f4a2713aSLionel Sambuc }
159f4a2713aSLionel Sambuc 
addObjCARCOptPass(const PassManagerBuilder & Builder,PassManagerBase & PM)160f4a2713aSLionel Sambuc static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) {
161f4a2713aSLionel Sambuc   if (Builder.OptLevel > 0)
162f4a2713aSLionel Sambuc     PM.add(createObjCARCOptPass());
163f4a2713aSLionel Sambuc }
164f4a2713aSLionel Sambuc 
addSampleProfileLoaderPass(const PassManagerBuilder & Builder,PassManagerBase & PM)165f4a2713aSLionel Sambuc static void addSampleProfileLoaderPass(const PassManagerBuilder &Builder,
166f4a2713aSLionel Sambuc                                        PassManagerBase &PM) {
167f4a2713aSLionel Sambuc   const PassManagerBuilderWrapper &BuilderWrapper =
168f4a2713aSLionel Sambuc       static_cast<const PassManagerBuilderWrapper &>(Builder);
169f4a2713aSLionel Sambuc   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
170f4a2713aSLionel Sambuc   PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile));
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc 
addAddDiscriminatorsPass(const PassManagerBuilder & Builder,PassManagerBase & PM)173*0a6a1f1dSLionel Sambuc static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder,
174*0a6a1f1dSLionel Sambuc                                      PassManagerBase &PM) {
175*0a6a1f1dSLionel Sambuc   PM.add(createAddDiscriminatorsPass());
176*0a6a1f1dSLionel Sambuc }
177*0a6a1f1dSLionel Sambuc 
addBoundsCheckingPass(const PassManagerBuilder & Builder,PassManagerBase & PM)178f4a2713aSLionel Sambuc static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
179f4a2713aSLionel Sambuc                                     PassManagerBase &PM) {
180f4a2713aSLionel Sambuc   PM.add(createBoundsCheckingPass());
181f4a2713aSLionel Sambuc }
182f4a2713aSLionel Sambuc 
addSanitizerCoveragePass(const PassManagerBuilder & Builder,PassManagerBase & PM)183*0a6a1f1dSLionel Sambuc static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
184f4a2713aSLionel Sambuc                                      PassManagerBase &PM) {
185f4a2713aSLionel Sambuc   const PassManagerBuilderWrapper &BuilderWrapper =
186f4a2713aSLionel Sambuc       static_cast<const PassManagerBuilderWrapper&>(Builder);
187f4a2713aSLionel Sambuc   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
188*0a6a1f1dSLionel Sambuc   PM.add(createSanitizerCoverageModulePass(CGOpts.SanitizeCoverage));
189*0a6a1f1dSLionel Sambuc }
190*0a6a1f1dSLionel Sambuc 
addAddressSanitizerPasses(const PassManagerBuilder & Builder,PassManagerBase & PM)191*0a6a1f1dSLionel Sambuc static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
192*0a6a1f1dSLionel Sambuc                                       PassManagerBase &PM) {
193*0a6a1f1dSLionel Sambuc   PM.add(createAddressSanitizerFunctionPass());
194*0a6a1f1dSLionel Sambuc   PM.add(createAddressSanitizerModulePass());
195f4a2713aSLionel Sambuc }
196f4a2713aSLionel Sambuc 
addMemorySanitizerPass(const PassManagerBuilder & Builder,PassManagerBase & PM)197f4a2713aSLionel Sambuc static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
198f4a2713aSLionel Sambuc                                    PassManagerBase &PM) {
199f4a2713aSLionel Sambuc   const PassManagerBuilderWrapper &BuilderWrapper =
200f4a2713aSLionel Sambuc       static_cast<const PassManagerBuilderWrapper&>(Builder);
201f4a2713aSLionel Sambuc   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
202*0a6a1f1dSLionel Sambuc   PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins));
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc   // MemorySanitizer inserts complex instrumentation that mostly follows
205f4a2713aSLionel Sambuc   // the logic of the original code, but operates on "shadow" values.
206f4a2713aSLionel Sambuc   // It can benefit from re-running some general purpose optimization passes.
207f4a2713aSLionel Sambuc   if (Builder.OptLevel > 0) {
208f4a2713aSLionel Sambuc     PM.add(createEarlyCSEPass());
209f4a2713aSLionel Sambuc     PM.add(createReassociatePass());
210f4a2713aSLionel Sambuc     PM.add(createLICMPass());
211f4a2713aSLionel Sambuc     PM.add(createGVNPass());
212f4a2713aSLionel Sambuc     PM.add(createInstructionCombiningPass());
213f4a2713aSLionel Sambuc     PM.add(createDeadStoreEliminationPass());
214f4a2713aSLionel Sambuc   }
215f4a2713aSLionel Sambuc }
216f4a2713aSLionel Sambuc 
addThreadSanitizerPass(const PassManagerBuilder & Builder,PassManagerBase & PM)217f4a2713aSLionel Sambuc static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
218f4a2713aSLionel Sambuc                                    PassManagerBase &PM) {
219*0a6a1f1dSLionel Sambuc   PM.add(createThreadSanitizerPass());
220f4a2713aSLionel Sambuc }
221f4a2713aSLionel Sambuc 
addDataFlowSanitizerPass(const PassManagerBuilder & Builder,PassManagerBase & PM)222f4a2713aSLionel Sambuc static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
223f4a2713aSLionel Sambuc                                      PassManagerBase &PM) {
224f4a2713aSLionel Sambuc   const PassManagerBuilderWrapper &BuilderWrapper =
225f4a2713aSLionel Sambuc       static_cast<const PassManagerBuilderWrapper&>(Builder);
226*0a6a1f1dSLionel Sambuc   const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
227*0a6a1f1dSLionel Sambuc   PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFile));
228f4a2713aSLionel Sambuc }
229f4a2713aSLionel Sambuc 
createTLI(llvm::Triple & TargetTriple,const CodeGenOptions & CodeGenOpts)230*0a6a1f1dSLionel Sambuc static TargetLibraryInfo *createTLI(llvm::Triple &TargetTriple,
231*0a6a1f1dSLionel Sambuc                                     const CodeGenOptions &CodeGenOpts) {
232*0a6a1f1dSLionel Sambuc   TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
233*0a6a1f1dSLionel Sambuc   if (!CodeGenOpts.SimplifyLibCalls)
234*0a6a1f1dSLionel Sambuc     TLI->disableAllFunctions();
235*0a6a1f1dSLionel Sambuc   return TLI;
236*0a6a1f1dSLionel Sambuc }
237*0a6a1f1dSLionel Sambuc 
addSymbolRewriterPass(const CodeGenOptions & Opts,PassManager * MPM)238*0a6a1f1dSLionel Sambuc static void addSymbolRewriterPass(const CodeGenOptions &Opts,
239*0a6a1f1dSLionel Sambuc                                   PassManager *MPM) {
240*0a6a1f1dSLionel Sambuc   llvm::SymbolRewriter::RewriteDescriptorList DL;
241*0a6a1f1dSLionel Sambuc 
242*0a6a1f1dSLionel Sambuc   llvm::SymbolRewriter::RewriteMapParser MapParser;
243*0a6a1f1dSLionel Sambuc   for (const auto &MapFile : Opts.RewriteMapFiles)
244*0a6a1f1dSLionel Sambuc     MapParser.parse(MapFile, &DL);
245*0a6a1f1dSLionel Sambuc 
246*0a6a1f1dSLionel Sambuc   MPM->add(createRewriteSymbolsPass(DL));
247*0a6a1f1dSLionel Sambuc }
248*0a6a1f1dSLionel Sambuc 
CreatePasses()249*0a6a1f1dSLionel Sambuc void EmitAssemblyHelper::CreatePasses() {
250f4a2713aSLionel Sambuc   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
251f4a2713aSLionel Sambuc   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
252f4a2713aSLionel Sambuc 
253f4a2713aSLionel Sambuc   // Handle disabling of LLVM optimization, where we want to preserve the
254f4a2713aSLionel Sambuc   // internal module before any optimization.
255f4a2713aSLionel Sambuc   if (CodeGenOpts.DisableLLVMOpts) {
256f4a2713aSLionel Sambuc     OptLevel = 0;
257f4a2713aSLionel Sambuc     Inlining = CodeGenOpts.NoInlining;
258f4a2713aSLionel Sambuc   }
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc   PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts);
261f4a2713aSLionel Sambuc   PMBuilder.OptLevel = OptLevel;
262f4a2713aSLionel Sambuc   PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize;
263f4a2713aSLionel Sambuc   PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB;
264f4a2713aSLionel Sambuc   PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
265f4a2713aSLionel Sambuc   PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
266f4a2713aSLionel Sambuc 
267*0a6a1f1dSLionel Sambuc   PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls;
268f4a2713aSLionel Sambuc   PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
269f4a2713aSLionel Sambuc   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
270*0a6a1f1dSLionel Sambuc   PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions;
271f4a2713aSLionel Sambuc   PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
272f4a2713aSLionel Sambuc 
273*0a6a1f1dSLionel Sambuc   PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
274*0a6a1f1dSLionel Sambuc                          addAddDiscriminatorsPass);
275*0a6a1f1dSLionel Sambuc 
276f4a2713aSLionel Sambuc   if (!CodeGenOpts.SampleProfileFile.empty())
277f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
278f4a2713aSLionel Sambuc                            addSampleProfileLoaderPass);
279f4a2713aSLionel Sambuc 
280f4a2713aSLionel Sambuc   // In ObjC ARC mode, add the main ARC optimization passes.
281f4a2713aSLionel Sambuc   if (LangOpts.ObjCAutoRefCount) {
282f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
283f4a2713aSLionel Sambuc                            addObjCARCExpandPass);
284f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly,
285f4a2713aSLionel Sambuc                            addObjCARCAPElimPass);
286f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
287f4a2713aSLionel Sambuc                            addObjCARCOptPass);
288f4a2713aSLionel Sambuc   }
289f4a2713aSLionel Sambuc 
290*0a6a1f1dSLionel Sambuc   if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) {
291f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
292f4a2713aSLionel Sambuc                            addBoundsCheckingPass);
293f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
294f4a2713aSLionel Sambuc                            addBoundsCheckingPass);
295f4a2713aSLionel Sambuc   }
296f4a2713aSLionel Sambuc 
297*0a6a1f1dSLionel Sambuc   if (CodeGenOpts.SanitizeCoverage) {
298*0a6a1f1dSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
299*0a6a1f1dSLionel Sambuc                            addSanitizerCoveragePass);
300*0a6a1f1dSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
301*0a6a1f1dSLionel Sambuc                            addSanitizerCoveragePass);
302*0a6a1f1dSLionel Sambuc   }
303*0a6a1f1dSLionel Sambuc 
304*0a6a1f1dSLionel Sambuc   if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
305f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
306f4a2713aSLionel Sambuc                            addAddressSanitizerPasses);
307f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
308f4a2713aSLionel Sambuc                            addAddressSanitizerPasses);
309f4a2713aSLionel Sambuc   }
310f4a2713aSLionel Sambuc 
311*0a6a1f1dSLionel Sambuc   if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
312f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
313f4a2713aSLionel Sambuc                            addMemorySanitizerPass);
314f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
315f4a2713aSLionel Sambuc                            addMemorySanitizerPass);
316f4a2713aSLionel Sambuc   }
317f4a2713aSLionel Sambuc 
318*0a6a1f1dSLionel Sambuc   if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
319f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
320f4a2713aSLionel Sambuc                            addThreadSanitizerPass);
321f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
322f4a2713aSLionel Sambuc                            addThreadSanitizerPass);
323f4a2713aSLionel Sambuc   }
324f4a2713aSLionel Sambuc 
325*0a6a1f1dSLionel Sambuc   if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
326f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
327f4a2713aSLionel Sambuc                            addDataFlowSanitizerPass);
328f4a2713aSLionel Sambuc     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
329f4a2713aSLionel Sambuc                            addDataFlowSanitizerPass);
330f4a2713aSLionel Sambuc   }
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc   // Figure out TargetLibraryInfo.
333f4a2713aSLionel Sambuc   Triple TargetTriple(TheModule->getTargetTriple());
334*0a6a1f1dSLionel Sambuc   PMBuilder.LibraryInfo = createTLI(TargetTriple, CodeGenOpts);
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc   switch (Inlining) {
337f4a2713aSLionel Sambuc   case CodeGenOptions::NoInlining: break;
338f4a2713aSLionel Sambuc   case CodeGenOptions::NormalInlining: {
339*0a6a1f1dSLionel Sambuc     PMBuilder.Inliner =
340*0a6a1f1dSLionel Sambuc         createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
341f4a2713aSLionel Sambuc     break;
342f4a2713aSLionel Sambuc   }
343f4a2713aSLionel Sambuc   case CodeGenOptions::OnlyAlwaysInlining:
344f4a2713aSLionel Sambuc     // Respect always_inline.
345f4a2713aSLionel Sambuc     if (OptLevel == 0)
346f4a2713aSLionel Sambuc       // Do not insert lifetime intrinsics at -O0.
347f4a2713aSLionel Sambuc       PMBuilder.Inliner = createAlwaysInlinerPass(false);
348f4a2713aSLionel Sambuc     else
349f4a2713aSLionel Sambuc       PMBuilder.Inliner = createAlwaysInlinerPass();
350f4a2713aSLionel Sambuc     break;
351f4a2713aSLionel Sambuc   }
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc   // Set up the per-function pass manager.
354*0a6a1f1dSLionel Sambuc   FunctionPassManager *FPM = getPerFunctionPasses();
355f4a2713aSLionel Sambuc   if (CodeGenOpts.VerifyModule)
356f4a2713aSLionel Sambuc     FPM->add(createVerifierPass());
357f4a2713aSLionel Sambuc   PMBuilder.populateFunctionPassManager(*FPM);
358f4a2713aSLionel Sambuc 
359f4a2713aSLionel Sambuc   // Set up the per-module pass manager.
360*0a6a1f1dSLionel Sambuc   PassManager *MPM = getPerModulePasses();
361*0a6a1f1dSLionel Sambuc   if (!CodeGenOpts.RewriteMapFiles.empty())
362*0a6a1f1dSLionel Sambuc     addSymbolRewriterPass(CodeGenOpts, MPM);
363*0a6a1f1dSLionel Sambuc   if (CodeGenOpts.VerifyModule)
364*0a6a1f1dSLionel Sambuc     MPM->add(createDebugInfoVerifierPass());
365f4a2713aSLionel Sambuc 
366f4a2713aSLionel Sambuc   if (!CodeGenOpts.DisableGCov &&
367f4a2713aSLionel Sambuc       (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
368f4a2713aSLionel Sambuc     // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if
369f4a2713aSLionel Sambuc     // LLVM's -default-gcov-version flag is set to something invalid.
370f4a2713aSLionel Sambuc     GCOVOptions Options;
371f4a2713aSLionel Sambuc     Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
372f4a2713aSLionel Sambuc     Options.EmitData = CodeGenOpts.EmitGcovArcs;
373f4a2713aSLionel Sambuc     memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4);
374f4a2713aSLionel Sambuc     Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
375f4a2713aSLionel Sambuc     Options.NoRedZone = CodeGenOpts.DisableRedZone;
376f4a2713aSLionel Sambuc     Options.FunctionNamesInData =
377f4a2713aSLionel Sambuc         !CodeGenOpts.CoverageNoFunctionNamesInData;
378f4a2713aSLionel Sambuc     MPM->add(createGCOVProfilerPass(Options));
379f4a2713aSLionel Sambuc     if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
380f4a2713aSLionel Sambuc       MPM->add(createStripSymbolsPass(true));
381f4a2713aSLionel Sambuc   }
382f4a2713aSLionel Sambuc 
383*0a6a1f1dSLionel Sambuc   if (CodeGenOpts.ProfileInstrGenerate) {
384*0a6a1f1dSLionel Sambuc     InstrProfOptions Options;
385*0a6a1f1dSLionel Sambuc     Options.NoRedZone = CodeGenOpts.DisableRedZone;
386*0a6a1f1dSLionel Sambuc     MPM->add(createInstrProfilingPass(Options));
387*0a6a1f1dSLionel Sambuc   }
388*0a6a1f1dSLionel Sambuc 
389f4a2713aSLionel Sambuc   PMBuilder.populateModulePassManager(*MPM);
390f4a2713aSLionel Sambuc }
391f4a2713aSLionel Sambuc 
CreateTargetMachine(bool MustCreateTM)392f4a2713aSLionel Sambuc TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
393f4a2713aSLionel Sambuc   // Create the TargetMachine for generating code.
394f4a2713aSLionel Sambuc   std::string Error;
395f4a2713aSLionel Sambuc   std::string Triple = TheModule->getTargetTriple();
396f4a2713aSLionel Sambuc   const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
397f4a2713aSLionel Sambuc   if (!TheTarget) {
398f4a2713aSLionel Sambuc     if (MustCreateTM)
399f4a2713aSLionel Sambuc       Diags.Report(diag::err_fe_unable_to_create_target) << Error;
400*0a6a1f1dSLionel Sambuc     return nullptr;
401f4a2713aSLionel Sambuc   }
402f4a2713aSLionel Sambuc 
403*0a6a1f1dSLionel Sambuc   unsigned CodeModel =
404*0a6a1f1dSLionel Sambuc     llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
405*0a6a1f1dSLionel Sambuc       .Case("small", llvm::CodeModel::Small)
406*0a6a1f1dSLionel Sambuc       .Case("kernel", llvm::CodeModel::Kernel)
407*0a6a1f1dSLionel Sambuc       .Case("medium", llvm::CodeModel::Medium)
408*0a6a1f1dSLionel Sambuc       .Case("large", llvm::CodeModel::Large)
409*0a6a1f1dSLionel Sambuc       .Case("default", llvm::CodeModel::Default)
410*0a6a1f1dSLionel Sambuc       .Default(~0u);
411*0a6a1f1dSLionel Sambuc   assert(CodeModel != ~0u && "invalid code model!");
412*0a6a1f1dSLionel Sambuc   llvm::CodeModel::Model CM = static_cast<llvm::CodeModel::Model>(CodeModel);
413f4a2713aSLionel Sambuc 
414f4a2713aSLionel Sambuc   SmallVector<const char *, 16> BackendArgs;
415f4a2713aSLionel Sambuc   BackendArgs.push_back("clang"); // Fake program name.
416f4a2713aSLionel Sambuc   if (!CodeGenOpts.DebugPass.empty()) {
417f4a2713aSLionel Sambuc     BackendArgs.push_back("-debug-pass");
418f4a2713aSLionel Sambuc     BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
419f4a2713aSLionel Sambuc   }
420f4a2713aSLionel Sambuc   if (!CodeGenOpts.LimitFloatPrecision.empty()) {
421f4a2713aSLionel Sambuc     BackendArgs.push_back("-limit-float-precision");
422f4a2713aSLionel Sambuc     BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
423f4a2713aSLionel Sambuc   }
424f4a2713aSLionel Sambuc   if (llvm::TimePassesIsEnabled)
425f4a2713aSLionel Sambuc     BackendArgs.push_back("-time-passes");
426f4a2713aSLionel Sambuc   for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
427f4a2713aSLionel Sambuc     BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
428f4a2713aSLionel Sambuc   if (CodeGenOpts.NoGlobalMerge)
429*0a6a1f1dSLionel Sambuc     BackendArgs.push_back("-enable-global-merge=false");
430*0a6a1f1dSLionel Sambuc   BackendArgs.push_back(nullptr);
431f4a2713aSLionel Sambuc   llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
432f4a2713aSLionel Sambuc                                     BackendArgs.data());
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc   std::string FeaturesStr;
435f4a2713aSLionel Sambuc   if (TargetOpts.Features.size()) {
436f4a2713aSLionel Sambuc     SubtargetFeatures Features;
437f4a2713aSLionel Sambuc     for (std::vector<std::string>::const_iterator
438f4a2713aSLionel Sambuc            it = TargetOpts.Features.begin(),
439f4a2713aSLionel Sambuc            ie = TargetOpts.Features.end(); it != ie; ++it)
440f4a2713aSLionel Sambuc       Features.AddFeature(*it);
441f4a2713aSLionel Sambuc     FeaturesStr = Features.getString();
442f4a2713aSLionel Sambuc   }
443f4a2713aSLionel Sambuc 
444f4a2713aSLionel Sambuc   llvm::Reloc::Model RM = llvm::Reloc::Default;
445f4a2713aSLionel Sambuc   if (CodeGenOpts.RelocationModel == "static") {
446f4a2713aSLionel Sambuc     RM = llvm::Reloc::Static;
447f4a2713aSLionel Sambuc   } else if (CodeGenOpts.RelocationModel == "pic") {
448f4a2713aSLionel Sambuc     RM = llvm::Reloc::PIC_;
449f4a2713aSLionel Sambuc   } else {
450f4a2713aSLionel Sambuc     assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
451f4a2713aSLionel Sambuc            "Invalid PIC model!");
452f4a2713aSLionel Sambuc     RM = llvm::Reloc::DynamicNoPIC;
453f4a2713aSLionel Sambuc   }
454f4a2713aSLionel Sambuc 
455f4a2713aSLionel Sambuc   CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
456f4a2713aSLionel Sambuc   switch (CodeGenOpts.OptimizationLevel) {
457f4a2713aSLionel Sambuc   default: break;
458f4a2713aSLionel Sambuc   case 0: OptLevel = CodeGenOpt::None; break;
459f4a2713aSLionel Sambuc   case 3: OptLevel = CodeGenOpt::Aggressive; break;
460f4a2713aSLionel Sambuc   }
461f4a2713aSLionel Sambuc 
462f4a2713aSLionel Sambuc   llvm::TargetOptions Options;
463f4a2713aSLionel Sambuc 
464*0a6a1f1dSLionel Sambuc   Options.ThreadModel =
465*0a6a1f1dSLionel Sambuc     llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel)
466*0a6a1f1dSLionel Sambuc       .Case("posix", llvm::ThreadModel::POSIX)
467*0a6a1f1dSLionel Sambuc       .Case("single", llvm::ThreadModel::Single);
468*0a6a1f1dSLionel Sambuc 
469*0a6a1f1dSLionel Sambuc   if (CodeGenOpts.DisableIntegratedAS)
470*0a6a1f1dSLionel Sambuc     Options.DisableIntegratedAS = true;
471*0a6a1f1dSLionel Sambuc 
472*0a6a1f1dSLionel Sambuc   if (CodeGenOpts.CompressDebugSections)
473*0a6a1f1dSLionel Sambuc     Options.CompressDebugSections = true;
474*0a6a1f1dSLionel Sambuc 
475f4a2713aSLionel Sambuc   // Set frame pointer elimination mode.
476f4a2713aSLionel Sambuc   if (!CodeGenOpts.DisableFPElim) {
477f4a2713aSLionel Sambuc     Options.NoFramePointerElim = false;
478f4a2713aSLionel Sambuc   } else if (CodeGenOpts.OmitLeafFramePointer) {
479f4a2713aSLionel Sambuc     Options.NoFramePointerElim = false;
480f4a2713aSLionel Sambuc   } else {
481f4a2713aSLionel Sambuc     Options.NoFramePointerElim = true;
482f4a2713aSLionel Sambuc   }
483f4a2713aSLionel Sambuc 
484f4a2713aSLionel Sambuc   if (CodeGenOpts.UseInitArray)
485f4a2713aSLionel Sambuc     Options.UseInitArray = true;
486f4a2713aSLionel Sambuc 
487f4a2713aSLionel Sambuc   // Set float ABI type.
488f4a2713aSLionel Sambuc   if (CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp")
489f4a2713aSLionel Sambuc     Options.FloatABIType = llvm::FloatABI::Soft;
490f4a2713aSLionel Sambuc   else if (CodeGenOpts.FloatABI == "hard")
491f4a2713aSLionel Sambuc     Options.FloatABIType = llvm::FloatABI::Hard;
492f4a2713aSLionel Sambuc   else {
493f4a2713aSLionel Sambuc     assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
494f4a2713aSLionel Sambuc     Options.FloatABIType = llvm::FloatABI::Default;
495f4a2713aSLionel Sambuc   }
496f4a2713aSLionel Sambuc 
497f4a2713aSLionel Sambuc   // Set FP fusion mode.
498f4a2713aSLionel Sambuc   switch (CodeGenOpts.getFPContractMode()) {
499f4a2713aSLionel Sambuc   case CodeGenOptions::FPC_Off:
500f4a2713aSLionel Sambuc     Options.AllowFPOpFusion = llvm::FPOpFusion::Strict;
501f4a2713aSLionel Sambuc     break;
502f4a2713aSLionel Sambuc   case CodeGenOptions::FPC_On:
503f4a2713aSLionel Sambuc     Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
504f4a2713aSLionel Sambuc     break;
505f4a2713aSLionel Sambuc   case CodeGenOptions::FPC_Fast:
506f4a2713aSLionel Sambuc     Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
507f4a2713aSLionel Sambuc     break;
508f4a2713aSLionel Sambuc   }
509f4a2713aSLionel Sambuc 
510f4a2713aSLionel Sambuc   Options.LessPreciseFPMADOption = CodeGenOpts.LessPreciseFPMAD;
511f4a2713aSLionel Sambuc   Options.NoInfsFPMath = CodeGenOpts.NoInfsFPMath;
512f4a2713aSLionel Sambuc   Options.NoNaNsFPMath = CodeGenOpts.NoNaNsFPMath;
513f4a2713aSLionel Sambuc   Options.NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
514f4a2713aSLionel Sambuc   Options.UnsafeFPMath = CodeGenOpts.UnsafeFPMath;
515f4a2713aSLionel Sambuc   Options.UseSoftFloat = CodeGenOpts.SoftFloat;
516f4a2713aSLionel Sambuc   Options.StackAlignmentOverride = CodeGenOpts.StackAlignment;
517f4a2713aSLionel Sambuc   Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;
518f4a2713aSLionel Sambuc   Options.TrapFuncName = CodeGenOpts.TrapFuncName;
519f4a2713aSLionel Sambuc   Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
520*0a6a1f1dSLionel Sambuc   Options.FunctionSections = CodeGenOpts.FunctionSections;
521*0a6a1f1dSLionel Sambuc   Options.DataSections = CodeGenOpts.DataSections;
522*0a6a1f1dSLionel Sambuc 
523*0a6a1f1dSLionel Sambuc   Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
524*0a6a1f1dSLionel Sambuc   Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
525*0a6a1f1dSLionel Sambuc   Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
526*0a6a1f1dSLionel Sambuc   Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
527*0a6a1f1dSLionel Sambuc   Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
528*0a6a1f1dSLionel Sambuc   Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
529*0a6a1f1dSLionel Sambuc   Options.MCOptions.ABIName = TargetOpts.ABI;
530f4a2713aSLionel Sambuc 
531f4a2713aSLionel Sambuc   TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
532f4a2713aSLionel Sambuc                                                      FeaturesStr, Options,
533f4a2713aSLionel Sambuc                                                      RM, CM, OptLevel);
534f4a2713aSLionel Sambuc 
535f4a2713aSLionel Sambuc   return TM;
536f4a2713aSLionel Sambuc }
537f4a2713aSLionel Sambuc 
AddEmitPasses(BackendAction Action,formatted_raw_ostream & OS)538f4a2713aSLionel Sambuc bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
539*0a6a1f1dSLionel Sambuc                                        formatted_raw_ostream &OS) {
540f4a2713aSLionel Sambuc 
541f4a2713aSLionel Sambuc   // Create the code generator passes.
542*0a6a1f1dSLionel Sambuc   PassManager *PM = getCodeGenPasses();
543f4a2713aSLionel Sambuc 
544f4a2713aSLionel Sambuc   // Add LibraryInfo.
545f4a2713aSLionel Sambuc   llvm::Triple TargetTriple(TheModule->getTargetTriple());
546*0a6a1f1dSLionel Sambuc   PM->add(createTLI(TargetTriple, CodeGenOpts));
547f4a2713aSLionel Sambuc 
548f4a2713aSLionel Sambuc   // Add Target specific analysis passes.
549f4a2713aSLionel Sambuc   TM->addAnalysisPasses(*PM);
550f4a2713aSLionel Sambuc 
551f4a2713aSLionel Sambuc   // Normal mode, emit a .s or .o file by running the code generator. Note,
552f4a2713aSLionel Sambuc   // this also adds codegenerator level optimization passes.
553f4a2713aSLionel Sambuc   TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
554f4a2713aSLionel Sambuc   if (Action == Backend_EmitObj)
555f4a2713aSLionel Sambuc     CGFT = TargetMachine::CGFT_ObjectFile;
556f4a2713aSLionel Sambuc   else if (Action == Backend_EmitMCNull)
557f4a2713aSLionel Sambuc     CGFT = TargetMachine::CGFT_Null;
558f4a2713aSLionel Sambuc   else
559f4a2713aSLionel Sambuc     assert(Action == Backend_EmitAssembly && "Invalid action!");
560f4a2713aSLionel Sambuc 
561f4a2713aSLionel Sambuc   // Add ObjC ARC final-cleanup optimizations. This is done as part of the
562f4a2713aSLionel Sambuc   // "codegen" passes so that it isn't run multiple times when there is
563f4a2713aSLionel Sambuc   // inlining happening.
564f4a2713aSLionel Sambuc   if (LangOpts.ObjCAutoRefCount &&
565f4a2713aSLionel Sambuc       CodeGenOpts.OptimizationLevel > 0)
566f4a2713aSLionel Sambuc     PM->add(createObjCARCContractPass());
567f4a2713aSLionel Sambuc 
568f4a2713aSLionel Sambuc   if (TM->addPassesToEmitFile(*PM, OS, CGFT,
569f4a2713aSLionel Sambuc                               /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
570f4a2713aSLionel Sambuc     Diags.Report(diag::err_fe_unable_to_interface_with_target);
571f4a2713aSLionel Sambuc     return false;
572f4a2713aSLionel Sambuc   }
573f4a2713aSLionel Sambuc 
574f4a2713aSLionel Sambuc   return true;
575f4a2713aSLionel Sambuc }
576f4a2713aSLionel Sambuc 
EmitAssembly(BackendAction Action,raw_ostream * OS)577f4a2713aSLionel Sambuc void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
578*0a6a1f1dSLionel Sambuc   TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
579f4a2713aSLionel Sambuc   llvm::formatted_raw_ostream FormattedOS;
580f4a2713aSLionel Sambuc 
581f4a2713aSLionel Sambuc   bool UsesCodeGen = (Action != Backend_EmitNothing &&
582f4a2713aSLionel Sambuc                       Action != Backend_EmitBC &&
583f4a2713aSLionel Sambuc                       Action != Backend_EmitLL);
584*0a6a1f1dSLionel Sambuc   if (!TM)
585*0a6a1f1dSLionel Sambuc     TM.reset(CreateTargetMachine(UsesCodeGen));
586*0a6a1f1dSLionel Sambuc 
587f4a2713aSLionel Sambuc   if (UsesCodeGen && !TM) return;
588*0a6a1f1dSLionel Sambuc   CreatePasses();
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc   switch (Action) {
591f4a2713aSLionel Sambuc   case Backend_EmitNothing:
592f4a2713aSLionel Sambuc     break;
593f4a2713aSLionel Sambuc 
594f4a2713aSLionel Sambuc   case Backend_EmitBC:
595*0a6a1f1dSLionel Sambuc     getPerModulePasses()->add(createBitcodeWriterPass(*OS));
596f4a2713aSLionel Sambuc     break;
597f4a2713aSLionel Sambuc 
598f4a2713aSLionel Sambuc   case Backend_EmitLL:
599f4a2713aSLionel Sambuc     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
600*0a6a1f1dSLionel Sambuc     getPerModulePasses()->add(createPrintModulePass(FormattedOS));
601f4a2713aSLionel Sambuc     break;
602f4a2713aSLionel Sambuc 
603f4a2713aSLionel Sambuc   default:
604f4a2713aSLionel Sambuc     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
605*0a6a1f1dSLionel Sambuc     if (!AddEmitPasses(Action, FormattedOS))
606f4a2713aSLionel Sambuc       return;
607f4a2713aSLionel Sambuc   }
608f4a2713aSLionel Sambuc 
609f4a2713aSLionel Sambuc   // Before executing passes, print the final values of the LLVM options.
610f4a2713aSLionel Sambuc   cl::PrintOptionValues();
611f4a2713aSLionel Sambuc 
612f4a2713aSLionel Sambuc   // Run passes. For now we do all passes at once, but eventually we
613f4a2713aSLionel Sambuc   // would like to have the option of streaming code generation.
614f4a2713aSLionel Sambuc 
615f4a2713aSLionel Sambuc   if (PerFunctionPasses) {
616f4a2713aSLionel Sambuc     PrettyStackTraceString CrashInfo("Per-function optimization");
617f4a2713aSLionel Sambuc 
618f4a2713aSLionel Sambuc     PerFunctionPasses->doInitialization();
619f4a2713aSLionel Sambuc     for (Module::iterator I = TheModule->begin(),
620f4a2713aSLionel Sambuc            E = TheModule->end(); I != E; ++I)
621f4a2713aSLionel Sambuc       if (!I->isDeclaration())
622f4a2713aSLionel Sambuc         PerFunctionPasses->run(*I);
623f4a2713aSLionel Sambuc     PerFunctionPasses->doFinalization();
624f4a2713aSLionel Sambuc   }
625f4a2713aSLionel Sambuc 
626f4a2713aSLionel Sambuc   if (PerModulePasses) {
627f4a2713aSLionel Sambuc     PrettyStackTraceString CrashInfo("Per-module optimization passes");
628f4a2713aSLionel Sambuc     PerModulePasses->run(*TheModule);
629f4a2713aSLionel Sambuc   }
630f4a2713aSLionel Sambuc 
631f4a2713aSLionel Sambuc   if (CodeGenPasses) {
632f4a2713aSLionel Sambuc     PrettyStackTraceString CrashInfo("Code generation");
633f4a2713aSLionel Sambuc     CodeGenPasses->run(*TheModule);
634f4a2713aSLionel Sambuc   }
635f4a2713aSLionel Sambuc }
636f4a2713aSLionel Sambuc 
EmitBackendOutput(DiagnosticsEngine & Diags,const CodeGenOptions & CGOpts,const clang::TargetOptions & TOpts,const LangOptions & LOpts,StringRef TDesc,Module * M,BackendAction Action,raw_ostream * OS)637f4a2713aSLionel Sambuc void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
638f4a2713aSLionel Sambuc                               const CodeGenOptions &CGOpts,
639f4a2713aSLionel Sambuc                               const clang::TargetOptions &TOpts,
640*0a6a1f1dSLionel Sambuc                               const LangOptions &LOpts, StringRef TDesc,
641*0a6a1f1dSLionel Sambuc                               Module *M, BackendAction Action,
642*0a6a1f1dSLionel Sambuc                               raw_ostream *OS) {
643f4a2713aSLionel Sambuc   EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
644f4a2713aSLionel Sambuc 
645f4a2713aSLionel Sambuc   AsmHelper.EmitAssembly(Action, OS);
646*0a6a1f1dSLionel Sambuc 
647*0a6a1f1dSLionel Sambuc   // If an optional clang TargetInfo description string was passed in, use it to
648*0a6a1f1dSLionel Sambuc   // verify the LLVM TargetMachine's DataLayout.
649*0a6a1f1dSLionel Sambuc   if (AsmHelper.TM && !TDesc.empty()) {
650*0a6a1f1dSLionel Sambuc     std::string DLDesc = AsmHelper.TM->getSubtargetImpl()
651*0a6a1f1dSLionel Sambuc                              ->getDataLayout()
652*0a6a1f1dSLionel Sambuc                              ->getStringRepresentation();
653*0a6a1f1dSLionel Sambuc     if (DLDesc != TDesc) {
654*0a6a1f1dSLionel Sambuc       unsigned DiagID = Diags.getCustomDiagID(
655*0a6a1f1dSLionel Sambuc           DiagnosticsEngine::Error, "backend data layout '%0' does not match "
656*0a6a1f1dSLionel Sambuc                                     "expected target description '%1'");
657*0a6a1f1dSLionel Sambuc       Diags.Report(DiagID) << DLDesc << TDesc;
658*0a6a1f1dSLionel Sambuc     }
659*0a6a1f1dSLionel Sambuc   }
660f4a2713aSLionel Sambuc }
661