diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 36 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 12 |
2 files changed, 42 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index f997721639e..85f42db81f5 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/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); } diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 62fa1f9843d..263e01e4f18 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -34,6 +34,7 @@ namespace clang { BackendAction Action; const CodeGenOptions &CodeGenOpts; const TargetOptions &TargetOpts; + const LangOptions &LangOpts; llvm::raw_ostream *AsmOutStream; ASTContext *Context; @@ -46,13 +47,16 @@ namespace clang { public: BackendConsumer(BackendAction action, Diagnostic &_Diags, const CodeGenOptions &compopts, - const TargetOptions &targetopts, bool TimePasses, + const TargetOptions &targetopts, + const LangOptions &langopts, + bool TimePasses, const std::string &infile, llvm::raw_ostream *OS, LLVMContext &C) : Diags(_Diags), Action(action), CodeGenOpts(compopts), TargetOpts(targetopts), + LangOpts(langopts), AsmOutStream(OS), LLVMIRGeneration("LLVM IR Generation Time"), Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)) { @@ -126,7 +130,7 @@ namespace clang { void *OldContext = Ctx.getInlineAsmDiagnosticContext(); Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this); - EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, + EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, TheModule.get(), Action, AsmOutStream); Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); @@ -285,6 +289,7 @@ ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), CI.getCodeGenOpts(), CI.getTargetOpts(), + CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, OS.take(), *VMContext); return BEConsumer; @@ -332,7 +337,8 @@ void CodeGenAction::ExecuteAction() { } EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), - CI.getTargetOpts(), TheModule.get(), + CI.getTargetOpts(), CI.getLangOpts(), + TheModule.get(), BA, OS); return; } |