From 8bc3434e68028263c42dd26bde3c16450cb146f4 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 16 May 2012 08:32:49 +0000 Subject: [PATCH] Teach the 'opt' tool about '-Os' and '-Oz', corresponding to the Clang options, to enable easier testing of the innards of LLVM that are enabled by such optimization strategies. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that this doesn't provide the (much needed) function attribute support for -Oz (as opposed to -Os), but still seems like a positive step to better test the logic that Clang currently relies on. Patch by Patrik Hägglund. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156913 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Other/optimize-options.ll | 8 +++++ tools/opt/opt.cpp | 53 ++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 test/Other/optimize-options.ll diff --git a/test/Other/optimize-options.ll b/test/Other/optimize-options.ll new file mode 100644 index 00000000000..5b1fe52ac15 --- /dev/null +++ b/test/Other/optimize-options.ll @@ -0,0 +1,8 @@ +;RUN: opt -S -O1 -debug-pass=Arguments |& FileCheck %s +;RUN: opt -S -O2 -debug-pass=Arguments |& FileCheck %s +;RUN: opt -S -Os -debug-pass=Arguments |& FileCheck %s +;RUN: opt -S -Oz -debug-pass=Arguments |& FileCheck %s +;RUN: opt -S -O3 -debug-pass=Arguments |& FileCheck %s + +; Just check that we get a non-empty set of passes for each -O opton. +;CHECK: Pass Arguments: {{.*}} -print-module diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index a5b0511fd98..d9758b35ff9 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -104,15 +104,23 @@ StandardLinkOpts("std-link-opts", static cl::opt OptLevelO1("O1", - cl::desc("Optimization level 1. Similar to llvm-gcc -O1")); + cl::desc("Optimization level 1. Similar to clang -O1")); static cl::opt OptLevelO2("O2", - cl::desc("Optimization level 2. Similar to llvm-gcc -O2")); + cl::desc("Optimization level 2. Similar to clang -O2")); + +static cl::opt +OptLevelOs("Os", + cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os")); + +static cl::opt +OptLevelOz("Oz", + cl::desc("Like -Os but reduces code size further. Similar to clang -Oz")); static cl::opt OptLevelO3("O3", - cl::desc("Optimization level 3. Similar to llvm-gcc -O3")); + cl::desc("Optimization level 3. Similar to clang -O3")); static cl::opt TargetTriple("mtriple", cl::desc("Override target triple for module")); @@ -409,16 +417,21 @@ static inline void addPass(PassManagerBase &PM, Pass *P) { /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, - unsigned OptLevel) { + unsigned OptLevel, unsigned SizeLevel) { FPM.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; + Builder.SizeLevel = SizeLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { unsigned Threshold = 225; + if (SizeLevel == 1) // -Os + Threshold = 75; + else if (SizeLevel == 2) // -Oz + Threshold = 25; if (OptLevel > 2) Threshold = 275; Builder.Inliner = createFunctionInliningPass(Threshold); @@ -571,7 +584,7 @@ int main(int argc, char **argv) { Passes.add(TD); OwningPtr FPasses; - if (OptLevelO1 || OptLevelO2 || OptLevelO3) { + if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (TD) FPasses->add(new TargetData(*TD)); @@ -617,17 +630,27 @@ int main(int argc, char **argv) { } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 1); + AddOptimizationPasses(Passes, *FPasses, 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2); + AddOptimizationPasses(Passes, *FPasses, 2, 0); OptLevelO2 = false; } + if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, 2, 1); + OptLevelOs = false; + } + + if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, 2, 2); + OptLevelOz = false; + } + if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 3); + AddOptimizationPasses(Passes, *FPasses, 3, 0); OptLevelO3 = false; } @@ -682,15 +705,21 @@ int main(int argc, char **argv) { } if (OptLevelO1) - AddOptimizationPasses(Passes, *FPasses, 1); + AddOptimizationPasses(Passes, *FPasses, 1, 0); if (OptLevelO2) - AddOptimizationPasses(Passes, *FPasses, 2); + AddOptimizationPasses(Passes, *FPasses, 2, 0); + + if (OptLevelOs) + AddOptimizationPasses(Passes, *FPasses, 2, 1); + + if (OptLevelOz) + AddOptimizationPasses(Passes, *FPasses, 2, 2); if (OptLevelO3) - AddOptimizationPasses(Passes, *FPasses, 3); + AddOptimizationPasses(Passes, *FPasses, 3, 0); - if (OptLevelO1 || OptLevelO2 || OptLevelO3) { + if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) FPasses->run(*F);