[PATCH] D81223: Size LTO (1/3): Standardizing the use of OptimizationLevel

2020-06-04 Thread Rodrigo Caetano Rocha via Phabricator via cfe-commits
rcorcs created this revision.
rcorcs added a reviewer: hiraditya.
rcorcs added projects: LLVM, lld.
Herald added subscribers: cfe-commits, msifontes, jurahul, Kayjukh, frgossen, 
grosul1, Joonsoo, stephenneuendorffer, liufengdb, lucyrfox, mgester, 
arpith-jacob, nicolasvasilache, antiagainst, shauheen, jpienaar, rriddle, 
mehdi_amini, dexonsmith, steven_wu, MaskRay, aheejin, arichardson, inglorion, 
sbc100, mgorny, emaste.
Herald added a reviewer: espindola.
Herald added a reviewer: MaskRay.
Herald added projects: clang, MLIR.

This patch is the first in the sequence of three patches for supporting size 
optimization with LTO. The planned patches are:
1: Standardizing the use of OptimizationLevel across pass builders, which 
includes both SpeedupLevel and SizeLevel.
2: Enable the support for -Os and -Oz for LTO in lld.
3: Tune the LTO pipeline for size optimization.

Since we already have a class that describes both speed and size levels of 
optimization, I believe it is a good idea to use across the code base when 
defining optimization levels.
In the next patch, instead of adding a SizeLevel variable for the LTO 
configuration, I'll be able to simply use this OptimizationLevel variable.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D81223

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  lld/COFF/LTO.cpp
  lld/ELF/LTO.cpp
  lld/wasm/LTO.cpp
  llvm/examples/Bye/Bye.cpp
  llvm/include/llvm/IR/PassManager.h
  llvm/include/llvm/LTO/Config.h
  llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
  llvm/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
  llvm/include/llvm/Passes/PassBuilder.h
  llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
  llvm/lib/IR/PassManager.cpp
  llvm/lib/LTO/LTO.cpp
  llvm/lib/LTO/LTOBackend.cpp
  llvm/lib/LTO/LTOCodeGenerator.cpp
  llvm/lib/LTO/ThinLTOCodeGenerator.cpp
  llvm/lib/Passes/PassBuilder.cpp
  llvm/lib/Transforms/IPO/PassManagerBuilder.cpp
  llvm/tools/bugpoint/bugpoint.cpp
  llvm/tools/llvm-lto/llvm-lto.cpp
  llvm/tools/llvm-lto2/llvm-lto2.cpp
  llvm/tools/lto/lto.cpp
  llvm/tools/opt/CMakeLists.txt
  llvm/tools/opt/NewPMDriver.cpp
  llvm/tools/opt/opt.cpp
  mlir/lib/ExecutionEngine/OptUtils.cpp

Index: mlir/lib/ExecutionEngine/OptUtils.cpp
===
--- mlir/lib/ExecutionEngine/OptUtils.cpp
+++ mlir/lib/ExecutionEngine/OptUtils.cpp
@@ -65,8 +65,7 @@
  unsigned optLevel, unsigned sizeLevel,
  llvm::TargetMachine *targetMachine) {
   llvm::PassManagerBuilder builder;
-  builder.OptLevel = optLevel;
-  builder.SizeLevel = sizeLevel;
+  builder.OptLevel = {optLevel, sizeLevel};
   builder.Inliner = llvm::createFunctionInliningPass(
   optLevel, sizeLevel, /*DisableInlineHotCallSite=*/false);
   builder.LoopVectorize = optLevel > 1 && sizeLevel < 2;
Index: llvm/tools/opt/opt.cpp
===
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -393,8 +393,7 @@
 FPM.add(createVerifierPass()); // Verify that input is correct
 
   PassManagerBuilder Builder;
-  Builder.OptLevel = OptLevel;
-  Builder.SizeLevel = SizeLevel;
+  Builder.OptLevel = {OptLevel, SizeLevel};
 
   if (DisableInline) {
 // No inlining pass
@@ -450,7 +449,7 @@
   PassManagerBuilder Builder;
   Builder.VerifyInput = true;
   if (DisableOptimizations)
-Builder.OptLevel = 0;
+Builder.OptLevel = OptimizationLevel::O0;
 
   if (!DisableInline)
 Builder.Inliner = createFunctionInliningPass();
Index: llvm/tools/opt/NewPMDriver.cpp
===
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -143,7 +143,7 @@
   if (tryParsePipelineText(PB, PeepholeEPPipeline))
 PB.registerPeepholeEPCallback(
 [&PB, VerifyEachPass, DebugLogging](
-FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
+FunctionPassManager &PM, OptimizationLevel Level) {
   ExitOnError Err("Unable to parse PeepholeEP pipeline: ");
   Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass,
DebugLogging));
@@ -152,7 +152,7 @@
 LateLoopOptimizationsEPPipeline))
 PB.registerLateLoopOptimizationsEPCallback(
 [&PB, VerifyEachPass, DebugLogging](
-LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
+LoopPassManager &PM, OptimizationLevel Level) {
   ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: ");
   Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline,
VerifyEachPass, DebugLogging));
@@ -160,7 +160,7 @@
   if (tryParsePipelineText(PB, LoopOptimizerEndEPPipeline))
 PB.registerLoopOptimizerEndEPCallback(
 [&PB, VerifyEachPass, DebugLogging](
-LoopPassManager &PM, Pa

[PATCH] D81223: Size LTO (1/3): Standardizing the use of OptimizationLevel

2020-06-05 Thread Rodrigo Caetano Rocha via Phabricator via cfe-commits
rcorcs added a comment.

LLVM already has the class PassBuilder::OptimizationLevel that encapsulates the 
logic of both speed and size optimization levels. This class already checks 
which values for SpeedLevel and SizeLevel are valid.

However, other parts of the code define two separate variables to describe 
speed and size optimization levels with their semantic specified either in 
comments or code. Note that when SizeLevel!=0, OptLevel (or SpeedLevel) is 
usually expected to be 2, that is, their values are interdependent.

From my understanding, ideally, LLVM would use the same OptimizationLevel 
encapsulation everywhere. If the same encapsulation is used everywhere we can 
avoid conversions and guarantee
that they always have the same semantics.

For example, the class PassManagerBuilder defines these two separate variables 
with their semantics in comments:

  /// The Optimization Level - Specify the basic optimization level.
  ///0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 
  unsigned OptLevel;
  
  /// SizeLevel - How much we're optimizing for size.
  ///0 = none, 1 = -Os, 2 = -Oz
  unsigned SizeLevel;

On the other hand, the class ThinLTOCodeGenerator defines the semantics of 
OptLevel in code:

  /// IR optimization level: from 0 to 3.
  void setOptLevel(unsigned NewOptLevel) {
OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
  }

This patch standardizes the use of OptimizationLevel across PassBuilder, 
PassManagerBuilder, LTO configuration, and LTO code generators. Even with this 
patch, further work is still needed to standardize the use of OptimizationLevel 
across LLVM.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81223/new/

https://reviews.llvm.org/D81223



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81223: Size LTO (1/3): Standardizing the use of OptimizationLevel

2020-06-05 Thread Rodrigo Caetano Rocha via Phabricator via cfe-commits
rcorcs added a comment.

If reviewers think that this patch is touching in too many files, I could try 
to focus it only on the LTO related files, converting OptimizationLevel back to 
two separate values when necessary.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81223/new/

https://reviews.llvm.org/D81223



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81223: Size LTO (1/3): Standardizing the use of OptimizationLevel

2020-06-11 Thread Rodrigo Caetano Rocha via Phabricator via cfe-commits
rcorcs added a comment.

The way I see it, with size level for LTO, we could have a different LTO 
optimization pipeline for size or runtime performance. For example, we could 
have a different tuning for inlining,  vectorization, etc. We could also use 
the size level to automatically enable optimizations such as HotColdSplitting, 
MergeFunctions, etc., instead of relying on specific enabling flags. We could 
also have other size-specific optimizations in the future, such as 
MergeSimilarFunctions (https://reviews.llvm.org/D52896).

I believe that function attributes for size are useful for optimizing cold 
functions that have been outlined by HotColdSplitting, for example. However, an 
ideal size level LTO would involve a different optimization pipeline and also a 
different tuning of those optimizations.

For example, when optimizing for size, we could disable loop vectorization and 
have SLP optimizing based on the code-size cost model. We could also have 
MergeFunctions enabled with Os and both MergeFunctions and 
MergeSimilarFunctions enabled with Oz. A similar logic could be applied to 
other optimizations, such as Inlining, HotColdSplitting, etc.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81223/new/

https://reviews.llvm.org/D81223



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits