72 Commits

Author SHA1 Message Date
Mats Petersson
2fb51fba8c
[FuncSpec] Update function specialization to handle phi-chains (#72903)
When using the LLVM flang compiler with alias analysis (AA) enabled,
SPEC2017:548.exchange2_r was running significantly slower than wihtout
the AA.

This was caused by the GVN pass replacing many of the loads in the
pre-AA code with phi-nodes that form a long chain of dependencies, which
the function specialization was unable to follow.

This adds a function to discover phi-nodes in a transitive set, with
some limitations to avoid spending ages analysing phi-nodes.

The minimum latency savings also had to be lowered - fewer load
instructions means less saving.

Adding some more prints to help debugging the isProfitable decision.

No significant change in compile time or generated code-size.

(A previous attempt to fix this was abandoned: https://github.com/llvm/llvm-project/pull/71442)

---------

Co-authored-by: Alexandros Lamprineas <alexandros.lamprineas@arm.com>
2023-11-22 10:41:01 +00:00
Alexandros Lamprineas
e15d72adac
[FuncSpec] Adjust the names of specializations and promoted stack values
Currently the naming scheme is a bit funky; the specializations are named
after the original function followed by an arbitrary decimal number. This
makes it hard to debug inlined specializations of recursive functions.
With this patch I am adding ".specialized." in between of the original
name and the suffix, which is now a single increment counter.
2023-09-19 14:40:31 +01:00
Alexandros Lamprineas
386aa2ab9d [FuncSpec] Increase the maximum number of times the specializer can run.
* Changes the default value of FuncSpecMaxIters from 1 to 10.
  This allows specialization of recursive functions.
* Adds an option to control the maximum codesize growth per function.
* Measured ~45% performance uplift for SPEC2017:548.exchange2_r on
  AWS Graviton3.

Differential Revision: https://reviews.llvm.org/D145819
2023-08-22 09:36:12 +01:00
Rahul Anand Radhakrishnan
18423c7e1f [SCCP] Do not attempt to create constexpr for a scalable vector GEP
Scalable vector GEPs are not constants and trying to create one for
these GEPs causes an assertion failure.

Reviewed By: nikic, paulwalker-arm

Differential Revision: https://reviews.llvm.org/D157590
2023-08-11 11:06:07 +00:00
Vincent Lee
2fc0d17e8b [FuncSpec] Avoid crashing when SwitchInst doesn't see ConstantInt
D150464 updated the cost model for function specialization. Unfortunately, this
also crashes when trying to build stage2 LLD with thinLTO and assertions. It looks
like the issue is caused by a mishandling of the Constant in a SwitchInst since the
Constant cannot always be assumed to safely casted to a ConstantInt. In the case
of the crash, Constant was a ConstantExpr which triggered the assertion.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D154159
2023-06-30 21:02:50 -07:00
Alexandros Lamprineas
ce9d3f09b4 [FuncSpec] Promote stack values before specialization.
After each iteration of the function specializer, constant stack values
are promoted to constant globals in order to enable recursive function
specialization. This should also be done once before running the
specializer. Enables specialization of _QMbrute_forcePdigits_2 from
SPEC2017:548.exchange2_r.

Differential Revision: https://reviews.llvm.org/D152799
2023-06-19 14:32:41 +01:00
Alexandros Lamprineas
475ddca56e Reland "[FuncSpec] Replace LoopInfo with BlockFrequencyInfo"
Using AvgLoopIters on any loop is too imprecise making the cost model
favor users inside loop nests regardless of the actual tripcount.

Differential Revision: https://reviews.llvm.org/D150375
2023-06-08 17:44:47 +01:00
Nikita Popov
96a14f388b Revert "[FuncSpec] Replace LoopInfo with BlockFrequencyInfo"
As reported on https://reviews.llvm.org/D150375#4367861 and
following, this change causes PDT invalidation issues. Revert
it and dependent commits.

This reverts commit 0524534d5220da5ecb2cd424a46520184d2be366.
This reverts commit ced90d1ff64a89a13479a37a3b17a411a3259f9f.
This reverts commit 9f992cc9350a7f7072a6dbf018ea07142ea7a7ed.
This reverts commit 1b1232047e83b69561fd64b9547cb0a0d374473a.
2023-05-30 14:49:03 +02:00
Alexandros Lamprineas
0524534d52 [FuncSpec] Enable specialization of literal constants.
To do so we have to tweak the cost model such that specialization
does not trigger excessively.

Differential Revision: https://reviews.llvm.org/D150649
2023-05-25 09:55:46 +01:00
Alexandros Lamprineas
1b1232047e [FuncSpec] Replace LoopInfo with BlockFrequencyInfo.
Using AvgLoopIters on any loop is too imprecise making the cost model
favor users inside loop nests regardless of the actual tripcount.

Differential Revision: https://reviews.llvm.org/D150375
2023-05-22 17:49:52 +01:00
Momchil Velikov
de24d08459 [FuncSpec] Fix inconsistent treatment of global variables
There are a few inaccuracies with how FuncSpec handles global
variables.

When specialisation on non-const global variables is disabled (the
default) the pass could nevertheless perform some specializations,
e.g. on a constant GEP expression, or on a SSA variable, for which the
Solver has determined it has the value of a global variable.

When specialisation on non-const global variables is enabled, the pass
would skip non-scalars, e.g. a global array, but this should be
completely inconsequential, a pointer is a pointer.

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D149476

Change-Id: Ic73051b2f8602587306760bf2ec552e5860f8d39
2023-05-05 09:56:06 +01:00
Alexandros Lamprineas
54e5fb789c [FuncSpec] Track the return values of specializations.
To track the return values of specializations, we need to invalidate all
the lattice values across the use-def chain which originates from the
callsites, recompute and propagate.

Differential Revision: https://reviews.llvm.org/D146158
2023-04-24 13:18:49 +01:00
Momchil Velikov
cc7bb7080f [FuncSpec] Relax restrictions on candidates for specialisation
Allow a function to be specialised even if it has its address taken or
it's global. For such functions, consider all of the arguments as
overdefined. Don't delete the functions even if all the apparent calls
were redirected to specialised instances.

Reviewed By: labrinea, ChuanqiXu

Differential Revision: https://reviews.llvm.org/D148345
2023-04-20 12:06:22 +01:00
Alexandros Lamprineas
7ea597ead9 [FuncSpec] Consider constant struct arguments when specializing.
Optionally enabled just like integer and floating point arguments.

Differential Revision: https://reviews.llvm.org/D145374
2023-04-17 18:39:21 +01:00
Alexandros Lamprineas
9627bcdeac [FuncSpec][NFC] Command line option renaming.
Standardize all options with 'funcspec' prefix and shorter abreviations.

Differential Revision: https://reviews.llvm.org/D145378
2023-03-15 18:03:44 +00:00
Alexandros Lamprineas
67fde2b932 [FuncSpec] Minor refactoring in statistics and debug messages.
* Remove redundant variable `NbFunctionsSpecialized` as it is no longer
  used by the cost model.
* Rename statistic `NumFuncSpecialized` to `NumSpecsCreated` as a better
  description (the old name confusingly implied number of functions we have
  created clones for).
* Same for variable `SpecializedFuncs`. Renamed to `Specializations`.
* Move debug message in the destructor (avoids repetition when MaxIters > 1).

Differential Revision: https://reviews.llvm.org/D145375
2023-03-15 09:10:06 +00:00
Tiwari Abhinav Ashok Kumar
bfb1559fbe [NFC] Fix missing colon in CHECK directives
Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D144412
2023-02-21 00:13:04 +05:30
Jonathon Penix
dfb98d8e2a [FuncSpec] Prevent assertion failure when no store value is found
If the only user of the Alloca argument provided to getPromotableAlloca()
is the same as the Call argument, StoreValue is never set and results
in an assertion failure that isa<> was used on a nullptr when passed into
getCandidateConstant().

This was originally seen when trying to build SPEC 2006 416.gamess using
flang with lto enabled.

Differential Revision: https://reviews.llvm.org/D143457
2023-02-07 13:57:27 -08:00
Alexandros Lamprineas
33ecc8a9b8 [IPSCCP][FuncSpec] Fix compiler crash 60191.
Found here https://github.com/llvm/llvm-project/issues/60191

The compiler would crash when specializing a function based on a function
pointer whose call sites may expect less parameters than those of the
function we are replacing the pointer with.

Differential Revision: https://reviews.llvm.org/D142444
2023-01-24 18:36:12 +00:00
Alexandros Lamprineas
572a757fa7 [IPSCCP] Enable specialization of functions.
Re-enable the optimization after having fixed the compilation error
found in SPEC/CINT2017rate/502.gcc_r when both LTO and PGO are in use
(see https://reviews.llvm.org/D141474).

Differential Revision: https://reviews.llvm.org/D140210
2023-01-13 14:04:17 +00:00
Florian Hahn
60359f56aa
Revert "[IPSCCP] Enable specialization of functions."
This reverts commit 2656572d485127cc30b8fe9752024d2a0f1c50db.

It looks like CINT2017rate/502.gcc_r gets mis-compiled with LTO + PGO on
AArch64 with function specialization.
2022-12-26 16:02:59 +00:00
Alexandros Lamprineas
2656572d48 [IPSCCP] Enable specialization of functions.
This patch enables Function Specialization by default at all
optimization levels except Os, Oz.

Compilation Time Overhead:
--------------------------
Measured the Instruction Count increase (Geomean) for CTMark from
the llvm-testsuite as in https://llvm-compile-time-tracker.com.
 * {-O3, Non-LTO}: +0.136% Instruction Count
 * {-O3, LTO}: +0.346% Instruction Count

Performance Uplift:
-------------------
Measured +9.121% score increase for 505.mcf_r from SPEC Int 2017
(Tested on Neoverse N1 with -O3 + LTO)

Correctness Testing:
--------------------
 * Passes bootstrap Clang with ASAN + LTO + FuncSpec aggressive options:
   { MaxClonesThreshold=10,
     SmallFunctionThreshold=10,
     AvgLoopIterationCount=30,
     SpecializeOnAddresses=true,
     EnableSpecializationForLiteralConstant=true,
     FuncSpecializationMaxIters=10 }
 * Builds Chromium and passes its unittests with the above options + ThinLTO.

For more info please refer to
https://discourse.llvm.org/t/rfc-should-we-enable-function-specialization/61518

Differential Revision: https://reviews.llvm.org/D140210
2022-12-25 10:05:21 +02:00
Alexandros Lamprineas
f952bc05fd [IPSCCP] Create a Pass parameter to control specialization of functions.
Required for D140210 in order to disable FuncSpec at {Os, Oz}
optimization levels.

Differential Revision: https://reviews.llvm.org/D140564
2022-12-23 16:54:45 +00:00
Momchil Velikov
e6b9fc4c8b [FuncSpec] Global ranking of specialisations
The `FunctionSpecialization` pass chooses specializations among the
opportunities presented by a single function and its calls,
progressively penalizing subsequent specialization attempts by
artificially increasing the cost of a specialization, depending on how
many specialization were applied before. Thus the chosen
specializations are sensitive to the order the functions appear in the
module and may be worse than others, had those others been considered
earlier.

This patch makes the `FunctionSpecialization` pass rank the
specializations globally, i.e.  choose the "best" specializations
among the all possible specializations in the module, for all
functions.

Since this involved quite a bit of redesign of the pass data
structures, this patch also carries:

  * removal of duplicate specializations

  * optimization of call sites update, by collecting per
    specialization the list of call sites that can be directly
    rewritten, without prior expensive check if the call constants and
    their positions match those of the specialized function.

A bit of a write-up up about the FuncSpec data structures and
operation:

Each potential function specialisation is kept in a single vector
(`AllSpecs` in `FunctionSpecializer::run`).  This vector is populated
by `FunctionSpecializer::findSpecializations`.

The `findSpecializations` member function has a local `DenseMap` to
eliminate duplicates - with each call to the current function,
`findSpecializations` builds a specialisation signature (`SpecSig`)
and looks it in the duplicates map. If the signature is present, the
function records the call to rewrite into the existing specialisation
instance.  If the signature is absent, it means we have a new
specialisation instance - the function calculates the gain and creates
a new entry in `AllSpecs`. Negative gain specialisation are ignored at
this point, unless forced.

The potential specialisations for a function form a contiguous range
in the `AllSpecs` [1]. This range is recorded in `SpecMap SM`, so we
can quickly find all specialisations for a function.

Once we have all the potential specialisations with their gains we
need to choose the best ones, which fit in the module specialisation
budget. This is done by using a max-heap (`std::make_heap`,
`std::push_heap`, etc) to find the best `NSpec` specialisations with a
single traversal of the `AllSpecs` vector. The heap itself is
contained with a small vector (`BestSpecs`) of indices into
`AllSpecs`, since elements of `AllSpecs` are a bit too heavy to
shuffle around.

Next the chosen specialisation are performed, that is, functions
cloned, `SCCPSolver` primed, and known call sites updated.

Then we run the `SCCPSolver` to propagate constants in the cloned
functions, after which we walk the calls of the original functions to
update them to call the specialised functions.

---

[1] This range may contain specialisation that were discarded and is
not ordered in any way. One alternative design is to keep a vector
indices of all specialisations for this function (which would
initially be, `i`, `i+1`, `i+2`, etc) and later sort them by gain,
pushing non-applied ones to the back. This has the potential to speed
`updateCallSites` up.

Reviewed By: ChuanqiXu, labrinea

Differential Revision: https://reviews.llvm.org/D139346

Change-Id: I708851eb38f07c42066637085b833ca91b195998
2022-12-14 15:30:32 +00:00
Alexandros Lamprineas
8136a0172b [FuncSpec] Make the Function Specializer part of the IPSCCP pass.
Reland 877a9f9abec61f06e39f1cd872e37b828139c2d1 since D138654 (parent)
has been fixed with 9ebaf4fef4aac89d4eff08e48185d61bc893f14e and with
8f1e11c5a7d70f96943a72649daa69f152d73e90.

Differential Revision: https://reviews.llvm.org/D126455
2022-12-10 14:39:49 +00:00
Alexandros Lamprineas
0f0cb92cb2 Revert "[FuncSpec] Make the Function Specializer part of the IPSCCP pass."
This reverts commit 877a9f9abec61f06e39f1cd872e37b828139c2d1.

It depends on the parent revision 42c2dc401742266da3e0251b6c1ca491f4779963
which needs to be reverted as it broke some buildbots, so reverting both.
2022-12-08 12:41:43 +00:00
Alexandros Lamprineas
877a9f9abe [FuncSpec] Make the Function Specializer part of the IPSCCP pass.
The aim of this patch is to minimize the compilation time overhead of
running Function Specialization. It is about 40% slower to run as a
standalone pass (IPSCCP + FuncSpec vs IPSCCP with FuncSpec) according
to my measurements. I compiled the llvm testsuite with NewPM-O3 + LTO
and measured single threaded [user + system] time of IPSCCP and FuncSpec
by passing the '-time-passes' option to lld. Then I compared the two
configurations in terms of Instruction Count of the total compilation
(not of the individual passes) as in https://llvm-compile-time-tracker.com.
Geomean for non-LTO builds is -0.25% and LTO is -0.5% approximately.

You can find more info below:

https://discourse.llvm.org/t/rfc-should-we-enable-function-specialization/61518

Differential Revision: https://reviews.llvm.org/D126455
2022-12-08 12:14:27 +00:00
Roman Lebedev
a1314b2f62
[NFC] Port all FunctionSpecialization tests to -passes= syntax 2022-12-08 02:38:43 +03:00
Momchil Velikov
e7ed43c753 [FuncSpec] Invalidate analyses when deleting a fully specialised function
Deleting a fully specialised function left dangling pointers in
`FunctionAnalysisManager`, which causes an internal compiler error
when the function's storage was reused.

Fixes bug #58759.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D138909

Change-Id: Ifed378c748af35e8fe7dcbdddb0f41b8777cbe87
2022-11-30 18:56:23 +00:00
Matt Arsenault
ebdf5aefcb FunctionSpecialization: Convert tests to opaque pointers 2022-11-28 09:35:48 -05:00
Alexandros Lamprineas
dbeaf6baa2 [FuncSpec] Do not overestimate the specialization bonus for users inside loops.
When calculating the specialization bonus for a given function argument,
we recursively traverse the chain of (certain) users, accumulating the
instruction costs. Then we exponentially increase the bonus to account
for loop nests. This is problematic for two reasons: (a) the users might
not themselves be inside the loop nest, (b) if they are we are accounting
for it multiple times. Instead we should be adjusting the bonus before
traversing the user chain.

This reduces the instruction count for CTMark (newPM-O3) when Function
Specialization is enabled without actually reducing the amount of
specializations performed (geomean: -0.001% non-LTO, -0.406% LTO).

Differential Revision: https://reviews.llvm.org/D136692
2022-10-27 15:26:11 +01:00
Momchil Velikov
38f44ccfba Recommit: [FuncSpec] Fix specialisation based on literals
[fixed test to work with reverse iteration]

The `FunctionSpecialization` pass has support for specialising
functions, which are called with literal arguments. This functionality
is disabled by default and is enabled with the option
`-function-specialization-for-literal-constant` .  There are a few
issues with the implementation, though:

* even with the default, the pass will still specialise based on
   floating-point literals

* even when it's enabled, the pass will specialise only for the `i1`
    type (or `i2` if all of the possible 4 values occur, or `i3` if all
    of the possible 8 values occur, etc)

The reason for this is incorrect check of the lattice value of the
function formal parameter. The lattice value is `overdefined` when the
constant range of the possible arguments is the full set, and this is
the reason for the specialisation to trigger. However, if the set of
the possible arguments is not the full set, that must not prevent the
specialisation.

This patch changes the pass to NOT consider a formal parameter when
specialising a function if the lattice value for that parameter is:

* unknown or undef
* a constant
* a constant range with a single element

on the basis that specialisation is pointless for those cases.

Is also changes the criteria for picking up an actual argument to
specialise if the argument is:

* a LLVM IR constant
* has `constant` lattice value
 has `constantrange` lattice value with a single element.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D135893

Change-Id: Iea273423176082ec51339aa66a5fe9fea83557ee
2022-10-27 12:48:20 +01:00
Momchil Velikov
5ea8951b88 [FuncSpec] Add a testcase for the treatment of constant and unused arguments
Increase test coverage - check that functions are not specialised on
constant or unused arguments.

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D136184
2022-10-26 17:25:18 +01:00
Momchil Velikov
9901583968 Revert "[FuncSpec] Fix specialisation based on literals"
This reverts commit a8b0f580170089fcd555ade5565ceff0ec60f609 because
of "reverse-iteration" buildbot failure.
2022-10-26 13:54:12 +01:00
Momchil Velikov
606d25e545 [FuncSpec] Compute specialisation gain even when forcing specialisation
When rewriting the call sites to call the new specialised functions, a
single call site can be matched by two different specialisations - a
"less specialised" version of the function and a "more specialised"
version of the function, e.g.  for a function

    void f(int x, int y)

the call like `f(1, 2)` could be matched by either

    void f.1(int x /* int y == 2 */);

or

    void f.2(/* int x == 1, int y == 2 */);

The `FunctionSpecialisation` pass tries to match specialisation in the
order of decreasing gain, so "more specialised" functions are
preferred to "less specialised" functions. This breaks, however, when
using the flag `-force-function-specialization`, in which case the
cost/benefit analysis is not performed and all the specialisations are
equally preferable.

This patch makes the pass calculate specialisation gain and order the
specialisations accordingly even when `-force-function-specialization`
is used, under the assumption that this flag has purely debugging
purpose and it is reasonable to ignore the extra computing effort it
incurs.

Reviewed By: ChuanqiXu, labrinea

Differential Revision: https://reviews.llvm.org/D136180
2022-10-26 10:08:03 +01:00
Momchil Velikov
a8b0f58017 [FuncSpec] Fix specialisation based on literals
The `FunctionSpecialization` pass has support for specialising
functions, which are called with literal arguments. This functionality
is disabled by default and is enabled with the option
`-function-specialization-for-literal-constant` .  There are a few
issues with the implementation, though:

* even with the default, the pass will still specialise based on
   floating-point literals

* even when it's enabled, the pass will specialise only for the `i1`
    type (or `i2` if all of the possible 4 values occur, or `i3` if all
    of the possible 8 values occur, etc)

The reason for this is incorrect check of the lattice value of the
function formal parameter. The lattice value is `overdefined` when the
constant range of the possible arguments is the full set, and this is
the reason for the specialisation to trigger. However, if the set of
the possible arguments is not the full set, that must not prevent the
specialisation.

This patch changes the pass to NOT consider a formal parameter when
specialising a function if the lattice value for that parameter is:

* unknown or undef
* a constant
* a constant range with a single element

on the basis that specialisation is pointless for those cases.

Is also changes the criteria for picking up an actual argument to
specialise if the argument is:

* a LLVM IR constant
* has `constant` lattice value
 has `constantrange` lattice value with a single element.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D135893
2022-10-26 09:55:33 +01:00
Momchil Velikov
1a525dec7f [FuncSpec] Fix missed opportunities for function specialisation
When collecting the possible constant arguments to
specialise a function the compiler will abandon the search
on the first argument that is for some reason unsuitable as
a specialisation constant. Thus, depending on the traversal
order of the functions and call sites, the compiler can end
up with a different set of possible constants, hence with
different set of specialisations.

With this patch, the compiler will skip unsuitable
constants, but nevertheless will continue searching for
more.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D135867
2022-10-25 23:19:48 +01:00
Momchil Velikov
c47739b45c [FuncSpec] Consider small noinline functions for specialisation
Small functions with size under a given threshold are not
considered for specialisaion on the presumption that they
are easy to inline. This does not apply to `noinline`
functions, though.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D135862
2022-10-25 19:49:04 +01:00
Alexandros Lamprineas
25162418c6 [NFC][FuncSpec] Add a test to show redundant function cloning.
Happens when we find identical specializations.

Differential Revision: https://reviews.llvm.org/D135459
2022-10-13 23:00:23 +01:00
Nikita Popov
1f88d80408 [SCCP] Don't mark edges feasible when resolving undefs
As branch on undef is immediate undefined behavior, there is no need
to mark one of the edges as feasible. We can leave all the edges
non-feasible. In IPSCCP, we can replace the branch with an unreachable
terminator.

Differential Revision: https://reviews.llvm.org/D126962
2022-06-22 10:28:27 +02:00
Bin Cheng
8b360c69e9 [FuncSpec]Fix assertion failure when value is not added to solver
This patch improves the fix in D110529 to prevent from crashing on value
with byval attribute that is not added in SCCP solver.

Authored-by: sinan.lin@linux.alibaba.com
Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D126355
2022-06-10 18:45:53 +08:00
Alexandros Lamprineas
a910337b5d [FuncSpec] Conditional jump or move depends on uninitialised value(s).
I found this bug when performing a two-stage build of clang with
Function Specialization enabled and tuned aggressively. The crash
appears only on release builds.

Fixes https://github.com/llvm/llvm-project/issues/55000.

Before accessing the contents of the ArgInfo iterator inside
SCCPInstVisitor::markArgInFuncSpecialization, we should be
checking that the iterator is valid.

Differential Revision: https://reviews.llvm.org/D124114
2022-04-27 07:28:25 +01:00
David Green
9727c77d58 [NFC] Rename Instrinsic to Intrinsic 2022-04-25 18:13:23 +01:00
Alexandros Lamprineas
b4417075dc [FuncSpec] Constant propagate multiple arguments for recursive functions.
This fixes a TODO in constantArgPropagation() to make it feature complete.
However, I do find myself in agreement with the review comments in
https://reviews.llvm.org/D106426. I don't think we should pursue
specializing such recursive functions as the code size increase becomes
linear to 'max-iters'. Compiling the modified test just with -O3 (no
function specialization) generates the same code.

Differential Revision: https://reviews.llvm.org/D122755
2022-03-31 13:00:08 +01:00
Alexandros Lamprineas
8045bf9d0d [FuncSpec] Support function specialization across multiple arguments.
The current implementation of Function Specialization does not allow
specializing more than one arguments per function call, which is a
limitation I am lifting with this patch.

My main challenge was to choose the most suitable ADT for storing the
specializations. We need an associative container for binding all the
actual arguments of a specialization to the function call. We also
need a consistent iteration order across executions. Lastly we want
to be able to sort the entries by Gain and reject the least profitable
ones.

MapVector fits the bill but not quite; erasing elements is expensive
and using stable_sort messes up the indices to the underlying vector.
I am therefore using the underlying vector directly after calculating
the Gain.

Differential Revision: https://reviews.llvm.org/D119880
2022-03-28 12:01:53 +01:00
Alexandros Lamprineas
33830326aa [FuncSpec] Remove definitions of fully specialized functions.
A function is basically dead when:
 * it has no uses
 * it has only self-referencing uses (it's recursive)

Differential Revision: https://reviews.llvm.org/D119878
2022-03-01 11:57:08 +00:00
Alexandros Lamprineas
438a81a284 [Function Specialisation] Fix use after free
This is a fix for a use-after-free found by the address sanitizer when
compiling GCC: https://github.com/llvm/llvm-project/issues/52821

The Function Specialization pass may remove instructions, cached
inside the PredicateBase class, which are later being dereferenced
from the SCCPInstVisitor class. To prevent the dangling references
I am lazily deleting the dead instructions after the Solver has run.

Differential Revision: https://reviews.llvm.org/D118591
2022-02-02 16:32:10 +00:00
Sjoerd Meijer
9e3ae8d296 [FuncSpec] Rename internal option. NFC.
Rename option MaxConstantsThreshold to MaxClonesThreshold. Not only is this
more descriptive, this is also in preparation of introducing another threshold
to analyse more than just 1 constant argument as we currently do, and to better
distinguish these options/thresholds.
2021-12-21 11:02:01 +00:00
Sjoerd Meijer
78a392cf9f [FuncSpec] Respect MaxConstantsThreshold
This is a follow up of D115458 and truncates the worklist of actual arguments
that can be specialised to 'MaxConstantsThreshold' candidates if
MaxConstantsThreshold was exceeded. Thus, this changes the behaviour of option
-func-specialization-max-constants. Before it didn't specialise at all when
this threshold was exceeded, but now it specialises up to MaxConstantsThreshold
candidates from the sorted worklist.

Differential Revision: https://reviews.llvm.org/D115509
2021-12-17 09:25:45 +00:00
Sjoerd Meijer
67a58fa3a6 [FuncSpec] Don't run the solver if there's nothing to do
Even if there are no interesting functions, the SCCP solver would still run
before bailing. Now bail earlier, avoid running the solver for nothing.

Differential Revision: https://reviews.llvm.org/D111645
2021-10-13 19:05:19 +01:00