From: Daniel Dunbar Date: Tue, 2 Jun 2009 22:07:45 +0000 (+0000) Subject: Add clang-cc support for -disable-llvm-optzns. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=877db3852e29c5b5a2dc25b3fe4a3b78619aa904;p=clang Add clang-cc support for -disable-llvm-optzns. - 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 --- diff --git a/include/clang/Frontend/CompileOptions.h b/include/clang/Frontend/CompileOptions.h index 1af5e48ea1..34815c8cb5 100644 --- a/include/clang/Frontend/CompileOptions.h +++ b/include/clang/Frontend/CompileOptions.h @@ -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; } }; diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp index 44aa3a81a9..697ba941af 100644 --- a/lib/Frontend/Backend.cpp +++ b/lib/Frontend/Backend.cpp @@ -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 index 0000000000..d159bd2233 --- /dev/null +++ b/test/CodeGen/always_inline.c @@ -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(); +} diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index a0ccafa9af..0e0a072758 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -666,6 +666,10 @@ DollarsInIdents("fdollars-in-identifiers", static llvm::cl::opt OptSize("Os", llvm::cl::desc("Optimize for size")); +static llvm::cl::opt +DisableLLVMOptimizations("disable-llvm-optzns", + llvm::cl::desc("Don't run LLVM optimization passes")); + static llvm::cl::opt NoCommon("fno-common", llvm::cl::desc("Compile common globals like normal definitions"), @@ -1420,16 +1424,26 @@ static void InitializeCompileOptions(CompileOptions &Opts, const llvm::StringMap &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;