Change FSO heuristic.

FSO functions that have high potential but does not have caller inside
current module.

The thunk can then be inlined into the module calling the function and
the function would get the benefit of FSO.

The heuristic for selecting such function is
1. Have no indirect caller. This would introduce a thunk.
2. Have potential to give better performance. i.e. function argument can
be O2G.

Regression
TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
BenchLangCallingCFunction                               | 184     | 211     | +14.7%    | **0.87x**
Calculator                                              | 55      | 59      | +7.3%     | **0.93x**
DeadArray                                               | 687     | 741     | +7.9%     | **0.93x**
MonteCarloPi                                            | 39275   | 41669   | +6.1%     | **0.94x**

Improvement
TEST                                                    | OLD_MIN | NEW_MIN | DELTA (%) | SPEEDUP
---                                                     | ---     | ---     | ---       | ---
LuhnAlgoLazy                                            | 2478    | 2327    | -6.1%     | **1.06x**
OpenClose                                               | 54      | 51      | -5.6%     | **1.06x**
SortLettersInPlace                                      | 1016    | 946     | -6.9%     | **1.07x**
ObjectiveCBridgeFromNSDictionaryAnyObjectToStringForced | 149993  | 139755  | -6.8%     | **1.07x**
Phonebook                                               | 9666    | 8992    | -7.0%     | **1.07x**
ObjectiveCBridgeFromNSDictionaryAnyObjectToString       | 222713  | 206538  | -7.3%     | **1.08x**
LuhnAlgoEager                                           | 2393    | 2226    | -7.0%     | **1.08x**
Dictionary                                              | 1307    | 1196    | -8.5%     | **1.09x**
JSONHelperDeserialize                                   | 3808    | 3492    | -8.3%     | **1.09x**
StdlibSort                                              | 7310    | 4084    | -44.1%    | **1.79x**

I see 0.15% increase in code size for Benchmark_O.

Thanks @gottesmm for suggesting this opportunity.

rdar://25345056
This commit is contained in:
Xin Tong
2016-03-29 19:43:22 -07:00
parent 99ea2fd79e
commit f95d9b3c92
11 changed files with 149 additions and 128 deletions

View File

@@ -486,10 +486,6 @@ static SILFunction*
createOptimizedFunction(RCIdentityFunctionInfo *RCIA,
FunctionSignatureInfo *FSI,
AliasAnalysis *AA, SILFunction *F) {
// Analyze function arguments. If there is no work to be done, exit early.
if (!FSI->analyze())
return nullptr;
// This is the new function name.
auto NewFName = FSI->getOptimizedName();
@@ -551,10 +547,21 @@ public:
if (!F->shouldOptimize())
return;
// If this function does not have a caller in the current module. We do not
// function signature specialize it.
if (!CA->hasCaller(F))
return;
// If there is no opportunity on the signature, simply return.
if (!FSI.shouldOptimize())
return;
// If this function does not have a caller in the current module.
if (!CA->hasCaller(F)) {
// If this function maybe called indirectly, e.g. from virtual table
// do not function signature specialize it, as this will introduce a thunk.
if (canBeCalledIndirectly(F->getRepresentation()))
return;
// if its not highly profitable to optimize this function. We do not
// function signature specialize it.
if (!FSI.profitableOptimize())
return;
}
// Check the signature of F to make sure that it is a function that we
// can specialize. These are conditions independent of the call graph.