Fix -save-temp when using objc-arc, sanitizer and profiling
authorSteven Wu <stevenwu@apple.com>
Fri, 17 Jul 2015 20:09:56 +0000 (20:09 +0000)
committerSteven Wu <stevenwu@apple.com>
Fri, 17 Jul 2015 20:09:56 +0000 (20:09 +0000)
Currently, -save-temp will cause ObjCARC optimization to be dropped,
sanitizer pass to run early in the pipeline, and profiling
instrumentation to run twice.
Fix the issue by properly disable all passes in the optimization
pipeline when generating bitcode output and parse some of the Language
Options even when the input is bitcode so the passes can be setup
correctly.

llvm-svn: 242565

clang/include/clang/Driver/CC1Options.td
clang/include/clang/Frontend/CodeGenOptions.def
clang/lib/CodeGen/BackendUtil.cpp
clang/lib/Driver/Tools.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/test/CodeGen/sanitize-address-field-padding.cpp
clang/test/CodeGenObjC/arc.ll [new file with mode: 0644]
clang/test/Driver/save-temps.c

index d2f0d05..16b105b 100644 (file)
@@ -153,6 +153,9 @@ def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
   HelpText<"Don't run LLVM optimization passes">;
 def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
   HelpText<"Don't run the LLVM IR verifier pass">;
+def disable_llvm_passes : Flag<["-"], "disable-llvm-passes">,
+  HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the "
+           "frontend by not running any LLVM passes at all">;
 def disable_red_zone : Flag<["-"], "disable-red-zone">,
   HelpText<"Do not emit code that uses the red zone.">;
 def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
index 803d023..482c9d0 100644 (file)
@@ -48,6 +48,9 @@ CODEGENOPT(DisableLLVMOpts   , 1, 0) ///< Don't run any optimizations, for use i
                                      ///< getting .bc files that correspond to the
                                      ///< internal state before optimizations are
                                      ///< done.
+CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
+                                     ///< the pristine IR generated by the
+                                     ///< frontend.
 CODEGENOPT(DisableRedZone    , 1, 0) ///< Set when -mno-red-zone is enabled.
 CODEGENOPT(DisableTailCalls  , 1, 0) ///< Do not emit tail calls.
 CODEGENOPT(EmitDeclMetadata  , 1, 0) ///< Emit special metadata indicating what
index afcb9e5..5754bb6 100644 (file)
@@ -272,6 +272,9 @@ static void addSymbolRewriterPass(const CodeGenOptions &Opts,
 }
 
 void EmitAssemblyHelper::CreatePasses() {
+  if (CodeGenOpts.DisableLLVMPasses)
+    return;
+
   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
 
index d4a307b..40643cc 100644 (file)
@@ -4800,7 +4800,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
   // parser.
   Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
-  bool OptDisabled = false;
   for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
     A->claim();
 
@@ -4808,17 +4807,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     // it and developers have been trained to spell it with -mllvm.
     if (StringRef(A->getValue(0)) == "-disable-llvm-optzns") {
       CmdArgs.push_back("-disable-llvm-optzns");
-      OptDisabled = true;
     } else
       A->render(Args, CmdArgs);
   }
 
   // With -save-temps, we want to save the unoptimized bitcode output from the
-  // CompileJobAction, so disable optimizations if they are not already
-  // disabled.
-  if (C.getDriver().isSaveTempsEnabled() && !OptDisabled &&
-      isa<CompileJobAction>(JA))
-    CmdArgs.push_back("-disable-llvm-optzns");
+  // CompileJobAction, use -disable-llvm-passes to get pristine IR generated
+  // by the frontend.
+  if (C.getDriver().isSaveTempsEnabled() && isa<CompileJobAction>(JA))
+    CmdArgs.push_back("-disable-llvm-passes");
 
   if (Output.getType() == types::TY_Dependencies) {
     // Handled with other dependency code.
index f325144..e4cfba3 100644 (file)
@@ -426,6 +426,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
     Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
 
   Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
+  Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes);
   Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
   Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
   Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
@@ -1887,7 +1888,16 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
   Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
                               Res.getTargetOpts());
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
-  if (DashX != IK_AST && DashX != IK_LLVM_IR) {
+  if (DashX == IK_AST || DashX == IK_LLVM_IR) {
+    // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
+    // PassManager in BackendUtil.cpp. They need to be initializd no matter
+    // what the input type is.
+    if (Args.hasArg(OPT_fobjc_arc))
+      Res.getLangOpts()->ObjCAutoRefCount = 1;
+    parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
+                        Diags, Res.getLangOpts()->Sanitize);
+  } else {
+    // Other LangOpts are only initialzed when the input is not AST or LLVM IR.
     ParseLangArgs(*Res.getLangOpts(), Args, DashX, Diags);
     if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
       Res.getLangOpts()->ObjCExceptions = 1;
index d4eea1b..7bd368f 100644 (file)
@@ -5,6 +5,7 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.type.blacklist -Rsanitize-address -emit-llvm -o - %s -O1 -mconstructor-aliases 2>&1 | FileCheck %s --check-prefix=WITH_CTOR_ALIASES
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsanitize=address -fsanitize-address-field-padding=1 -fsanitize-blacklist=%t.file.blacklist -Rsanitize-address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=FILE_BLACKLIST
 // RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=NO_PADDING
+// RUN: %clang -save-temps -fsanitize=address -emit-llvm -S -o - %s 2>&1 | FileCheck %s --check-prefix=NO_PADDING
 //
 
 // The reasons to ignore a particular class are not set in stone and will change.
diff --git a/clang/test/CodeGenObjC/arc.ll b/clang/test/CodeGenObjC/arc.ll
new file mode 100644 (file)
index 0000000..caafcff
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: %clang_cc1 -Os -emit-llvm -fobjc-arc -o - %s | FileCheck %s
+
+target triple = "x86_64-apple-darwin10"
+
+declare i8* @objc_retain(i8*)
+declare void @objc_release(i8*)
+
+; CHECK-LABEL: define void @test(
+; CHECK-NOT: @objc_
+; CHECK: }
+define void @test(i8* %x, i1* %p) nounwind {
+entry:
+  br label %loop
+
+loop:
+  call i8* @objc_retain(i8* %x)
+  %q = load i1, i1* %p
+  br i1 %q, label %loop.more, label %exit
+
+loop.more:
+  call void @objc_release(i8* %x)
+  br label %loop
+
+exit:
+  call void @objc_release(i8* %x)
+  ret void
+}
index 277a901..c974d15 100644 (file)
@@ -2,7 +2,7 @@
 // RUN:   | FileCheck %s
 // CHECK: "-o" "save-temps.i"
 // CHECK: "-emit-llvm-uselists"
-// CHECK: "-disable-llvm-optzns"
+// CHECK: "-disable-llvm-passes"
 // CHECK: "-o" "save-temps.bc"
 // CHECK: "-o" "save-temps.s"
 // CHECK: "-o" "save-temps.o"
@@ -14,7 +14,7 @@
 // RUN:   | FileCheck %s -check-prefix=CWD
 // CWD: "-o" "save-temps.i"
 // CWD: "-emit-llvm-uselists"
-// CWD: "-disable-llvm-optzns"
+// CWD: "-disable-llvm-passes"
 // CWD: "-o" "save-temps.bc"
 // CWD: "-o" "save-temps.s"
 // CWD: "-o" "save-temps.o"
@@ -63,7 +63,7 @@
 // RUN: %clang -target x86_64-apple-darwin -save-temps=obj -o obj/dir/a.out -arch x86_64 %s -### 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=CHECK-OBJ
 // CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.i"
-// CHECK-OBJ: "-disable-llvm-optzns"
+// CHECK-OBJ: "-disable-llvm-passes"
 // CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.bc"
 // CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.s"
 // CHECK-OBJ: "-o" "obj/dir{{/|\\\\}}save-temps.o"
@@ -72,7 +72,7 @@
 // RUN: %clang -target x86_64-apple-darwin -save-temps=obj -arch x86_64 %s -### 2>&1 \
 // RUN:   | FileCheck %s -check-prefix=CHECK-OBJ-NOO
 // CHECK-OBJ-NOO: "-o" "save-temps.i"
-// CHECK-OBJ-NOO: "-disable-llvm-optzns"
+// CHECK-OBJ-NOO: "-disable-llvm-passes"
 // CHECK-OBJ-NOO: "-o" "save-temps.bc"
 // CHECK-OBJ-NOO: "-o" "save-temps.s"
 // CHECK-OBJ-NOO: "-o" "save-temps.o"