[LLVMdev] Strange LLVM Crash

Nick Lewycky nicholas at mxc.ca
Sat Mar 14 18:02:18 PDT 2009


Nyx wrote:
> I don't know how to do that. Rather new to LLVM. The functions that get
> stripped out are native C++ functions that I'm registering in my execution
> engine by doing: 

Ah! Given that information I produce this testcase:

   $ cat gdce.ll
   declare i32 @foo()
   $ llvm-as < gdce.ll | opt -globaldce | llvm-dis
   ; ModuleID = '<stdin>'
   $

The globaldce pass eliminates declarations with no definition, even if 
they aren't marked internal. There's your problem.

Should this really be happening? Does global DCE offer other 
optimizations that JIT users would want but without deleting externally 
visible globals? Or should JIT users just not run global DCE?

Nick

> 	
>     // Create a function type object for the function
>     llvm::FunctionType* pFuncType = llvm::FunctionType::get(returnType,
> argTypes, false);
>     
>     // Create a function object with external linkage and the specified
> function type
>     llvm::Function* pFuncObj = llvm::Function::Create(
>     	pFuncType,
>     	llvm::Function::ExternalLinkage,
>     	name,
>     	s_pModule
>     ); 
>     
>     // Add a global mapping in the execution engine for the function pointer
>     s_pExecEngine->addGlobalMapping(pFuncObj, pFuncPtr); 
> 
> Where pFuncPtr is a void pointer to the native C++ function. I register
> several of these native functions which are meant to be runtime support for
> the scripts I then JIT compile. After compiling each script, I run
> optimization passes. If the global DCE one is enabled, it eliminates the
> native functions that were not yet used from the module. Then, if I try to
> compile other scripts that would use the functions that have been
> eliminated, I get a crash.
> 
>>From the LLVM source code, I found the following comment:
> 
> // createGlobalDCEPass - This transform is designed to eliminate unreachable
> // internal globals (functions or global variables)
> 
> So I guess the optmization pass is doing exactly what it was meant to do. I
> disabled it for now since I don't want the native functions to get
> eliminated, and am currently not using any global variables.
> 
> By the way, is there any way to have the pass managers run its passes on a
> single function, instead of a whole module?
> 
> - Maxime
> 
> 
> Nick Lewycky wrote:
>> Nyx wrote:
>>> The linkage type is set to external, I have little code snippet I use to
>>> register those native functions in the first post of this topic. The
>>> global
>>> DCE pass deletes the unused native functions when run. I commented it out
>>> for now...
>> Can you make this happen by writing a custom .ll to demonstrate the 
>> problem? For example:
>>
>>    $ cat gdce.ll
>>    define i32 @foo() {
>>      ret i32 0
>>    }
>>    $ llvm-as < gdce.ll | opt -globaldce | llvm-dis
>>    ; ModuleID = '<stdin>'
>>
>>    define i32 @foo() {
>>            ret i32 0
>>    }
>>
>> If it happens as you say, you should be able to create a .ll where "opt 
>> -globaldce" will eliminate your function.
>>
>> Nick
>>
>>>
>>> Nick Lewycky wrote:
>>>> Nyx wrote:
>>>>> Ok, well, I seem to have pinpointed the cause of the problem more
>>>>> accurately.
>>>>> I'm running some optimization passes on my module after I compile each
>>>>> function in my scripting language (functions can be compiled at various
>>>>> times, when scripts are loaded). Now it seems these optimization passes
>>>>> will
>>>>> prune some of the native C++ functions I'm registering in my module
>>>>> (the
>>>>> functions that haven't been called/used yet). I'd like to find a way to
>>>>> disable this so that all the native functions I register will stay in
>>>>> the
>>>>> module.
>>>> "externally visible" functions should never be deleted. What's the 
>>>> linkage type on your functions? internal? Don't mark things internal 
>>>> unless you don't mind if they go away. :)
>>>>
>>>> Nick
>>>>
>>>>> Here are the optimization passes I'm running:
>>>>>
>>>>> 	passManager.add(new llvm::TargetData(s_pModule));
>>>>> 	passManager.add(llvm::createLowerSetJmpPass());
>>>>> 	passManager.add(llvm::createRaiseAllocationsPass());
>>>>> 	passManager.add(llvm::createCFGSimplificationPass());
>>>>> 	passManager.add(llvm::createPromoteMemoryToRegisterPass());
>>>>> 	passManager.add(llvm::createGlobalOptimizerPass());
>>>>> 	passManager.add(llvm::createGlobalDCEPass());
>>>>> 	passManager.add(llvm::createFunctionInliningPass());
>>>>>
>>>>> I would like to know either which pass does this (global optimizer
>>>>> maybe?)
>>>>> so I can disable it, or what flag I can set on my C++ function objects
>>>>> to
>>>>> keep them from being pruned out.
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>>
>>>>
>> _______________________________________________
>> LLVM Developers mailing list
>> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>>
> 




More information about the llvm-dev mailing list