This is a follow-up of D102201. After some discussion, it is a better idea
to upgrade all invalid uses of alignment attributes on function return
values and parameters, not just limited to void function return types.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
First, thanks a lot for looking into this again. I appreciate it a lot.
I left a bunch of minor comments and suggestions. Now that I thought about it for a second, I feel we should not look for alignment at all but instead call typeIncompatible here. For one, that will make future updates obsolete. It also will directly handle other attributes we might have missed here. Finally, it will handle pointer vectors and such properly.
WDYT?
llvm/lib/Bitcode/Reader/BitcodeReader.cpp | ||
---|---|---|
5641 | I didn't see this before but CallInst is not enough, you want CallBase. | |
llvm/lib/IR/AutoUpgrade.cpp | ||
4383–4388 | I haven't run this but should be easier to read. |
Address review feedback. Now remove all incompatible attributes from non pointer type.
Maybe we can expand more to try to upgrade everything including pointer type as well.
I don't think that matters too much and I am not sure if I revert a binary file will add a duplication to git history. The case in 3.3 version is kind of covered by newly added test case except created by different llvm version.
I didn't update the PR description but you can see my actual commit message by go to Revision Contents -> Commits -> Summary (show more..)
I think it matters. With the original file in place, it's clear that we actually upgrade correctly all the attributes that were in the 3.3 test. Without it, it's unclear.
I am not sure if I revert a binary file will add a duplication to git history.
Every object in Git is referenced by the hash of its content. Older commits (before @jdoerfert's patch) will point at the same hash for attributes-3.3.ll.bc as the new commits after it gets reverted back. There's no duplication here.
The case in 3.3 version is kind of covered by newly added test case except created by different llvm version.
Yeah, kind of. But not entirely.
FYI, this change causes a non-trivial compile-time regression in LTO builds: https://llvm-compile-time-tracker.com/compare.php?from=136ced498ba84f6b6126051626e319f18ba740f5&to=5b6cae5524905bc43cfc21a515f828528d1f2e68&stat=instructions (Worst regression seems to be the ThinLTO kc.link step, which is up 4%.)
LLVM attributes are optimized for immutable usage, and it's hard to overstate just how slow the mutable APIs on them are...
I suggested not to check for attributes just to remove them. I still think that's the right thing *but* we can check for them in the remove functions.
@nikic you think that will resolve the compile time issue?
Three other ideas, which can all be applied, but the compile time regression might be fixed without doing them all:
- Serialize somewhere an "attribute list version", which can be used to skip attribute-upgrading entirely if the current and serialized versions match. This avoids any slowdown in the typical LTO case (old archived object files notwithstanding).
- Keep a map when upgrading from (AttributeList,FunctionType*) to AttributeList to cache the computation.
- Construct a new attribute list in bulk rather than going through intermediate states and mutating the old one piecemeal.
I've added two optimizations along those lines in https://github.com/llvm/llvm-project/commit/fd46ed3f397d6cf41bc6c5a04ab2089f585afe44 and https://github.com/llvm/llvm-project/commit/05738ffcb87b76c6f166f965ba9b2db3257a4338.
The remaining impact from this change is now https://llvm-compile-time-tracker.com/compare.php?stat=instructions&from=9530d41b3106a8bdc619f7bf4dd6e2e645bb2b07&to=05738ffcb87b76c6f166f965ba9b2db3257a4338, which seems acceptable.
Yep, thanks to both of you to solving the problem with general solutions, will help in the long run for sure :)
I didn't see this before but CallInst is not enough, you want CallBase.
I'm not sure why you go through the functiontype but it seems odd.
If the call base type is not a pointer, just remove alignment attribute (no need to check I think).
You want the call site arguments not the function type parameters, the former are potentially more for varargs functions and then we also don't want to have aligned non-pointer arguments.
And again, no need to check if the argument is present, removing it eagerly should be as expensive.