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