-
-
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 the Pony compiler to be able to use LLVM 4.0.0 (#1592). #2061
Conversation
.travis.yml
Outdated
packages: | ||
- g++-6 | ||
env: | ||
- FAVORITE_CONFIG=yes |
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.
can only have 1 favorite config. can you set this to "no" for now.
favorite config is used to decide which linux version will be done for release. so until we decide that 4.0.0 is the default, it should be "no"
getting some build errors:
|
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.
Awesome, thank you!
This should also contain README changes for LLVM 4. I've also left a few inline comments.
src/libponyc/codegen/genreference.c
Outdated
|
||
if(ast_id(def) != TK_STRUCT) | ||
index++; | ||
|
||
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.
Whitespace here.
Makefile
Outdated
else | ||
$(warning WARNING: Unsupported LLVM version: $(llvm_version)) | ||
$(warning Please use LLVM 3.7.1, 3.8.1, or 3.9.1) | ||
$(warning Please use LLVM 3.7.1, 3.8.1, 3.9.1, or 4.0.0) |
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 should contain 4.0.1 as well.
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 wont work with homebrew on the mac until 4.0.1 is in here.
Based on how we do this, we shouldn't be supporting 4.0.0 we should only support 4.0.1
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.
Ok, I wasn't aware of the homebrew status.
IIRC, we're not supporting 3.7.0, 3.8.0 and 3.9.0 because we've found blocking LLVM bugs in these versions. Until we find such a bug in either 4.0.0 or 4.0.1, I think it would be good to officially support both.
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.
i thought we were only "supporting" the most recent version of any of the major releases. if we are supporting 4.0.0 then we need to do CI on it. Homebrew is going to install 4.0.1 on OSX.
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.
The CI is a good point. You're right, we should keep the current scheme.
src/libponyc/codegen/codegen.h
Outdated
@@ -179,8 +181,10 @@ typedef struct compile_t | |||
LLVMDIBuilderRef di; | |||
LLVMMetadataRef di_unit; | |||
LLVMValueRef tbaa_root; | |||
#if LLVM_PONY < 400 |
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 should be PONY_LLVM
.
src/libponyc/codegen/gentype.c
Outdated
static LLVMValueRef make_tbaa_root(LLVMContextRef ctx) | ||
{ | ||
const char str[] = "Pony TBAA"; | ||
LLVMValueRef mdstr = LLVMMDStringInContext(ctx, str, sizeof(str) - 1); | ||
return LLVMMDNodeInContext(ctx, &mdstr, 1); | ||
} | ||
|
||
static LLVMValueRef make_tbaa_descriptor(LLVMContextRef ctx, LLVMValueRef root) |
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.
Why was this removed? It is still needed for TBAA on type descriptors.
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.
Hmm, you're right. Seems to have been lost when I reverted my over-ambitious TBAA stuff.
src/libponyc/codegen/gentype.c
Outdated
return LLVMMDNodeInContext(ctx, params, 3); | ||
} | ||
|
||
static LLVMValueRef make_tbaa_descptr(LLVMContextRef ctx, LLVMValueRef root) |
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.
Same as above.
src/libponyc/codegen/host.cc
Outdated
{ | ||
pony_assert(parent != NULL); | ||
pony_assert(node != NULL); | ||
pony_assert((int)i >= 0); |
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 check isn't needed. llvm::MDNode::replaceOperandWith
has an unsigned parameter so i
will never be used as signed.
@kulibali you need to update .travis_install.bash to correctly install LLVM 4.0 on Travis. You'd need OSX and Linux versions. |
.travis_install.bash
Outdated
brew install pcre2 | ||
brew install libressl | ||
|
||
brew install [email protected] |
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.
.travis_install.bash
Outdated
brew install libressl | ||
|
||
brew install [email protected] | ||
brew link --overwrite --force [email protected] |
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.
you don't want [email protected] here
.travis_install.bash
Outdated
brew link --overwrite --force [email protected] | ||
mkdir llvmsym | ||
ln -s "$(which llvm-config)" llvmsym/llvm-config-4.0 | ||
ln -s "$(which clang++)" llvmsym/clang++-4.0 |
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.
im not sure that these are needed. i'd say turn these 3 lines and the corresponding export PATH off and we can enable if needed.
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.
Would this be OK for the OSX section?
"osx:llvm-config-4.0")
brew update
brew install shellcheck
shellcheck ./.*.bash ./*.bash
brew install pcre2
brew install libressl
brew install llvm
# brew link --overwrite --force llvm
# mkdir llvmsym
# ln -s "$(which llvm-config)" llvmsym/llvm-config-4.0
# ln -s "$(which clang++)" llvmsym/clang++-4.0
# do this elsewhere:
#export PATH=llvmsym/:$PATH
;;
Makefile
Outdated
LLVM_LINK = /usr/local/opt/[email protected]/bin/llvm-link | ||
LLVM_OPT = /usr/local/opt/[email protected]/bin/opt | ||
ifneq (,$(shell which /usr/local/opt/[email protected]/bin/llvm-config 2> /dev/null)) | ||
LLVM_CONFIG = /usr/local/opt/[email protected]/bin/llvm-config |
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.
there's no [email protected]
it installs into /usr/local/opt/[email protected]/bin/
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.
Do you mean /usr/local/opt/llvm/bin
?
Ok, I'll need to build new Windows libraries to support 4.0.1, and then I'll update the Windows build. I don't have any access to OSX so I'll try to get it right but will probably need some help. |
src/libponyc/codegen/gentype.c
Outdated
static LLVMValueRef make_tbaa_root(LLVMContextRef ctx) | ||
{ | ||
const char str[] = "Pony TBAA"; | ||
LLVMValueRef mdstr = LLVMMDStringInContext(ctx, str, sizeof(str) - 1); | ||
return LLVMMDNodeInContext(ctx, &mdstr, 1); | ||
} | ||
|
||
#if PONY_LLVM < 400 | ||
|
||
static LLVMValueRef make_tbaa_descriptor(LLVMContextRef ctx, LLVMValueRef root) |
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.
Unfortunately this still isn't correct. The two functions are needed even for LLVM 4. The created metadata nodes are used when loading an element of a type descriptor. See for example desc_field
in gendesc.c
.
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.
For LLVM 4 they need to be in the new path-aware format. I had done some work on this but not finished it. I'll take a further look.
I'm not sure what the Linux test errors are about. On my Ubuntu 16.04 machine all the tests pass. I'm going to need some help with the OSX travis setup, as I have no access to an OSX machine. |
@kulibali I'll take a look, to see if it segfaults on my machine. |
I can reproduce the segfault. At first I suspected that it came from the descriptor TBAA stuff but I fixed that and it still happens. I'll continue to investigate. Here's the diff for the TBAA. |
I've narrowed the crash down to the HeapToStack optimisation pass. It looks like a change in LLVM 4 made previously valid transformations invalid. |
Thanks! I have applied your patch. The tests still pass on Ubuntu 16.04 for me. |
Status update on the crash: it looks like the problem is related to the LICM pass in LLVM, which is hoisting loads and sinking stores in invalid places, resulting in reads from uninitialised memory. I'm still unsure whether the problem is coming from the custom passes in the Pony compiler or the LLVM passes. I've reduced the crash in class val MapNode
let entries: USize = 0
class val HashMap
let root: MapNode = MapNode
actor Main
new create(env: Env) =>
var m6 = HashMap
let vs = Array[U8].create(2).>push(0).>push(1)
let i = vs.values()
while i.has_next() do
try
i.next()
if m6.root.entries != 0 then
error
end
m6 = HashMap
end
end |
I have found by trial and error that if I change |
@kulibali Unfortunately I don't think that's the problem. That function determines whether a given heap allocation can be stack allocated by looking at the uses of the allocation, on the basis that no use should capture the allocated pointer (e.g. by storing it somewhere). A load never captures, so I think you're seeing that result because the change to the load case is overriding the hypothetical buggy case which is erroneously saying that the corresponding operation doesn't capture. |
The segfault also disappears when I disable the inliner pass. |
Interesting |
This change includes the following: - Compiler code updates for changes to the LLVM 4.0.0 API. - Updates to Type-Based Alias Analysis metadata format for LLVM 4.0.0. - Builds in Release mode on Windows to conform to the Unix makefile. - Some efficiency tweaks for the Windows build.
Just for fun I have made a branch that uses LLVM 5.0.0: https://github.com/kulibali/ponyc/tree/llvm500 It compiles on Ubuntu, but crashes in |
I have fixed the crash in |
This sounds like the same bug that's blocking the LLVM 4 port. |
This PR is superceded by #2303 |
This change includes the following: - Compiler code updates for changes to the LLVM 4.0.0 and 5.0.0 API. - Updates to Type-Based Alias Analysis metadata format for LLVM 4.0.0 and up. Note that this code contains a workaround for a problem with hoisting loads of stack-allocated references (see ponylang#2303, ponylang#2061, ponylang#1592), and should be considered experimental. Do not use LLVM 4 or 5 for critical production builds.
This change includes the following: