ExecutionEngine blew the stack ?

Segfault in EE->getPointerToFunction.
I think it's blown the stack, gdb reports a never ending backtrace (below).

I generate llvm assembly and parse/verify OK.
Attached is the assembly. It is the smallest example
generated that causes the segfault.

If this EE uses a recursive function (??), it seems an inherent limitation
in how big llvm functions can be.

Simon.

gdb backtrace:
#0 0x40b126a3 in (anonymous namespace)::X86DAGToDAGISel::Select_store(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf800a10, N={Val = 0x8254338, ResNo = 0}) at X86GenDAGISel.inc:19768
#1 0x40b01b44 in (anonymous namespace)::X86DAGToDAGISel::SelectCode(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf800a10, N={Val = 0x8254338, ResNo = 0}) at X86GenDAGISel.inc:27833
#2 0x40ada64f in (anonymous namespace)::X86DAGToDAGISel::Select(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf800a10, N={Val = 0x8254338, ResNo = 0}) at X86ISelDAGToDAG.cpp:835
#3 0x40b00bb4 in (anonymous namespace)::X86DAGToDAGISel::SelectCode(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf800d28, N={Val = 0x8254458, ResNo = 0}) at X86GenDAGISel.inc:27686
#4 0x40ada64f in (anonymous namespace)::X86DAGToDAGISel::Select(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf800d28, N={Val = 0x8254458, ResNo = 0}) at X86ISelDAGToDAG.cpp:835
#5 0x40b9886e in (anonymous namespace)::X86DAGToDAGISel::Select_X86call(llvm::SDOperand&, llvm::SDOperand) (
    this=0x822d660, Result=@0xbf801098, N={Val = 0x82544d0, ResNo = 0}) at X86GenDAGISel.inc:658
#6 0x40b01391 in (anonymous namespace)::X86DAGToDAGISel::SelectCode(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf801098, N={Val = 0x82544d0, ResNo = 0}) at X86GenDAGISel.inc:27760
#7 0x40ada64f in (anonymous namespace)::X86DAGToDAGISel::Select(llvm::SDOperand&, llvm::SDOperand) (this=0x822d660,
    Result=@0xbf801098, N={Val = 0x82544d0, ResNo = 0}) at X86ISelDAGToDAG.cpp:835

etc....

dump.ll (66.4 KB)

Hi Simon,

You're probably right. LLVM's instruction selector is recursive so it can run out of stack space. Select_store used to have enormous stack frame (thanks to some gcc issues), we had to do all kinds of tricks to get it under control. I just took a look at it, it's around 0.7k. It used to be around 20k on x86 Mac OS X.

It's also possible that it has gotten into a real infinite loop. I'll take a look at it tomorrow.

Could you increase the stack limit on your system and see if that works around this problem?

Cheers,

Evan

It works fine on smaller problem sizes, so I don't think it is a problem
with the EE's control flow.

I don't know how to increase the stack limit. And even if I did
I would just want to run it on bigger problems..

But it should be documented somewhere that this is a limitation.
And/or, some kind of runtime check that each basic block/function
is not too big (maybe that's too hard to check).

In my case the function is eminantly decomposable into subfuctions so it
looks like that's the correct way to handle this.

This leads me to my next question: as I make more and more functions
with the EE, it slows down. I am re-using the Module, ExistingModuleProvider,
and ExecutionEngine, and pumping the parser like so:
   M = ParseAssemblyString(AsmString, M);

ISTM that there should be a way of creating multiple modules/EEs but I ran
into trouble when I tried that (some time ago).

Is there a way around this ? I'm looking for scalability.

Simon.

Can you quantify what you mean? How does it "slow down"?

-Chris

It slows in the construction phase, so one of these calls:
   M = ParseAssemblyString(AsmString, M);
   verifyModule( *M )
   M->getNamedFunction(name);
   EE->getPointerToFunction

It feels like there is a linear name lookup going on somewhere.

(will be able to do report more thorough timings later)

Simon.

it's verifyModule (of course). As the module grows, it takes longer
to verify. So, I will disable this for now.

Simon.

Alernatively, you could just verify the functions that are newly loaded, so that you are verifying linear amounts of code instead of N^2.

-Chris