LLVM optimization passes crash when running on second thread

Hello,

I am trying to modify my LLVM-based compiler to perform an initial, no-optimization compilation synchronously on startup and then perform an asynchronous, optimized recompilation in the background, and I am getting in one of the optimization passes.

- I am using the official release of LLVM 2.8
- I have compiled LLVM with threading enabled; I am running llvm::llvm_start_multithreaded() on application startup and checking that that result is true.
- The foreground compilation works fine.
- The background compilation also works fine if I comment out the addition of the optimization passes.
- The optimization passes are being added as follows:
        llvm::OwningPtr<llvm::PassManager> passManager( new llvm::PassManager );
        if ( optimize )
        {
          llvm::createStandardFunctionPasses( passManager.get(), 2 );
          llvm::createStandardModulePasses( passManager.get(), 2, false, true, true, true, false, llvm::createFunctionInliningPass() );
          llvm::createStandardLTOPasses( passManager.get(), true, true, false );
        }
        passManager->run( *module );
- If I *don't* comment out the optimization passes (inside the if statement above) LLVM crashes with what appears to be a stack overflow; I've attached the stack trace below.
- The code above is in the Fabric::DG::Code::compileAST() function shown in the stack trace below; its child in the stack is the passManager->run() call.
- I have added a global mutex lock around all my accesses to LLVM, just to try to debug the problem, and it doesn't make any difference.
- Both compilations are using the same LLVMContext. It is unclear from the LLVM docs whether this is allowed. I would be surprised, however, if the global lock I added wouldn't have sorted out that issue if it was the problem.
- In case it makes any difference, I am running on OS X and using Grand Central Dispatch to execute the background compilation using dispatch_group_async_f()

Is this a known problem? Can anyone suggest anything I can do to fix or further debug this problem?

Thanks in advance,
Peter Zion

#0 0x965221a6 in szone_malloc_should_clear ()
#1 0x00916795 in ChromeMain ()
#2 0x96522148 in malloc_zone_malloc ()
#3 0x96520218 in malloc ()
#4 0x953da617 in operator new ()
#5 0x169f5872 in std::_Rb_tree<llvm::AssertingVH<llvm::BasicBlock>, std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal>, std::_Select1st<std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal> >, std::less<llvm::AssertingVH<llvm::BasicBlock> >, std::allocator<std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal> > >::_M_insert () at ctype.h:275
#6 0x169f5a5a in std::_Rb_tree<llvm::AssertingVH<llvm::BasicBlock>, std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal>, std::_Select1st<std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal> >, std::less<llvm::AssertingVH<llvm::BasicBlock> >, std::allocator<std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal> > >::_M_insert_unique () at ctype.h:275
#7 0x169f5bfd in std::map<llvm::AssertingVH<llvm::BasicBlock>, (anonymous namespace)::LVILatticeVal, std::less<llvm::AssertingVH<llvm::BasicBlock> >, std::allocator<std::pair<llvm::AssertingVH<llvm::BasicBlock> const, (anonymous namespace)::LVILatticeVal> > >::operator[] () at ctype.h:275
#8 0x169f9661 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#9 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#10 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#11 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
...
#657 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#658 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#659 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#660 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#661 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#662 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#663 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#664 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#665 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#666 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#667 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#668 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#669 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#670 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#671 0x169fc2da in (anonymous namespace)::LVIQuery::getEdgeValue () at ctype.h:275
#672 0x169f9a25 in (anonymous namespace)::LVIQuery::getBlockValue () at ctype.h:275
#673 0x169fb6ee in (anonymous namespace)::LazyValueInfoCache::getValueInBlock () at ctype.h:275
#674 0x169fbf64 in llvm::LazyValueInfo::getConstant () at ctype.h:275
#675 0x168dcc70 in (anonymous namespace)::CorrelatedValuePropagation::runOnFunction () at ctype.h:275
#676 0x16b626b5 in llvm::FPPassManager::runOnFunction () at ctype.h:275
#677 0x169c32ce in (anonymous namespace)::CGPassManager::runOnModule () at ctype.h:275
#678 0x16b63cae in llvm::MPPassManager::runOnModule () at ctype.h:275
#679 0x16b63f32 in llvm::PassManagerImpl::run () at ctype.h:275
#680 0x16b63fcb in llvm::PassManager::run () at ctype.h:275
#681 0x162ba04c in Fabric::DG::Code::compileAST (this=0x1b0cfba0, optimize=true) at build/osx/debug/Fabric/DG/Code.cpp:118
#682 0x162bc86d in Fabric::DG::Code::CompileOptimizedAST (userdata=0x1b0cfba0) at Code.h:74
#683 0x96544271 in _dispatch_worker_thread2 ()
#684 0x96543d21 in _pthread_wqthread ()
#685 0x96543b66 in start_wqthread ()
(gdb) Handling SIGTERM in renderer.
Wrote signal to shutdown pipe.

My best guess is that your background thread has less stack space than
the main thread. The version of LazyValueInfo which is in 2.8 was
recursive, and can use a lot of stack space in extreme cases (this was
fixed for 2.9, which should be released soon). If you need to use
2.8, I would suggest either allocating more stack space, or
customizing the passes you use not to include -jump-threading and
-correlated-propagation.

-Eli

That was exactly the problem, thank you!

pz