[PATCH] D93838: [SCCP] Add Function Specialization pass
Chuanqi Xu via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu May 13 19:19:34 PDT 2021
ChuanqiXu added a comment.
In D93838#2756933 <https://reviews.llvm.org/D93838#2756933>, @SjoerdMeijer wrote:
> One more data point.
>
> MCF is one end of the spectrum with a LTO compile/link step of ~1 second, and SQLite somewhere at the other end with a compile time of 160 seconds (i.e., the amalgamation version: 184K lines of code (one file), over 6.4 megabytes in size). It specialises 4 functions, and thus triggers 4 times. The overhead of function specialisation is just 1.3% - 1.8%, and is mainly just in running the pass itself, not any knock on effect of the rest of the pipeline chewing on more instructions. I think this shows that:
>
> - the cost of function specialisation is amortised with larger compile times,
> - but of course also the ratio of the number of existing and new functions/instructions is important.
>
> Similarly zooming in on the compile-times for SQLite:
>
> | Timing report (in seconds) | -O3 | -O3 + func spec |
> | ------------------------------------ | -------- | --------------- |
> | Pass execution 1 | 159.9010 | 164.3134 | |
> | Register Allocation | 2.7357 | 2.7376 | |
> | Instruction Selection and Scheduling | 9.0910 | 9.0746 | |
> | Pass execution 2 | 61.8962 | 61.6610 | |
> | DWARF Emission | 12.2326 | 12.2232 | |
> |
>
> And again the function specialisation pass does not enter the top 5 of the most compile time consuming passes:
>
> 2.8416 ( 1.8%) 0.3040 ( 5.6%) 3.1456 ( 1.9%) 3.1457 ( 1.9%) FunctionSpecializationPass
>
> The binary size is 1.575.571 bytes vs. 1.575.299 bytes, so slightly reduced which is interesting.
>
> So, as it stands, and sort of repeating what I said earlier today: this looks like an good candidate for an initial commit. I.e., this looks like a good basis that performs the transformation, but we know this needs further cost-model tuning. For example, the first thing I would like to add is a budget to not let the functions grow out of proportion. What do we think about that?
>From the cost model, I think it is hard to inflate the codes too much. The key component of the cost model is:
if (PossibleConstants.size() > MaxConstantsThreshold) {
LLVM_DEBUG(dbgs() << "FnSpecialization: number of constants found exceed "
<< "the maximum number of constants threshold.\n");
return false;
}
// ...
/// Compute the cost of specializing function \p F.
uint64_t getSpecializationCost(Function *F) {
// Compute the code metrics for the function.
SmallPtrSet<const Value *, 32> EphValues;
CodeMetrics::collectEphemeralValues(F, &(GetAC)(*F), EphValues);
CodeMetrics Metrics;
for (BasicBlock &BB : *F)
Metrics.analyzeBasicBlock(&BB, (GetTTI)(*F), EphValues);
// If the code metrics reveal that we shouldn't duplicate the function, we
// shouldn't specialize it. Set the specialization cost to the maximum.
if (Metrics.notDuplicatable)
return std::numeric_limits<unsigned>::max();
// Otherwise, set the specialization cost to be the cost of all the
// instructions in the function and penalty for specializing more functions.
unsigned Penalty = (NumFuncSpecialized + 1);
return Metrics.NumInsts * InlineConstants::InstrCost * Penalty;
}
>From the implementation of `getSpecializationCost`, we could know with number of specialized functions increases, the cost to specialize another function would be get larger. So there shouldn't be too many functions in a large program could be specialized actually.
( So here introduces another problem about the order of functions to specialized. And I think we could handle this in successive patches.)
Add a new budget could help the users to feel more controllable for this pass. I think we could limit the numbers of function specialized.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93838/new/
https://reviews.llvm.org/D93838
More information about the llvm-commits
mailing list