[LLVMdev] cyclical dependence between caller and callee in JIT

Nick Lewycky nicholas at mxc.ca
Wed Apr 10 17:01:28 PDT 2013


charles quarra wrote:
> 2013/3/27 Nick Lewycky<nicholas at mxc.ca>:
>> The common idiom to delete any Value* is:
>>
>> V->replaceAllUsesWith(UndefValue::get(V->getType());
>> V->eraseFromParent();
>>
>> Does that work for functions? You may need to make sure the 'undef' has a
>> pointer to function type instead of the function type.
>>
>
> I tried this code sample, passing the type returned by
> llvm::Function::getType(), but i get this assertion failure:
>
>    %"calling function" = call i32 @X.foo(i32 %read)
> F is used in instruction:
>    %"calling function" = call i32 @X.foo(i32 %read)
> mytests: /home/charlesq/third_party/llvm-3.1.src/include/llvm/ADT/ValueMap.h:220:
> void llvm::ValueMapCallbackVH<KeyT, ValueT,
> Config>::allUsesReplacedWith(llvm::Value*) [with KeyT = const
> llvm::Function*; ValueT = {anonymous}::JITEmitter::EmittedCode; Config
> = {anonymous}::JITEmitter::EmittedFunctionConfig]: Assertion
> `isa<KeySansPointerT>(new_key)&&  "Invalid RAUW on key of ValueMap<>"'
> failed.
>
>
> Apparently, the undefValue is expected to be isa<KeySansPointerT>. Are
> there any examples or references about how to bring such an
> undefValue?

Something else is going on. The problem isn't with your call to 
replaceAllUsesWith per se, the problem is that somebody (I would guess 
the JIT?) is holding it in a ValueMap.

We used to have a problem that some parts of the code would keep a 
mapping like so:
   std::map<Value *, ...>
while somebody else would modify the Value* without them noticing, 
leading to a dangling pointer in the map. To fix that, we invented the 
ValueMap which puts a Use that doesn't show up in the use_iterator on 
the Value it holds. When the Value is erased or RAUW'd, the ValueMap is 
notified and in this case decides that's not okay and terminates the 
program.

Probably what's happened here is that the calling function has had its 
code generated by the JIT, but not the callee. Thus the JIT emitted a 
call to a generated stub, and will do the codegen of the callee once 
that stub is reached. Of course, once the JIT is in this state, it holds 
on to the Function with a ValueMap in order to prevent things from 
getting out of sync.

Nick



More information about the llvm-dev mailing list