#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"
Diagnostic &Diags;
const CodeGenOptions &CodeGenOpts;
const TargetOptions &TargetOpts;
+ const LangOptions &LangOpts;
Module *TheModule;
Timer CodeGenerationTime;
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) {}
}
+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;
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());
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);
}
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);
}
BackendAction Action;
const CodeGenOptions &CodeGenOpts;
const TargetOptions &TargetOpts;
+ const LangOptions &LangOpts;
llvm::raw_ostream *AsmOutStream;
ASTContext *Context;
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)) {
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);
BEConsumer =
new BackendConsumer(BA, CI.getDiagnostics(),
CI.getCodeGenOpts(), CI.getTargetOpts(),
+ CI.getLangOpts(),
CI.getFrontendOpts().ShowTimers, InFile, OS.take(),
*VMContext);
return BEConsumer;
}
EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(),
- CI.getTargetOpts(), TheModule.get(),
+ CI.getTargetOpts(), CI.getLangOpts(),
+ TheModule.get(),
BA, OS);
return;
}