diff options
Diffstat (limited to 'lib/CodeGen/BackendUtil.cpp')
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index f997721639..85f42db81f 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -10,6 +10,7 @@ #include "clang/CodeGen/BackendUtil.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Basic/LangOptions.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/Module.h" @@ -39,6 +40,7 @@ class EmitAssemblyHelper { Diagnostic &Diags; const CodeGenOptions &CodeGenOpts; const TargetOptions &TargetOpts; + const LangOptions &LangOpts; Module *TheModule; Timer CodeGenerationTime; @@ -82,8 +84,9 @@ private: public: EmitAssemblyHelper(Diagnostic &_Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, + const LangOptions &LOpts, Module *M) - : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), + : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), TheModule(M), CodeGenerationTime("Code Generation Time"), CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {} @@ -98,6 +101,16 @@ public: } +static void addObjCARCExpandPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { + if (Builder.OptLevel > 0) + PM.add(createObjCARCExpandPass()); +} + +static void addObjCARCOptPass(const PassManagerBuilder &Builder, PassManagerBase &PM) { + if (Builder.OptLevel > 0) + PM.add(createObjCARCOptPass()); +} + void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; @@ -116,6 +129,14 @@ void EmitAssemblyHelper::CreatePasses() { PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; + + // In ObjC ARC mode, add the main ARC optimization passes. + if (LangOpts.ObjCAutoRefCount) { + PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, + addObjCARCExpandPass); + PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, + addObjCARCOptPass); + } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); @@ -297,6 +318,13 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, CGFT = TargetMachine::CGFT_Null; else assert(Action == Backend_EmitAssembly && "Invalid action!"); + + // Add ObjC ARC final-cleanup optimizations. This is done as part of the + // "codegen" passes so that it isn't run multiple times when there is + // inlining happening. + if (LangOpts.ObjCAutoRefCount) + PM->add(createObjCARCContractPass()); + if (TM->addPassesToEmitFile(*PM, OS, CGFT, OptLevel, /*DisableVerify=*/!CodeGenOpts.VerifyModule)) { Diags.Report(diag::err_fe_unable_to_interface_with_target); @@ -359,9 +387,11 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) { } void clang::EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts, - const TargetOptions &TOpts, Module *M, + const TargetOptions &TOpts, + const LangOptions &LOpts, + Module *M, BackendAction Action, raw_ostream *OS) { - EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, M); + EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M); AsmHelper.EmitAssembly(Action, OS); } |