llvm.org GIT mirror llvm / 416d8ec
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232769 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 4 years ago
10 changed file(s) with 152 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
7575
7676 void setCpu(const char *mCpu) { MCpu = mCpu; }
7777 void setAttr(const char *mAttr) { MAttr = mAttr; }
78 void setOptLevel(unsigned optLevel) { OptLevel = optLevel; }
7879
7980 void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
8081
101102 // Do not try to remove the object file in LTOCodeGenerator's destructor
102103 // as we don't who (LTOCodeGenerator or the obj file) will last longer.
103104 bool compile_to_file(const char **name,
104 bool disableOpt,
105105 bool disableInline,
106106 bool disableGVNLoadPRE,
107107 bool disableVectorization,
113113 // caller. This function should delete intermediate object file once its content
114114 // is brought to memory. Return NULL if the compilation was not successful.
115115 const void *compile(size_t *length,
116 bool disableOpt,
117116 bool disableInline,
118117 bool disableGVNLoadPRE,
119118 bool disableVectorization,
120119 std::string &errMsg);
121120
122121 // Optimizes the merged module. Returns true on success.
123 bool optimize(bool disableOpt,
124 bool disableInline,
122 bool optimize(bool disableInline,
125123 bool disableGVNLoadPRE,
126124 bool disableVectorization,
127125 std::string &errMsg);
170168 std::string MAttr;
171169 std::string NativeObjectPath;
172170 TargetOptions Options;
171 unsigned OptLevel;
173172 lto_diagnostic_handler_t DiagHandler;
174173 void *DiagContext;
175174 LTOModule *OwnedModule;
139139 legacy::PassManagerBase &PM) const;
140140 void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
141141 void addLTOOptimizationPasses(legacy::PassManagerBase &PM);
142 void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
142143
143144 public:
144145 /// populateFunctionPassManager - This fills in the function pass manager,
7070
7171 LTOCodeGenerator::LTOCodeGenerator(std::unique_ptr Context)
7272 : OwnedContext(std::move(Context)), Context(*OwnedContext),
73 IRLinker(new Module("ld-temp.o", *OwnedContext)) {
73 IRLinker(new Module("ld-temp.o", *OwnedContext)), OptLevel(2) {
7474 initialize();
7575 }
7676
290290
291291
292292 bool LTOCodeGenerator::compile_to_file(const char **name,
293 bool disableOpt,
294293 bool disableInline,
295294 bool disableGVNLoadPRE,
296295 bool disableVectorization,
297296 std::string &errMsg) {
298 if (!optimize(disableOpt, disableInline, disableGVNLoadPRE,
297 if (!optimize(disableInline, disableGVNLoadPRE,
299298 disableVectorization, errMsg))
300299 return false;
301300
303302 }
304303
305304 const void* LTOCodeGenerator::compile(size_t *length,
306 bool disableOpt,
307305 bool disableInline,
308306 bool disableGVNLoadPRE,
309307 bool disableVectorization,
310308 std::string &errMsg) {
311 if (!optimize(disableOpt, disableInline, disableGVNLoadPRE,
309 if (!optimize(disableInline, disableGVNLoadPRE,
312310 disableVectorization, errMsg))
313311 return nullptr;
314312
362360 MCpu = "cyclone";
363361 }
364362
363 CodeGenOpt::Level CGOptLevel;
364 switch (OptLevel) {
365 case 0:
366 CGOptLevel = CodeGenOpt::None;
367 break;
368 case 1:
369 CGOptLevel = CodeGenOpt::Less;
370 break;
371 case 2:
372 CGOptLevel = CodeGenOpt::Default;
373 break;
374 case 3:
375 CGOptLevel = CodeGenOpt::Aggressive;
376 break;
377 }
378
365379 TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options,
366380 RelocModel, CodeModel::Default,
367 CodeGenOpt::Aggressive);
381 CGOptLevel);
368382 return true;
369383 }
370384
511525 }
512526
513527 /// Optimize merged modules using various IPO passes
514 bool LTOCodeGenerator::optimize(bool DisableOpt,
515 bool DisableInline,
528 bool LTOCodeGenerator::optimize(bool DisableInline,
516529 bool DisableGVNLoadPRE,
517530 bool DisableVectorization,
518531 std::string &errMsg) {
541554 if (!DisableInline)
542555 PMB.Inliner = createFunctionInliningPass();
543556 PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple);
544 if (DisableOpt)
545 PMB.OptLevel = 0;
557 PMB.OptLevel = OptLevel;
546558 PMB.VerifyInput = true;
547559 PMB.VerifyOutput = true;
548560
490490 addExtensionsToPM(EP_Peephole, PM);
491491
492492 PM.add(createJumpThreadingPass());
493
494 // Lower bitset metadata to bitsets.
495 PM.add(createLowerBitSetsPass());
496
493 }
494
495 void PassManagerBuilder::addLateLTOOptimizationPasses(
496 legacy::PassManagerBase &PM) {
497497 // Delete basic blocks, which optimization passes may have killed.
498498 PM.add(createCFGSimplificationPass());
499499
515515 PM.add(createDebugInfoVerifierPass());
516516 }
517517
518 if (OptLevel > 1)
519 addLTOOptimizationPasses(PM);
520
521 // Lower bit sets to globals. This pass supports Clang's control flow
522 // integrity mechanisms (-fsanitize=cfi*) and needs to run at link time if CFI
523 // is enabled. The pass does nothing if CFI is disabled.
524 PM.add(createLowerBitSetsPass());
525
518526 if (OptLevel != 0)
519 addLTOOptimizationPasses(PM);
527 addLateLTOOptimizationPasses(PM);
520528
521529 if (VerifyOutput) {
522530 PM.add(createVerifierPass());
2424 ret i32 0
2525 }
2626
27 ; RUN: llvm-lto -o %t -dso-symbol=zed1 -dso-symbol=zed2 %t1 -disable-opt
27 ; RUN: llvm-lto -o %t -dso-symbol=zed1 -dso-symbol=zed2 %t1 -O0
2828 ; RUN: llvm-nm %t | FileCheck %s -check-prefix=ZED1_AND_ZED2
2929 ; ZED1_AND_ZED2: V zed1
3030 @zed1 = linkonce_odr global i32 42
0 ; RUN: llvm-as < %s >%t1
11 ; RUN: llvm-lto -o %t2 -dso-symbol=foo1 -dso-symbol=foo2 -dso-symbol=foo3 \
2 ; RUN: -dso-symbol=foo4 -dso-symbol=v1 -dso-symbol=v2 %t1 -disable-opt
2 ; RUN: -dso-symbol=foo4 -dso-symbol=v1 -dso-symbol=v2 %t1 -O0
33 ; RUN: llvm-nm %t2 | FileCheck %s
44
55 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
0 ; RUN: llvm-as -o %t.bc %s
1 ; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so -plugin-opt=save-temps \
2 ; RUN: -plugin-opt=O0 -r -o %t.o %t.bc
3 ; RUN: llvm-dis < %t.o.opt.bc -o - | FileCheck --check-prefix=CHECK-O0 %s
4 ; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so -plugin-opt=save-temps \
5 ; RUN: -plugin-opt=O1 -r -o %t.o %t.bc
6 ; RUN: llvm-dis < %t.o.opt.bc -o - | FileCheck --check-prefix=CHECK-O1 %s
7 ; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so -plugin-opt=save-temps \
8 ; RUN: -plugin-opt=O2 -r -o %t.o %t.bc
9 ; RUN: llvm-dis < %t.o.opt.bc -o - | FileCheck --check-prefix=CHECK-O2 %s
10
11 ; CHECK-O0: define internal void @foo(
12 ; CHECK-O1: define internal void @foo(
13 ; CHECK-O2-NOT: define internal void @foo(
14 define internal void @foo() {
15 ret void
16 }
17
18 ; CHECK-O0: define internal i32 @bar(
19 ; CHECK-O1: define internal i32 @bar(
20 define internal i32 @bar(i1 %p) {
21 br i1 %p, label %t, label %f
22
23 t:
24 br label %end
25
26 f:
27 br label %end
28
29 end:
30 ; CHECK-O0: phi
31 ; CHECK-O1: select
32 %r = phi i32 [ 1, %t ], [ 2, %f ]
33 ret i32 %r
34 }
35
36 define void @baz() {
37 call void @foo()
38 %c = call i32 @bar(i1 true)
39 ret void
40 }
41
42 @a = constant i32 1
43
44 !0 = !{!"bitset1", i32* @a, i32 0}
45
46 ; CHECK-O0-NOT: llvm.bitsets
47 ; CHECK-O1-NOT: llvm.bitsets
48 ; CHECK-O2-NOT: llvm.bitsets
49 !llvm.bitsets = !{ !0 }
9090 };
9191 static bool generate_api_file = false;
9292 static OutputType TheOutputType = OT_NORMAL;
93 static unsigned OptLevel = 2;
9394 static std::string obj_path;
9495 static std::string extra_library_path;
9596 static std::string triple;
123124 TheOutputType = OT_SAVE_TEMPS;
124125 } else if (opt == "disable-output") {
125126 TheOutputType = OT_DISABLE;
127 } else if (opt.size() == 2 && opt[0] == 'O') {
128 if (opt[1] < '0' || opt[1] > '3')
129 report_fatal_error("Optimization level must be between 0 and 3");
130 OptLevel = opt[1] - '0';
126131 } else {
127132 // Save this option to pass to the code generator.
128133 // ParseCommandLineOptions() expects argv[0] to be program name. Lazily
723728 PMB.VerifyOutput = true;
724729 PMB.LoopVectorize = true;
725730 PMB.SLPVectorize = true;
731 PMB.OptLevel = options::OptLevel;
726732 PMB.populateLTOPassManager(passes);
727733 passes.run(M);
728734 }
753759 Features.AddFeature(A);
754760
755761 TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
762 CodeGenOpt::Level CGOptLevel;
763 switch (options::OptLevel) {
764 case 0:
765 CGOptLevel = CodeGenOpt::None;
766 break;
767 case 1:
768 CGOptLevel = CodeGenOpt::Less;
769 break;
770 case 2:
771 CGOptLevel = CodeGenOpt::Default;
772 break;
773 case 3:
774 CGOptLevel = CodeGenOpt::Aggressive;
775 break;
776 }
756777 std::unique_ptr TM(TheTarget->createTargetMachine(
757778 TripleStr, options::mcpu, Features.getString(), Options, RelocationModel,
758 CodeModel::Default, CodeGenOpt::Aggressive));
779 CodeModel::Default, CGOptLevel));
759780
760781 runLTOPasses(M, *TM);
761782
2525
2626 using namespace llvm;
2727
28 static cl::opt
29 DisableOpt("disable-opt", cl::init(false),
30 cl::desc("Do not run any optimization passes"));
28 static cl::opt
29 OptLevel("O",
30 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
31 "(default = '-O2')"),
32 cl::Prefix,
33 cl::ZeroOrMore,
34 cl::init('2'));
3135
3236 static cl::opt
3337 DisableInline("disable-inlining", cl::init(false),
145149 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
146150 cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n");
147151
152 if (OptLevel < '0' || OptLevel > '3') {
153 errs() << argv[0] << ": optimization level must be between 0 and 3\n";
154 return 1;
155 }
156
148157 // Initialize the configured targets.
149158 InitializeAllTargets();
150159 InitializeAllTargetMCs();
230239 // Set cpu and attrs strings for the default target/subtarget.
231240 CodeGen.setCpu(MCPU.c_str());
232241
242 CodeGen.setOptLevel(OptLevel - '0');
243
233244 std::string attrs;
234245 for (unsigned i = 0; i < MAttrs.size(); ++i) {
235246 if (i > 0)
244255 size_t len = 0;
245256 std::string ErrorInfo;
246257 const void *Code =
247 CodeGen.compile(&len, DisableOpt, DisableInline, DisableGVNLoadPRE,
258 CodeGen.compile(&len, DisableInline, DisableGVNLoadPRE,
248259 DisableLTOVectorization, ErrorInfo);
249260 if (!Code) {
250261 errs() << argv[0]
264275 } else {
265276 std::string ErrorInfo;
266277 const char *OutputName = nullptr;
267 if (!CodeGen.compile_to_file(&OutputName, DisableOpt, DisableInline,
278 if (!CodeGen.compile_to_file(&OutputName, DisableInline,
268279 DisableGVNLoadPRE, DisableLTOVectorization,
269280 ErrorInfo)) {
270281 errs() << argv[0]
2222 #include "llvm/Support/TargetSelect.h"
2323
2424 // extra command-line flags needed for LTOCodeGenerator
25 static cl::opt
26 DisableOpt("disable-opt", cl::init(false),
27 cl::desc("Do not run any optimization passes"));
25 static cl::opt
26 OptLevel("O",
27 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
28 "(default = '-O2')"),
29 cl::Prefix,
30 cl::ZeroOrMore,
31 cl::init('2'));
2832
2933 static cl::opt
3034 DisableInline("disable-inlining", cl::init(false),
8488
8589 CG->setAttr(attrs.c_str());
8690 }
91
92 if (OptLevel < '0' || OptLevel > '3')
93 report_fatal_error("Optimization level must be between 0 and 3");
94 CG->setOptLevel(OptLevel - '0');
8795 }
8896
8997 extern const char* lto_get_version() {
280288 unwrap(cg)->addMustPreserveSymbol(symbol);
281289 }
282290
283 bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
291 static void maybeParseOptions() {
284292 if (!parsedOptions) {
285293 unwrap(cg)->parseCodeGenDebugOptions();
286294 lto_add_attrs(cg);
287295 parsedOptions = true;
288296 }
297 }
298
299 bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
300 maybeParseOptions();
289301 return !unwrap(cg)->writeMergedModules(path, sLastErrorString);
290302 }
291303
292304 const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
293 if (!parsedOptions) {
294 unwrap(cg)->parseCodeGenDebugOptions();
295 lto_add_attrs(cg);
296 parsedOptions = true;
297 }
298 return unwrap(cg)->compile(length, DisableOpt, DisableInline,
305 maybeParseOptions();
306 return unwrap(cg)->compile(length, DisableInline,
299307 DisableGVNLoadPRE, DisableLTOVectorization,
300308 sLastErrorString);
301309 }
302310
303311 bool lto_codegen_optimize(lto_code_gen_t cg) {
304 if (!parsedOptions) {
305 unwrap(cg)->parseCodeGenDebugOptions();
306 lto_add_attrs(cg);
307 parsedOptions = true;
308 }
309 return !unwrap(cg)->optimize(DisableOpt, DisableInline,
312 maybeParseOptions();
313 return !unwrap(cg)->optimize(DisableInline,
310314 DisableGVNLoadPRE, DisableLTOVectorization,
311315 sLastErrorString);
312316 }
313317
314318 const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
315 if (!parsedOptions) {
316 unwrap(cg)->parseCodeGenDebugOptions();
317 lto_add_attrs(cg);
318 parsedOptions = true;
319 }
319 maybeParseOptions();
320320 return unwrap(cg)->compileOptimized(length, sLastErrorString);
321321 }
322322
323323 bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
324 if (!parsedOptions) {
325 unwrap(cg)->parseCodeGenDebugOptions();
326 lto_add_attrs(cg);
327 parsedOptions = true;
328 }
324 maybeParseOptions();
329325 return !unwrap(cg)->compile_to_file(
330 name, DisableOpt, DisableInline, DisableGVNLoadPRE,
326 name, DisableInline, DisableGVNLoadPRE,
331327 DisableLTOVectorization, sLastErrorString);
332328 }
333329