Segmentation fault - Kaleidoscope

Hello,

Following the tutorial “Kaleidoscope: Adding JIT and Optimizer Support”, I found a Segmentation fault when I try to execute it. I am new in the neighbourhood, so I don’t know what is wrong. Could you help me with that?

I am working with the last version of LLVM (2.5). The code in chapter 2 and 3 works good, but the code in the chapter 4 did not work.

Below are the detail of what I did.

Regards,

Juan Carlos

FWIW, I'm also suddenly experiencing segfaults in code that used to work
a few days ago (I'm using svn). This may be unrelated to the problem
described below, but perhaps it's the same thing.

In my case it seems that creating an ExecutionEngine has changed. I used
to do

    Module* Mod = makeLLVMModule(); // basically create a gcd function
    verifyModule(*Mod, PrintMessageAction);

    ExecutionEngine *EE;
    EE = ExecutionEngine::create(Mod);

but I now get 0x0 for EE. The compile command I'm using is

g++ -O3 -I ~/llvm/include/ -L ~/llvm bug.cpp `llvm-config --cxxflags
--ldflags --libs core jit native` -o bug

I noticed something very recently changed w.r.t. the way LLVM's
libraries are built (no more .o files). Could this have something to
with it?

Regards,
Paul

Juan Carlos Martinez Santos wrote:

I *just* changed this. :slight_smile:

For JIT applications, please include llvm/Target/TargetSelect.h and call the llvm::InitializeNativeTarget() function before creating an EE.

-Chris

Some recent API changes require that the JIT have to be initialized before use:

#include "llvm/Target/TargetSelect.h"

and use
// If we have a native target, initialize it to ensure it is linked in and
// usable by the JIT.
InitializeNativeTarget();

the llvm examples including Kaleidoscope have been changed to use the jit in this new way: this will fix the 0x0 for EE error. Xerxes Den 2009-06-17 18:46, Paul Melis skrev:

Hello,

Maybe my version (LLVM 2.5) is incomplete… now get this error:

toy.cpp:11:38: error: llvm/Target/TargetSelect.h: No such file or directory

How can I get this file?

Regards,

Juan Carlos

Chris Lattner wrote:

FWIW, I'm also suddenly experiencing segfaults in code that used to
work
a few days ago (I'm using svn). This may be unrelated to the problem
described below, but perhaps it's the same thing.

In my case it seems that creating an ExecutionEngine has changed. I
used
to do

   Module* Mod = makeLLVMModule(); // basically create a gcd
function
   verifyModule(*Mod, PrintMessageAction);

   ExecutionEngine *EE;
   EE = ExecutionEngine::create(Mod);

but I now get 0x0 for EE. The compile command I'm using is

g++ -O3 -I ~/llvm/include/ -L ~/llvm bug.cpp `llvm-config --cxxflags
--ldflags --libs core jit native` -o bug

I noticed something very recently changed w.r.t. the way LLVM's
libraries are built (no more .o files). Could this have something to
with it?
    
I *just* changed this. :slight_smile:
  

Hmm, I can see your commits from a few hours ago, but something was
already up a bit earlier. Anyways...

For JIT applications, please include llvm/Target/TargetSelect.h and
call the llvm::InitializeNativeTarget() function before creating an EE.
  

I just svn up-ped to r73620, recompiled and reinstalled LLVM and still
got 0x0 for the execution engine instance.
Found the problem: I didn't include "llvm/ExecutionEngine/JIT.h"

Paul

This only exists on mainline.

-Chris

Hi,

Why are there so many undocumented (and as I far I can see) unnecessary API changes?

Recently there has been:

1.
For JIT applications, please include llvm/Target/TargetSelect.h and
call the llvm::InitializeNativeTarget() function before creating an EE.

2.
The major CHANGE is: the JIT will no longer be safe for executing
threaded applications without first invoking llvm_start_multithreaded(). Please begin to update your client applications now if this affects you, as I will be throwing the switch in SVN sooner rather than later.

3.
The change you should make: every call to addPassesToEmitFile,
addPassesToEmitFileFinish, addPassesToEmitMachineCode, or
addCommonCodeGenPasses should pass an optimization level enum rather
than true / false for "Fast". The enum is in
llvm/Target/TargetMachine.h:

namespace CodeGenOpt {
   enum Level {
     Default,
     None,
     Aggressive
   };
}

4.
The LLVM IR opcodes Add, Sub, and Mul have been each split into two. Add, Sub, and Mul now only handle integer types, and three new opcodes, FAdd, FSub, and FMul now handle floating-point types.

And that's just in a few days!

I recently tried to build my compiler-generator with the svn-head version of llvm.
No chance.
It wouldn't build, thanks to (3) above.
Once I got it to build, it crashed.
It all works just fine with 2.5.

I spent a lot of time and effort, getting things to work, first with 2.4, then with 2.5 (The changes in the API between 2.4 and 2.5 were more than I would have liked, but mainly renaming and caught by the compiler).

Remember, its not just gcc-llvm and clang that use llvm.

So please treat the API with respect.
Don't change it often, and document EACH and EVERY change.

PS.

Change (1) above seems to be pointless.
Why can't the code to create the EE, just call llvm::InitializeNativeTarget()?

Mark.

Chris Lattner wrote:

For JIT applications, please include llvm/Target/TargetSelect.h and
call the llvm::InitializeNativeTarget() function before creating an EE.

Couldn't the EE creation functions do this call automatically if no
target has been set yet, instead of just returning a null pointer? For
the sake of backward compatibility.

Hi Mark,

3.
The change you should make: every call to addPassesToEmitFile,
addPassesToEmitFileFinish, addPassesToEmitMachineCode, or
addCommonCodeGenPasses should pass an optimization level enum rather
than true / false for "Fast". The enum is in
llvm/Target/TargetMachine.h:

namespace CodeGenOpt {
enum Level {
Default,
None,
Aggressive
};
}

We needed a finer-grained control over what optimizations are run
during the code generation passes. Some optimizations aren't
appropriate for the Default case, but are for the Aggressive case.

I can't comment on the other changes. But in general, the llvm
development trunk is in a state of perpetual flux. It only settles
down around release time. Also, our APIs aren't written in stone,
which is by design. The downside of this is that people who use our
APIs may have to change their code from release to release. And if you
live on the development trunk, it takes a lot of maintenance to keep
up (as you found out). We do try to document, or at least warn, about
every change we make. But that documentation tends to be from release
to release.

-bw

No, the whole point of this is to make it trivial for a JIT to link in just the code generator it needs. If the EE depended on all the targets, then all the targets would have to get linked in. This would be bad for code size reasons among other things.

-Chris

Why are there so many undocumented (and as I far I can see) unnecessary
API changes?

They are only seem unnecessary if you don't understand the reason they were made. We don't make change for change's sake :slight_smile:

Recently there has been:

1.
For JIT applications, please include llvm/Target/TargetSelect.h and
call the llvm::InitializeNativeTarget() function before creating an EE.

This fixes long standing linkage problems and helps us move forward with cmake.

2.
The major CHANGE is: the JIT will no longer be safe for executing
threaded applications without first invoking llvm_start_multithreaded().
Please begin to update your client applications now if this affects
you, as I will be throwing the switch in SVN sooner rather than later.

I don't believe that this is true anymore. However, the reason for this series of changes is to make LLVM multithread safe, so that you can have multiple threads JIT'ing at the same time etc.

3.
The change you should make: every call to addPassesToEmitFile,
addPassesToEmitFileFinish, addPassesToEmitMachineCode, or
addCommonCodeGenPasses should pass an optimization level enum rather
than true / false for "Fast". The enum is in
llvm/Target/TargetMachine.h:

This was made to give more control over optimization level.

4.
The LLVM IR opcodes Add, Sub, and Mul have been each split into two.
Add, Sub, and Mul now only handle integer types, and three new opcodes,
FAdd, FSub, and FMul now handle floating-point types.

This is to allow LLVM IR to more accurately model integer overflow, which is very important for loop optimization (particularly on 64-bit platforms).

And that's just in a few days!

LLVM moves quickly :slight_smile:

I spent a lot of time and effort, getting things to work, first with
2.4, then with 2.5 (The changes in the API between 2.4 and 2.5 were more
than I would have liked, but mainly renaming and caught by the compiler).

Remember, its not just gcc-llvm and clang that use llvm.

So please treat the API with respect.
Don't change it often, and document EACH and EVERY change.

You'll notice that llvmdev was notified about all of these changes.

Change (1) above seems to be pointless.
Why can't the code to create the EE, just call
llvm::InitializeNativeTarget()?

Because InitializeNativeTarget() is actually more about linking than initializing. You'll notice that all the targets have empty implementations of this method. However, if you don't call this, the (e.g.) X86 backend won't get linked into your app.

I'm sorry about API changes, but change is an inherent part of making LLVM better. We will aim to document them in the 2.6 release notes.

-Chris

The major CHANGE is: the JIT will no longer be safe for executing
threaded applications without first invoking llvm_start_multithreaded().
Please begin to update your client applications now if this affects
you, as I will be throwing the switch in SVN sooner rather than later.

This one is necessary for the ongoing work to make the LLVM APIs thread-safe. Because of portability issues (mostly concerned with differences between Windows and Unix-like systems), this is the only acceptable way we have found to ensure that the necessary guard structures are allocated and available when they are needed.

Remember, its not just gcc-llvm and clang that use llvm.

So please treat the API with respect.
Don’t change it often, and document EACH and EVERY change.

I’m not sure exactly what you’re getting at here. If anything, I’ve been very impressed in the recent days with the effort people are putting in to announce their API-breaking changes. It’s much improved from the old days of no notice breakage.

The API can and will evolve over time, and we’re making efforts to make it easier for client programs to keep up by announcing API changes, including recipes for how to deal with them, in an obvious manner in advance of the change itself.

–Owen

Chris Lattner <clattner@apple.com> writes:

1.
For JIT applications, please include llvm/Target/TargetSelect.h and
call the llvm::InitializeNativeTarget() function before creating an
EE.

This fixes long standing linkage problems and helps us move forward
with cmake.

Just to clarify: the cmake build was not impeded by this issue at
all. Now we can get rid of some cmake nasty scripts, but the
implementation that managed partially linked objects was already there.

OTOH, as a LLVM user, I think it is a good thing that the partially
linked objects are gone.

[snip]

I'm sorry about API changes, but change is an inherent part of making
LLVM better. We will aim to document them in the 2.6 release notes.

Speaking as a LLVM user, API changes should be thoroughly documented on
the release notes. For instance, just dropping a one-line note
mentioning that certain API changed is not enough. The change itself
shall be described with hints for migrating the existent code, if
needed. Writing a really descriptive note does not require more than a
few minutes for the author, but it may save hours of browsing the
doxygen docs and compile-run-crash cycles to all LLVM users.

The issue about LLVM being on a constant API flux is a more complex
matter that would deserve a full thread by itself.

Hi everyone,

Thanks for reading my rant, the other day :wink:
All your comments were appreciated.

For llvm users (rather than developers) such as myself,
it seems that the best idea is to stick with the major releases.
I will stick with 2.5 until 2.6 arrives.

Has any thought been given to the possibility of bug-fix releases?

Cheers,
Mark.

Yes, many people would like that, but we lack manpower to make extra releases happen.

-Chris

Hi Mark,

Why are there so many undocumented (and as I far I can see) unnecessary API changes?

these can now be documented in docs/ReleaseNotes-2.6.html.

Ciao,

Duncan.