Skip to content
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

RFC: Use JL_LLVM_VERSION instead of LLVMxx #17826

Merged
merged 1 commit into from
Sep 16, 2016

Conversation

ararslan
Copy link
Member

@ararslan ararslan commented Aug 5, 2016

Fixes #9860.

As noted in the linked issue, the names LLVM37, LLVM34, etc. aren't immediately descriptive because they don't refer to specific versions but rather to ranges of versions. This implements the proposed fix of having a single LLVM_VERSION macro that holds the LLVM version as a two-digit number and instead of checking whether LLVMxx is defined, we check whether LLVM_VERSION >= xx. Similarly, checking whether LLVMxx is not defined equates to LLVM_VERSION < xx.

This works locally, so fingers crossed that it works everywhere else...

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

There was some discussion of whether there should be a 3.10 version. Just to be safe, I think we can use something like 0x030701.

#elif LLVM_VERSION_MINOR == 3
#define LLVM_VERSION 33
#endif
#endif
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructing LLVM_VERSION can be done more succinctly as

#define CONCAT(a, b) a ## b
#define GETVERS(maj, min) CONCAT(maj, min)
#define LLVM_VERSION GETVERS(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR)

But as @yuyichao noted, this is the kind of thing that one gets stabbed for if put into production.

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

You mean check for LLVM 3.10 by doing LLVM_VERSION >= 0x030701?

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

No, I mean #define JL_LLVM_VERSION (LLVM_VERSION_MAJOR * 0x10000 + LLVM_VERSION_MINOR * 0x100 + LLVM_VERSION_PATCH)

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

100 instead of 0x100 is also fine, and can possibly reduce typo (it's probably more likely to miss a 0x than adding one)

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

Anyther way is to use something like the glibc trick

# if __GLIBC_PREREQ(2, 12)

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

So something like

#if _LLVM_VERSION_GE(3, 10)

where _LLVM_VERSION_GE(x, y) checks that the version is at least x.y?

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

I get segfaults when I do #define JL_LLVM_VERSION (LLVM_VERSION_MAJOR * 0x10000 + LLVM_VERSION_MINOR * 0x100 + LLVM_VERSION_PATCH)

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

Yes.... Maybe use JL_ instead of _ as prefix. IIRC, there is one place we check patch version in this file. Too bad msvc doesn't like variadic macros otherwise we can use the same macro to check version with an optional patch version....

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

I get segfaults when I do

Full patch??

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

What do you mean full patch? This is what I was doing to test:

#define LLVM_VERSION_MAJOR 3
#define LLVM_VERSION_MINOR 10
#define LLVM_VERSION_PATCH 1

#define JL_LLVM_VERSION (LLVM_VERSION_MAJOR * 0x10000 + LLVM_VERSION_MINOR * 0x100 + LLVM_VERSION_PATCH)

int main() {
    int x = JL_LLVM_VERSION;
    printf("%s", x);
    return 0;
}

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

    int x = JL_LLVM_VERSION;
    printf("%s", x);
    return 0;

Why should this work at all?

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

¯_(ツ)_/¯ Because I'm not good at C

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

Because I'm not good at C

A good advice for C is to turn on -Wall -Wextra and fix all the warning.

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

Oh, heh, whoops. Format string...

So for major version 3, minor 10, patch 1, I get 199169. How would you check the version based on that number?

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

0x31001

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

Do patches ever have more than two digits?

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

Do patches ever have more than two digits?

The nope is that neither patch and minor do. Actually 100 is better than 0x100 sin 3.10 is actually 0x30a00 ........

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

Okay, changed to use the 0x version you suggested.

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

I actually mean the 100 version is better ....


#endif
#if LLVM_VERSION < 0x33000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think thse bounds are wrong. E.g. after switching to 100, this should be 30300

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

LGTM other than the missing JL_ prefix.

@ararslan
Copy link
Member Author

ararslan commented Aug 5, 2016

Okay, added the JL_ prefix. I had meant to add it when you had first mentioned it but forgot. Thanks so much for all of your help and patience!

@@ -1,6 +1,6 @@
// This file is a part of Julia. License is MIT: http:https://julialang.org/license

#if defined(LLVM38) && !defined(LLVM37)
#if defined(JL_LLVM_VERSION) && JL_LLVM_VERSION >= 30800
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the defined(JL_LLVM_VERSION) needed here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's not needed. I'll take it out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, we shouldn't check if JL_LLVM_VERSION is defined. This can catch errors of missing include earlier rather than silently ignoring the error.

@yuyichao
Copy link
Contributor

yuyichao commented Aug 5, 2016

I looked through the diff and I think the translation is correct. Since the diff is so long, it would be better if someone else could have a look too to make sure we aren't silently disabling features on newer version of llvm.

@@ -103,7 +103,7 @@ void addOptimizationPasses(PassManager *PM)
#endif

#if defined(JL_ASAN_ENABLED)
# if defined(LLVM37) && !defined(LLVM38)
# if JL_LLVM_VERSION == 30700
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#if JL_LLVM_VERSION >= 30700 && JL_LLVM_VERSION < 30800

@@ -1,6 +1,6 @@
// This file is a part of Julia. License is MIT: http:https://julialang.org/license

#if defined(LLVM38) && !defined(LLVM37)
#if JL_LLVM_VERSION >= 30800
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would the old version of this ever happen?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function is also declared in jitlayers.cpp. Doing it here might have some issue due to missing type declaration/missing headers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tkelman If 3.8 is the lowest version. So it's at least 3.8 and not 3.7 or lower.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuyichao Should the function declaration here be removed then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition is actually USE_ORCJIT && JL_LLVM_VERSION <= 30800 (roughly 3.7 <= llvm_ver < 3.8). It is better to remove the declaration in jitlayers.cpp instead and keep this one with the condition fixed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition there before was false, the current condition is wrong. The correct one is in jitlayers.cpp and is the same with the one I gave above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it fails if I remove the part in jitlayers.cpp.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to jitlayers.h

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defined(LLVM38) && !defined(LLVM37) would never happen since LLVM37 meant "3.7 or newer"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is why I said,

The condition there before was false

This was added before the JIT and codegen are split and therefore before jitlayers.h exists. This is needed only by jitlayers.cpp, which doesn't include codegen_internal.h, for LLVM 3.7.x which is why it should be moved to jitlayers.h.

@ararslan ararslan force-pushed the aa/llvm_version_macro branch 5 times, most recently from cef63d2 to 0158e6c Compare September 8, 2016 00:51
@@ -1,6 +1,6 @@
// This file is a part of Julia. License is MIT: http:https://julialang.org/license

#if defined(LLVM38) && !defined(LLVM37)
#if defined(USE_ORCJIT) && JL_LLVM_VERSION <= 30800
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the old version of this could never be true, probably best to just delete these few lines

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @yuyichao specifically requested this change: #17826 (comment)

@tkelman
Copy link
Contributor

tkelman commented Sep 8, 2016

(I found this a little easier to review locally after

curl -L https://github.com/JuliaLang/julia/pull/17826.patch | git apply
for i in $(seq 3 9); do
  sed -i -e "s/JL_LLVM_VERSION >= 30${i}00/defined(LLVM3$i)/g" \
    -e "s/JL_LLVM_VERSION < 30${i}00/\!defined(LLVM3$i)/g" \
    -e "s/#if defined(LLVM3$i)/#ifdef LLVM3$i/g" \
    -e "s/#if \!defined(LLVM3$i)/#ifndef LLVM3$i/g" src/*.cpp src/*.h
done

which gives a shorter diff)

@ararslan ararslan force-pushed the aa/llvm_version_macro branch 3 times, most recently from dd37fe8 to 8cc0383 Compare September 14, 2016 22:32
@ararslan ararslan changed the title RFC: Use LLVM_VERSION instead of LLVMxx RFC: Use JL_LLVM_VERSION instead of LLVMxx Sep 14, 2016
@ararslan
Copy link
Member Author

Is there anything else this needs before it's good to go?

@@ -59,7 +59,7 @@ using namespace llvm;
#include <cstdio>
#include <cassert>

#if defined(LLVM35) && !defined(LLVM36)
#if JL_LLVM_VERSION == 30500
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should in principle still be a range since LLVM 3.5.1 does exist. Not sure if it actually matters though since we might not compile there anyway....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

@yuyichao
Copy link
Contributor

yuyichao commented Sep 15, 2016

LGTM other than the very minor comment above. I think we should merge this now. It's unlikely that we can trivially backport all codegen changes anymore and the conflict introduced by this change should be easy to resolve.

If everyone is fine with this I'd like to merge this tomorrow (with the comment above fixed or not) and rebase #18519 on top of this.

@yuyichao
Copy link
Contributor

I think there was a conflict before #18519 was merged........ So I guess this needs to be rebased again (hopefully the last time).

@ararslan
Copy link
Member Author

Rebased and conflicts resolved. Thanks for the heads up!

@yuyichao yuyichao merged commit 8cb72ee into JuliaLang:master Sep 16, 2016
@ararslan ararslan deleted the aa/llvm_version_macro branch September 16, 2016 17:21
@ararslan
Copy link
Member Author

Reviewers should probably pay extra careful attention to future PRs that modify or introduce LLVM version conditioning in the C preprocessor, since #ifdef LLVMxx will always be false now.

@tkelman
Copy link
Contributor

tkelman commented Sep 16, 2016

should we make those defines result in compile-time errors now? maybe just for a little while?

@ararslan
Copy link
Member Author

That seems like a good idea to me. How would you propose we go about that? I can submit a PR.

@yuyichao
Copy link
Contributor

I don't think there's a way to do it in C++ code (a grep on CI could do that though). It shouldn't be a huge issue since hopefully PR's that uses those are already tested on newer LLVM versions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace LLVM_34 and friends by LLVM_VERSION
4 participants