summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/CodeGen/BackendUtil.h4
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp36
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp12
3 files changed, 45 insertions, 7 deletions
diff --git a/clang/include/clang/CodeGen/BackendUtil.h b/clang/include/clang/CodeGen/BackendUtil.h
index abcef8130db..9636d6e527c 100644
--- a/clang/include/clang/CodeGen/BackendUtil.h
+++ b/clang/include/clang/CodeGen/BackendUtil.h
@@ -19,6 +19,7 @@ namespace clang {
class Diagnostic;
class CodeGenOptions;
class TargetOptions;
+ class LangOptions;
enum BackendAction {
Backend_EmitAssembly, ///< Emit native assembly files
@@ -30,7 +31,8 @@ namespace clang {
};
void EmitBackendOutput(Diagnostic &Diags, const CodeGenOptions &CGOpts,
- const TargetOptions &TOpts, llvm::Module *M,
+ const TargetOptions &TOpts, const LangOptions &LOpts,
+ llvm::Module *M,
BackendAction Action, llvm::raw_ostream *OS);
}
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;
}
OpenPOWER on IntegriCloud