Merge pull request #12658 from rajbarik/master

Improve Osize
diff --git a/include/swift/AST/SILOptions.h b/include/swift/AST/SILOptions.h
index 4a77a33..bbd37b9 100644
--- a/include/swift/AST/SILOptions.h
+++ b/include/swift/AST/SILOptions.h
@@ -32,6 +32,12 @@
   /// Controls the aggressiveness of the performance inliner.
   int InlineThreshold = -1;
 
+  /// Controls the aggressiveness of the performance inliner for Osize.
+  int CallerBaseBenefitReductionFactor = 2;
+
+  /// Controls the aggressiveness of the loop unroller.
+  int UnrollThreshold = 250;
+
   /// The number of threads for multi-threaded code generation.
   int NumThreads = 0;
   
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index f3fbf3d..018ec22 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -369,6 +369,16 @@
   MetaVarName<"<50>">,
   HelpText<"Controls the aggressiveness of performance inlining">;
 
+def sil_inline_caller_benefit_reduction_factor : Separate<["-"], "sil-inline-caller-benefit-reduction-factor">,
+  MetaVarName<"<2>">,
+  HelpText<"Controls the aggressiveness of performance inlining in -Osize "
+          "mode by reducing the base benefits of a caller (lower value "
+          "permits more inlining!)">;
+
+def sil_unroll_threshold : Separate<["-"], "sil-unroll-threshold">,
+  MetaVarName<"<250>">,
+  HelpText<"Controls the aggressiveness of loop unrolling">;
+
 def sil_merge_partial_modules : Flag<["-"], "sil-merge-partial-modules">,
   HelpText<"Merge SIL from all partial swiftmodules into the final module">;
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 0e6419a..8d88e15 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1188,6 +1188,20 @@
       return true;
     }
   }
+  if (const Arg *A = Args.getLastArg(OPT_sil_inline_caller_benefit_reduction_factor)) {
+    if (StringRef(A->getValue()).getAsInteger(10, Opts.CallerBaseBenefitReductionFactor)) {
+      Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
+                     A->getAsString(Args), A->getValue());
+      return true;
+    }
+  }
+  if (const Arg *A = Args.getLastArg(OPT_sil_unroll_threshold)) {
+    if (StringRef(A->getValue()).getAsInteger(10, Opts.UnrollThreshold)) {
+      Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
+                     A->getAsString(Args), A->getValue());
+      return true;
+    }
+  }
   if (const Arg *A = Args.getLastArg(OPT_num_threads)) {
     if (StringRef(A->getValue()).getAsInteger(10, Opts.NumThreads)) {
       Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 59ce9d0..b931047 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -845,7 +845,7 @@
     Attrs.addAttribute("target-features", allFeatures);
   }
   if (IRGen.Opts.OptimizeForSize)
-    Attrs.addAttribute(llvm::Attribute::OptimizeForSize);
+    Attrs.addAttribute(llvm::Attribute::MinSize);
 }
 
 llvm::AttributeList IRGenModule::constructInitialAttributes() {
diff --git a/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp b/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp
index dd43738..e231f12 100644
--- a/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp
+++ b/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp
@@ -29,7 +29,6 @@
 using llvm::DenseMap;
 using llvm::MapVector;
 
-static const uint64_t SILLoopUnrollThreshold = 250;
 
 namespace {
 
@@ -187,6 +186,9 @@
   // It is used to estimate the cost of the callee
   // inside a loop.
   const uint64_t InsnsPerBB = 4;
+  // Use command-line threshold for unrolling.
+  const uint64_t SILLoopUnrollThreshold = Loop->getBlocks().empty() ? 0 : 
+    (Loop->getBlocks())[0]->getParent()->getModule().getOptions().UnrollThreshold;
   for (auto *BB : Loop->getBlocks()) {
     for (auto &Inst : *BB) {
       if (!Loop->canDuplicate(&Inst))
diff --git a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
index 7049745..8190a3e 100644
--- a/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
+++ b/lib/SILOptimizer/Transforms/PerformanceInliner.cpp
@@ -256,7 +256,9 @@
         return false;
     }
 
-    BaseBenefit = BaseBenefit / 2;
+    // Use command line option to control inlining in Osize mode.
+    const uint64_t CallerBaseBenefitReductionFactor = AI.getFunction()->getModule().getOptions().CallerBaseBenefitReductionFactor;
+    BaseBenefit = BaseBenefit / CallerBaseBenefitReductionFactor;
   }
 
   // It is always OK to inline a simple call.
diff --git a/test/IRGen/optimize_for_size.sil b/test/IRGen/optimize_for_size.sil
index c116b44..32cfa3f 100644
--- a/test/IRGen/optimize_for_size.sil
+++ b/test/IRGen/optimize_for_size.sil
@@ -13,4 +13,4 @@
 }
 
 // O-NOT: attributes #0 = {{{.*}}optsize
-// CHECK: attributes #0 = {{{.*}}optsize
+// CHECK: attributes #0 = {{{.*}}minsize