This patch allows iterating typed enum via the ADT/Sequence utility.
It also changes the original design to better separate concerns:
- `StrongInt` only deals with safe `intmax_t` operations,
- `SafeIntIterator` presents the iterator and reverse iterator
interface but only deals with safe `StrongInt` internally.
- `iota_range` only deals with `SafeIntIterator` internally.
This design ensures that operations are always valid. In particular,
"Out of bounds" assertions fire when:
- the `value_type` is not representable as an `intmax_t`
- iterator operations make internal computation underflow/overflow
- the internal representation cannot be converted back to `value_type`
Differential Revision: https://reviews.llvm.org/D106279
The argument reduction pass shouldn't remove arguments of
intrinsics, because the resulting module is ill-formed, and so
inherently uninteresting.
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D103129
The parseInputFile function returns an empty unique_ptr to signal an
error, like when the input file doesn't exist, or is malformed. In this
case, the tool should exit immediately rather than segfault by
dereferencing the unique_ptr later.
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D102891
This introduces a flag that aborts if we ever reduce to IR that fails
the verifier.
Reviewed By: swamulism, arichardson
Differential Revision: https://reviews.llvm.org/D101279
Much like with ReduceFunctionBodies delta pass,
we need to remove comdat and set linkage to external,
else verifier will complain, and our deltas are invalid.
The limitation of the current pass that it skips initializer-less GV's
seems arbitrary, in all the reduced cases i (personally) looked at,
the globals weren't needed, yet they were kept.
So let's do two things:
1. allow reducing initializer-less globals
2. before reducing globals, reduce their initializers, much like we do function bodies
ee6e25e4391a6d3ac0a3c89615474e512f44cda6 changed
the delta pass to skip intrinsics, which means we may end up being
left with declarations of intrinsics, that aren't otherwise referenced
in the module. This is obviously unwanted, do drop them.
No longer rely on an external tool to build the llvm component layout.
Instead, leverage the existing `add_llvm_componentlibrary` cmake function and
introduce `add_llvm_component_group` to accurately describe component behavior.
These function store extra properties in the created targets. These properties
are processed once all components are defined to resolve library dependencies
and produce the header expected by llvm-config.
Differential Revision: https://reviews.llvm.org/D90848
This patch adds a reduction of 'special' globals that lead to further
reductions (e.g. alias or regular globals reduction) being less efficient
because there are special constraints on values referenced in those
special globals. For example, values in @llvm.used and
@llvm.compiler.used need to be named, so replacing all uses of an
alias/global with undef or a different unnamed constant results in
invalid IR.
More details:
https://llvm.org/docs/LangRef.html#intrinsic-global-variables
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D90302
This patch adds a new reduction pass that tries to remove aliases.
It runs early, as most of those likely can be removed up-front in
practice.
This substantially improves llvm-reduce for IR generated by the swift
compiler, which can generate a lot of aliases which lead to lots of
invalid reductions.
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D90260
These don't really have function bodies to try to eliminate. This also
has a good chance of just producing invalid IR since intrinsics can
have special operand constraints (e.g. metadata arguments aren't valid
for an arbitrary call). This was wasting quite a bit of time producing
and failing on invalid IR when replacing dbg.values with undefs.
Currently replaceBranchTerminator/removeUninterestingBBsFromSwitch
always creates `ret void` instructions if no successor is in the chunk.
This results in invalid IR for functions with non-void return types,
which makes those reductions unfeasible. Instead, create `ret ty undef`
for functions with non-void return types.
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D86849
althought the interstingness test should usually fail when the module is invalid
this changes reduces the frequency at which llvm-reduce generate invalid IR.
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D86404
Some reduction passes may create invalid IR. I am not aware of any use
case where we would like to proceed reducing invalid IR. Various utils
used here, including CloneModule, assume the module to clone is valid
and crash otherwise.
Ideally, no reduction pass would create invalid IR, but some currently
do. ReduceInstructions can be fixed relatively easily (D86210), but
others are harder. For example, ReduceBasicBlocks may remove result in
invalid PHI nodes.
For now, skip the chunks. If we get to the point where all reduction
passes result in valid IR, we may want to turn this into an assertion.
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D86212
Removing terminators will result in invalid IR, making further
reductions pointless. I do not think there is any valid use case where
we actually want to create invalid IR as part of a reduction.
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D86210
This helps with both debugging llvm-reduce and sometimes getting usefull result even if llvm-reduce crashes
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D85996
It is not enough to replace all uses of users of the function with undef,
the users, we only drop instruction users, so they may stick around.
Let's try different approach - first drop bodies for all the functions
we will drop, which should take care of blockaddress issue the previous
rewrite was dealing with; then, after dropping *all* such bodies,
replace remaining uses with undef (thus all the uses are either
outside of functions, or are in kept functions)
and then finally drop functions.
This seems to work, and passes the *existing* test coverage,
but it is possible that a new issue will be discovered later :)
A new (previously crashing) test added.
Much like with function reduction, there may be remaining unhandled uses
of function, in particular in blockaddress. And in constants we can't
RAUW it with undef, because undef is not a function.
Instead, let's try to pretent that in the remaining cases, the new
signature didn't change, by bitcasting it.
A new (previously crashing) test case added.
There may be other users of a function other than CallInsts,
but what's more important, we can't actually replace function pointer
with undef, because for constants, that would not preserve the type
and RAUW would assert.
In particular, that affects blockaddress, however it proves to be
prohibitively complex to come up with a good test involving blockaddress:
we'd need to both ensure that the function body survives until
this pass, and is not interesting in this pass.
We can happily turn function definitions into declarations,
thus obscuring their argument from being elided by this pass.
I don't believe there is a good reason to just ignore declarations.
likely even proper llvm intrinsics ones,
at worst the input becomes uninteresting.
The other question here is that all these transforms are all-or-nothing.
In some cases, should we be treating each use separately?
The main blocker here seemed to be that llvm::CloneFunctionInto()
does `&OldFunc->front()`, which inserts a nullptr into a densemap,
which is not happy about it and asserts.
replaceFunctionCalls() is very non-exhaustive, it only handles
CallInst's. Which means, by the time we drop old function,
there may still be uses of it lurking around.
Let's instead whack-a-mole them by all by replacing with undef.
I'm not sure this is the best handling, especially for calls, but IMO
poorly reduced input is much better than crashing reduction tool.
A (previously-crashing!) test added.
Fixes https://bugs.llvm.org/show_bug.cgi?id=46819
Terminator may have returned value, so we need to replace uses,
and in general handle invoke as a branch inst.
I'm not sure this is the best handling, but IMO poorly reduced
input is much better than crashing reduction tool.
A (previously-crashing!) test added.
Fixes https://bugs.llvm.org/show_bug.cgi?id=46818
ReduceFunctions could do it, but it also replaces *all* calls with undef,
so if any of undef replacements makes reduction uninteresting,
it won't work.
ReduceBasicBlocks also could do it, but well, it may take many guesses
for all the blocks of a function to happen to be out-of-chunk,
which is not a very efficient way to go about it.
So let's just do this first.
Summary:
If there was a single target to begin with, because a single target
can only occupy a single chunk, we couldn't increase granularity.
and would immediately give up.
Likewise, if we had multiple targets, if by the end we'd end up with
a single target, we wouldn't finish reducing it, it would always
end up being "interesting"
Reviewers: dblaikie, nickdesaulniers, diegotf
Reviewed By: dblaikie
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D84318
Newly-added test previously crashed.
While it is up for debate whether or not instruction reduction
should be indiscriminate in instruction dropping (there you can
just ensure that the test case is still -verify'ies), here
if we drop terminator, CloneFunctionInto() will immediately crash.
So let's not do that :)
The function extractArgumentsFromModule() was passing a one-based index to,
but replaceFunctionCalls() was expecting a zero-based argument index. This
resulted in assertion errors when reducing function call arguments with
different types. Additionally, the
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D84099
Summary:
This handles all three places where attributes could currently be - `GlobalVariable`, `Function` and `CallBase`.
For last two, it correctly handles all three possible attribute locations (return value, arguments and function itself)
There was a previous attempt at it D73853,
which was committed in rGfc62b36a000681c01e993242b583c5ec4ab48a3c,
but then reverted all the way back in rGb12176d2aafa0ccb2585aa218fc3b454ba84f2a9
due to some (osx?) test failures.
Reviewers: nickdesaulniers, dblaikie, diegotf, george.burgess.iv, jdoerfert, Tyker, arsenm
Reviewed By: nickdesaulniers
Subscribers: wdng, MaskRay, arsenm, llvm-commits, mgorny
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83351
Summary:
I think, this results in much more understandable/readable flow.
At least the original logic was perhaps the most hard thing for me to grasp when taking an initial look on the delta passes.
Reviewers: nickdesaulniers, dblaikie, diegotf, george.burgess.iv
Reviewed By: nickdesaulniers
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83287
Summary:
This would have been marginally useful to me during/for rG7ea46aee3670981827c04df89b2c3a1cbdc7561b.
With ongoing migration to representing assumes via operand bundles on the assume, this will be gradually more useful.
Reviewers: nickdesaulniers, diegotf, dblaikie, george.burgess.iv, jdoerfert, Tyker
Reviewed By: nickdesaulniers
Subscribers: hiraditya, mgorny, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83177
As it can be seen in newly-added (previously-crashing) test-case,
there can be a situation where multiple GV's are used in instr,
and we would schedule the same instruction to be deleted several times,
crashing when trying to delete it the second time.
We could either store WeakVH (done here), or use something set-like.
I think using WeakVH is prevalent in these cases elsewhere.
As it can be seen in newly-added (previously-crashing) test-case,
there can be a situation where multiple arguments are used in instr,
and we would schedule the same instruction to be deleted several times,
crashing when trying to delete it the second time.
We could either store WeakVH (done here), or use something set-like.
I think using WeakVH is prevalent in these cases elsewhere.
Summary:
The output from llvm-reduce still has significantly more attributes than
bugpoint does. Teach llvm-reduce to remove attributes.
Reviewers: diegotf, dblaikie, george.burgess.iv
Subscribers: mgorny, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73853
This is how it should've been and brings it more in line with
std::string_view. There should be no functional change here.
This is mostly mechanical from a custom clang-tidy check, with a lot of
manual fixups. It uncovers a lot of minor inefficiencies.
This doesn't actually modify StringRef yet, I'll do that in a follow-up.