]> granicus.if.org Git - clang/commitdiff
Add clang-cc support for -disable-llvm-optzns.
authorDaniel Dunbar <daniel@zuster.org>
Tue, 2 Jun 2009 22:07:45 +0000 (22:07 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 2 Jun 2009 22:07:45 +0000 (22:07 +0000)
 - Avoids running any LLVM optimizations, even at -O2, etc., while still keeping
   any language changes these optimizations imply.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72742 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/CompileOptions.h
lib/Frontend/Backend.cpp
test/CodeGen/always_inline.c [new file with mode: 0644]
tools/clang-cc/clang-cc.cpp

index 1af5e48ea119489a193b889964580d0e07dd6ffb..34815c8cb54f38b7037302f550122e99188c4667 100644 (file)
@@ -23,12 +23,17 @@ namespace clang {
 /// is optimized and passed to the backend.
 class CompileOptions {
 public:
+  enum InliningMethod {
+    NoInlining,         // Perform no inlining whatsoever.
+    NormalInlining,     // Use the standard function inlining pass.
+    OnlyAlwaysInlining  // Only run the always inlining pass.
+  };
+
   unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
   unsigned OptimizeSize      : 1; /// If -Os is specified.
   unsigned DebugInfo         : 1; /// Should generate deubg info (-g).
   unsigned UnitAtATime       : 1; /// Unused. For mirroring GCC
                                   /// optimization selection.
-  unsigned InlineFunctions   : 1; /// Should functions be inlined?
   unsigned SimplifyLibCalls  : 1; /// Should standard library calls be
                                   /// treated specially.
   unsigned UnrollLoops       : 1; /// Control whether loops are unrolled.
@@ -37,6 +42,9 @@ public:
   unsigned TimePasses        : 1; /// Set when -ftime-report is enabled.
   unsigned NoCommon          : 1; /// Set when -fno-common or C++ is enabled.
 
+  /// Inlining - The kind of inlining to perform.
+  InliningMethod Inlining;
+
   /// CPU - An optional CPU to target.
   std::string CPU;
 
@@ -50,10 +58,11 @@ public:
     OptimizeSize = 0;
     DebugInfo = 0;
     UnitAtATime = 1;
-    InlineFunctions = SimplifyLibCalls = UnrollLoops = 0;
+    SimplifyLibCalls = UnrollLoops = 0;
     VerifyModule = 1;
     TimePasses = 0;
     NoCommon = 0;
+    Inlining = NoInlining;
   }  
 };
 
index 44aa3a81a96ef50b2c04304a178bfa1897a2ff27..697ba941af231a2d8b5fccdf982eadd31291d8cd 100644 (file)
@@ -294,10 +294,16 @@ void BackendConsumer::CreatePasses() {
       PM->add(createPruneEHPass());               // Remove dead EH info
       PM->add(createFunctionAttrsPass());         // Set readonly/readnone attrs
     }
-    if (CompileOpts.InlineFunctions)
+    switch (CompileOpts.Inlining) {
+    case CompileOptions::NoInlining:
+      break;
+    case CompileOptions::NormalInlining:
       PM->add(createFunctionInliningPass());      // Inline small functions
-    else 
+      break;
+    case CompileOptions::OnlyAlwaysInlining:
       PM->add(createAlwaysInlinerPass());         // Respect always_inline
+      break;
+    }
     if (CompileOpts.OptimizationLevel > 2)
       PM->add(createArgumentPromotionPass());     // Scalarize uninlined fn args
     if (CompileOpts.SimplifyLibCalls)
@@ -341,7 +347,16 @@ void BackendConsumer::CreatePasses() {
     if (CompileOpts.OptimizationLevel > 1 && CompileOpts.UnitAtATime)
       PM->add(createConstantMergePass());         // Merge dup global constants 
   } else {
-    PM->add(createAlwaysInlinerPass());  
+    switch (CompileOpts.Inlining) {
+    case CompileOptions::NoInlining:
+      break;
+    case CompileOptions::NormalInlining:
+      PM->add(createFunctionInliningPass());      // Inline small functions
+      break;
+    case CompileOptions::OnlyAlwaysInlining:
+      PM->add(createAlwaysInlinerPass());         // Respect always_inline
+      break;
+    }
   }
 }
 
diff --git a/test/CodeGen/always_inline.c b/test/CodeGen/always_inline.c
new file mode 100644 (file)
index 0000000..d159bd2
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: clang-cc -emit-llvm -o %t %s &&
+// RUN: grep '@f0' %t | count 0 &&
+// RUN: clang-cc -disable-llvm-optzns -emit-llvm -o %t %s &&
+// RUN: grep '@f0' %t | count 2
+
+//static int f0() { 
+static int __attribute__((always_inline)) f0() { 
+  return 1;
+}
+
+int f1() {
+  return f0();
+}
index a0ccafa9afceacd88d610414d9bb52b461c578e6..0e0a07275892196eef8499cd9a4f9380d3e38628 100644 (file)
@@ -666,6 +666,10 @@ DollarsInIdents("fdollars-in-identifiers",
 static llvm::cl::opt<bool>
 OptSize("Os", llvm::cl::desc("Optimize for size"));
 
+static llvm::cl::opt<bool>
+DisableLLVMOptimizations("disable-llvm-optzns", 
+                         llvm::cl::desc("Don't run LLVM optimization passes"));
+
 static llvm::cl::opt<bool>
 NoCommon("fno-common",
          llvm::cl::desc("Compile common globals like normal definitions"),
@@ -1420,16 +1424,26 @@ static void InitializeCompileOptions(CompileOptions &Opts,
                                      const llvm::StringMap<bool> &Features) {
   Opts.OptimizeSize = OptSize;
   Opts.DebugInfo = GenerateDebugInfo;
-  if (OptSize) {
-    // -Os implies -O2
-    // FIXME: Diagnose conflicting options.
-    Opts.OptimizationLevel = 2;
+
+  if (DisableLLVMOptimizations) {
+    Opts.OptimizationLevel = 0;
+    Opts.Inlining = CompileOptions::NoInlining;
   } else {
-    Opts.OptimizationLevel = OptLevel;
+    if (OptSize) {
+      // -Os implies -O2
+      Opts.OptimizationLevel = 2;
+    } else {
+      Opts.OptimizationLevel = OptLevel;
+    }
+
+    // We must always run at least the always inlining pass.
+    if (Opts.OptimizationLevel > 1)
+      Opts.Inlining = CompileOptions::NormalInlining;
+    else
+      Opts.Inlining = CompileOptions::OnlyAlwaysInlining;
   }
 
   // FIXME: There are llvm-gcc options to control these selectively.
-  Opts.InlineFunctions = (Opts.OptimizationLevel > 1);
   Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !OptSize);
   Opts.SimplifyLibCalls = !LangOpts.NoBuiltin;