Hi, I am working on a pass to convert lib calls to intrinsic calls as discussed here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058507.html In my first attempt I created a FunctionPass that uses CallInst::setCalledFunction to replace the callee with the appropriate intrinsic (using Intrinsic::getDeclaration). After the pass runs I get an assertion from CallGraphSCCPass: clang-3.3: /home/predmond/src/ssg_llvm/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:338: bool {anonymous}::CGPassManager::RefreshCallGraph(llvm::CallGraphSCC&, llvm::CallGraph&, bool): Assertion `CallSites.empty() && "Dangling pointers found in call sites map"' failed. My guess is that I'm modifying the module illegally in a FunctionPass and things break. I see a similar approach used in InstCombineCall however the difference is setCalledFunction is used to replace one intrinsic with another. The obvious fix (which works) is to use a ModulePass but I'm wondering if there's a way to make this work with a FunctionPass. paul
Hi Paul,> I am working on a pass to convert lib calls to intrinsic calls as discussed here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058507.htmlthis whole area is a little confusing. If you can recognize a libcall as being equivalent to an intrinsic, you could indeed turn it into an intrinsic, but on the other hand you could just directly do on it the IR transforms you want to do on the builtin. At the IR level turning it into an intrinsic doesn't buy you much. If it's not buying you anything, why do it? On the other hand, you might then wonder why the intrinsics exist at all. One answer is that you can use the intrinsics with vectors, which isn't usually the case with the libcall versions. At the codegen level things are a bit different. If a libcall can be correctly turned into a target processor instruction, then at some point that conversion has to happen. Thus the recognition of certain libcalls, and their conversion into a SDNode. Ciao, Duncan.> > In my first attempt I created a FunctionPass that uses CallInst::setCalledFunction to replace the callee with the appropriate intrinsic (using Intrinsic::getDeclaration). > > After the pass runs I get an assertion from CallGraphSCCPass: > > clang-3.3: /home/predmond/src/ssg_llvm/llvm/lib/Analysis/IPA/CallGraphSCCPass.cpp:338: bool {anonymous}::CGPassManager::RefreshCallGraph(llvm::CallGraphSCC&, llvm::CallGraph&, bool): Assertion `CallSites.empty() && "Dangling pointers found in call sites map"' failed. > > My guess is that I'm modifying the module illegally in a FunctionPass and things break. I see a similar approach used in InstCombineCall however the difference is setCalledFunction is used to replace one intrinsic with another. > > The obvious fix (which works) is to use a ModulePass but I'm wondering if there's a way to make this work with a FunctionPass. > > paul > > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Hi Duncan, On 2013-01-24, at 4:23 PM, Duncan Sands wrote:> Hi Paul, > >> I am working on a pass to convert lib calls to intrinsic calls as discussed here: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058507.html > > this whole area is a little confusing. If you can recognize a libcall as > being equivalent to an intrinsic, you could indeed turn it into an intrinsic, > but on the other hand you could just directly do on it the IR transforms you > want to do on the builtin. At the IR level turning it into an intrinsic doesn't > buy you much. If it's not buying you anything, why do it? On the other hand, > you might then wonder why the intrinsics exist at all. One answer is that you > can use the intrinsics with vectors, which isn't usually the case with the > libcall versions. >The nice thing about the intrinsic forms is that you don't need to consider multiple types. For example the loop vectorizer can vectorize sin intrinsics for any float type. To support sinf, sin, sinl you would have to have a case for each. Another example can be found in the list of TODOs at the bottom of SimplifyLibCalls.cpp. Most of those transformation could be implemented with InstCombine rules to handle all types if given intrinsics. I'm certainly open to any feedback or suggestions. paul> At the codegen level things are a bit different. If a libcall can be correctly > turned into a target processor instruction, then at some point that conversion > has to happen. Thus the recognition of certain libcalls, and their conversion > into a SDNode. > > Ciao, Duncan.