charles quarra
2013-Apr-02 21:04 UTC
[LLVMdev] cyclical dependence between caller and callee in JIT
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?
Nick Lewycky
2013-Apr-11 00:01 UTC
[LLVMdev] cyclical dependence between caller and callee in JIT
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
Reasonably Related Threads
- [LLVMdev] cyclical use between caller and callee
- [LLVMdev] Fwd: cyclical use between caller and callee
- [LLVMdev] cyclical use between caller and callee
- [LLVMdev] Remove class/struct DenseMapInfo mix
- [LLVMdev] compile error when using overloaded = operator of DenseMap