-
-
Notifications
You must be signed in to change notification settings - Fork 418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update LLVM to 14.0.3 #4055
Update LLVM to 14.0.3 #4055
Conversation
Hi @kulibali, The changelog - changed label was added to this pull request; all PRs with a changelog label need to have release notes included as part of the PR. If you haven't added release notes already, please do. Release notes are added by creating a uniquely named file in the The basic format of the release notes (using markdown) should be:
Thanks. |
Ponyc compiles and all tests succeed except for |
We should also see if Windows debug builds stop hanging with this change. |
Investigation so far: Given a Pony program
Using LLVM 13, the
This is inlined from Using LLVM 14 with optimizations on, the
and there is no If I change line 1365 in |
Discussed during the sync call - I suspect if we link against the runtime bitcode the problem will be fixed, because we likely are tagging wrong attributes on one of our runtime functions. We need to tag the right attributes so that LLVM knows that the descriptor memory will be read from by our garbage collector, so that it won't try to optimize away the store to that memory. That's what I suspect. |
…n doesn't elide them
Looks like marking the store as volatile prevents it being removed. |
Also on Linux I had to make copies of some of the LLVM C functions because they were marked as deprecated (I didn't see this at first because we don't error on warning in Windows). They were all expecting non-opaque pointers (which we supply), from which they could extract the LLVM type. LLVM has been deprecating these in favour of new functions (with a "2" added to their name) that can take opaque pointers, so you have to provide their types explicitly. So I made copies of the old functions (with a "_P" for Pony added to their names) that aren't marked deprecated. Alternatively if we don't like this approach we could add a new C function that calls |
src/libponyc/codegen/gencall.c
Outdated
|
||
LLVMValueRef desc_ptr = LLVMBuildStructGEP_P(c->builder, value, 0, ""); | ||
LLVMValueRef store_inst = LLVMBuildStore(c->builder, c_t->desc, desc_ptr); | ||
LLVMSetVolatile(store_inst, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where we set the type descriptor store to be volatile.
I worry that marking the stores as That said, I don't have the answers about what the real solution would be. @kulibali - did you try linking against the runtime bitcode and seeing if that resolves the issue? |
Stupid typo in my comment above; using runtime bitcode DOES exhibit the problem. So it seems dead store elimination is a little agressive. |
This seems like it might be worth opening an LLVM issue? |
I believe we said last week that when Sean was recovered he would do some performance testing on this branch. |
I'll spend some time poking around the LLVM git history. |
I'll also try removing attributes from function declarations and call sites. |
I have tracked down the breaking change to llvm/llvm-project@3cef3cf. I'll investigate further what we're doing with alias scopes. |
Thanks for tracking down the commit. Perhaps all that's needed is to remove the Technically it's not true that there is no alias to these new objects, because we hold an alias to each of them in our heap's object map (which is the alias we use for running the finalizer). So removing that attribute is probably the "correct" way to solve this problem. |
I have removed the |
Glad that solved the issue! I'm gonna clone this locally because there's one more thing I want to try - keeping the I'm going to do more reading in the Pony runtime to look for all the places we might dereference this pointer. |
I've pushed a commit which reinstates most of the This should help us keep the potential of LLVM being able to optimize away some heap allocations/stores which are not read from / captured, while still keeping correctness for objects with finalisers that may have specific finaliser effects to be run. |
Only the `pony_alloc_final*` functions need to avoid the `noalias` attribute, because running a finaliser is the only case where we have the issue where the runtime needs to dereference memory with the alias held by the object map, but LLVM sees that the object was never read from again, and thus can optimize it away. Only finaliser effects prevent this LLVM optimization.
In LLVM 13.0.0 we had observed a bug in which, when using the new LLVM PassBuilder, some functions were being generated without return instructions, causing the instruction pointer to just blunder off the end of one function definition into the next one in the executable binary's memory layout, likely violating stack/argument assumptions of that function, ultimately leading to some form of memory corruption. This is why we had disabled use of those optimizations temporarily in an earlier PR (#203), though it was only diagnosed in detail this morning. We update to the latest available LLVM release (14.0.3) to avoid this issue and also to keep up with the times. Note that in this update to 14.0.3 an issue was discovered in Pony with the use of `NoAlias` attributes on allocation functions for those functions that allocate an object with a finalizer. These attributes were technically incorrect, and a new optimization present in 14.0.3 now can optimize away code that shouldn't be removed if it trusts the erroneous use of that attribute. See ponylang/ponyc#4055 This bug had not been observed directly in Savi because we do not yet support allocations with finalizers. But the attributes are updated here nonetheless, as it's easy to fix this correctness issue now while it's at top of mind.
In LLVM 13.0.0 we had observed a bug in which, when using the new LLVM PassBuilder, some functions were being generated without return instructions, causing the instruction pointer to just blunder off the end of one function definition into the next one in the executable binary's memory layout, likely violating stack/argument assumptions of that function, ultimately leading to some form of memory corruption. This is why we had disabled use of those optimizations temporarily in an earlier PR (#203), though it was only diagnosed in detail this morning. We update to the latest available LLVM release (14.0.3) to avoid this issue and also to keep up with the times. Note that in this update to 14.0.3 an issue was discovered in Pony with the use of `NoAlias` attributes on allocation functions for those functions that allocate an object with a finalizer. These attributes were technically incorrect, and a new optimization present in 14.0.3 now can optimize away code that shouldn't be removed if it trusts the erroneous use of that attribute. See ponylang/ponyc#4055 This bug had not been observed directly in Savi because we do not yet support allocations with finalizers. But the attributes are updated here nonetheless, as it's easy to fix this correctness issue now while it's at top of mind.
In LLVM 13.0.0 we had observed a bug in which, when using the new LLVM PassBuilder, some functions were being generated without return instructions, causing the instruction pointer to just blunder off the end of one function definition into the next one in the executable binary's memory layout, likely violating stack/argument assumptions of that function, ultimately leading to some form of memory corruption. This is why we had disabled use of those optimizations temporarily in an earlier PR (#203), though it was only diagnosed in detail this morning. We update to the latest available LLVM release (14.0.3) to avoid this issue and also to keep up with the times. Note that in this update to 14.0.3 an issue was discovered in Pony with the use of `NoAlias` attributes on allocation functions for those functions that allocate an object with a finalizer. These attributes were technically incorrect, and a new optimization present in 14.0.3 now can optimize away code that shouldn't be removed if it trusts the erroneous use of that attribute. See ponylang/ponyc#4055 This bug had not been observed directly in Savi because we do not yet support allocations with finalizers. But the attributes are updated here nonetheless, as it's easy to fix this correctness issue now while it's at top of mind.
This change updates our LLVM submodule to 14.0.3 and updates ponyc to compile with that version.