[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