libLTO, llvm-lto, gold: Introduce flag for controlling optimization level.

This change also introduces a link-time optimization level of 1. This
optimization level runs only the globaldce pass as well as cleanup passes for
passes that run at -O0, specifically simplifycfg which cleans up lowerbitsets.

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20150316/266951.html

llvm-svn: 232769
diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp
index ecafb03..142e430 100644
--- a/llvm/tools/lto/lto.cpp
+++ b/llvm/tools/lto/lto.cpp
@@ -23,9 +23,13 @@
 #include "llvm/Support/TargetSelect.h"
 
 // extra command-line flags needed for LTOCodeGenerator
-static cl::opt<bool>
-DisableOpt("disable-opt", cl::init(false),
-  cl::desc("Do not run any optimization passes"));
+static cl::opt<char>
+OptLevel("O",
+         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
+                  "(default = '-O2')"),
+         cl::Prefix,
+         cl::ZeroOrMore,
+         cl::init('2'));
 
 static cl::opt<bool>
 DisableInline("disable-inlining", cl::init(false),
@@ -85,6 +89,10 @@
 
     CG->setAttr(attrs.c_str());
   }
+
+  if (OptLevel < '0' || OptLevel > '3')
+    report_fatal_error("Optimization level must be between 0 and 3");
+  CG->setOptLevel(OptLevel - '0');
 }
 
 extern const char* lto_get_version() {
@@ -281,54 +289,42 @@
   unwrap(cg)->addMustPreserveSymbol(symbol);
 }
 
-bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
+static void maybeParseOptions() {
   if (!parsedOptions) {
     unwrap(cg)->parseCodeGenDebugOptions();
     lto_add_attrs(cg);
     parsedOptions = true;
   }
+}
+
+bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
+  maybeParseOptions();
   return !unwrap(cg)->writeMergedModules(path, sLastErrorString);
 }
 
 const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
-  if (!parsedOptions) {
-    unwrap(cg)->parseCodeGenDebugOptions();
-    lto_add_attrs(cg);
-    parsedOptions = true;
-  }
-  return unwrap(cg)->compile(length, DisableOpt, DisableInline,
+  maybeParseOptions();
+  return unwrap(cg)->compile(length, DisableInline,
                              DisableGVNLoadPRE, DisableLTOVectorization,
                              sLastErrorString);
 }
 
 bool lto_codegen_optimize(lto_code_gen_t cg) {
-  if (!parsedOptions) {
-    unwrap(cg)->parseCodeGenDebugOptions();
-    lto_add_attrs(cg);
-    parsedOptions = true;
-  }
-  return !unwrap(cg)->optimize(DisableOpt, DisableInline,
+  maybeParseOptions();
+  return !unwrap(cg)->optimize(DisableInline,
                                DisableGVNLoadPRE, DisableLTOVectorization,
                                sLastErrorString);
 }
 
 const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
-  if (!parsedOptions) {
-    unwrap(cg)->parseCodeGenDebugOptions();
-    lto_add_attrs(cg);
-    parsedOptions = true;
-  }
+  maybeParseOptions();
   return unwrap(cg)->compileOptimized(length, sLastErrorString);
 }
 
 bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
-  if (!parsedOptions) {
-    unwrap(cg)->parseCodeGenDebugOptions();
-    lto_add_attrs(cg);
-    parsedOptions = true;
-  }
+  maybeParseOptions();
   return !unwrap(cg)->compile_to_file(
-      name, DisableOpt, DisableInline, DisableGVNLoadPRE,
+      name, DisableInline, DisableGVNLoadPRE,
       DisableLTOVectorization, sLastErrorString);
 }