On Apr 14, 2009, at 1:49 PM, Luke Dalessandro wrote:> > On Apr 14, 2009, at 12:48 PM, Brice Lin wrote: > >> I just read the LLVM Programmer's Manual, which mentions (but >> specifically does not include any details of) the InstVisitor >> template. Could someone please provide an example of how to use this >> template to find (as an example) all CallSites for the function >> strcpy? > > If this is really what you want to do, then the easiest method is to > just get the declaration of the strcpy function, and iterate over its > uses.I guess I should note that the "use iteration" will only work for direct calls. If you are concerned with indirect calls you need an alias analysis or call graph or some such thing. There are lots of ways to deal with this. Also, you might need to be smarter about the Instruction check if you expect ConstantExpr casts or any other such use of the declaration. Luke> > > Function* const strcpy = m.getFunction("strcpy"); > for (Value::use_iterator i = strcpy->use_begin(), e = strcpy- >> use_end(); i != e; ++i) > if (Instruction* const use = dyn_cast<Instruction>(i)) { > // Do what you need here > CallSite call(use); > ... > } > > If you want to know how to use InstVisitor for other purposes, you > just derive a class from the InstVisitor template, and overload the > visit routines that you want. > > class StrcpyVisitor : public InstVisitor<StrcpyVisitor> { > void handleStrcpy(CallSite strcpy); > string strcpyName; > public: > void visitCallInst(CallInst& call) { > if (call.getName() == strcpyName) > handleStrcpy(&call); > } > void visitInvokeInst(InvokeInst& invoke) { > if (call.getName() == strcpyName) > handleStrcpy(&invoke); > } > }; > > Then, you probably want to inherit from ModulePass, or FunctionPass, > or BasicBlockPass, or whatever makes sense, and in the relevant > runOnX(X& x) callback you say: > > bool runOnX(X& x) { > visit(x); > return true/false/something_computed; > } > > Hope this helps, > Luke > >> >> >> Thanks, >> Brice Lin >> _______________________________________________ >> 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
Thanks for providing me with those examples. My rather inefficient pass, which inherits from ModulePass, currently iterates through the Module, Functions, and BasicBlocks multiple times (once to find strcpy, another to find strcat, and so on for various other functions). If I only care about the direct calls, would I benefit more from switching to multiple use_iterators or the InstVisitor template? - Brice On Tue, Apr 14, 2009 at 1:13 PM, Luke Dalessandro <luked at cs.rochester.edu> wrote:> > On Apr 14, 2009, at 1:49 PM, Luke Dalessandro wrote: > > I guess I should note that the "use iteration" will only work for > direct calls. If you are concerned with indirect calls you need an > alias analysis or call graph or some such thing. There are lots of > ways to deal with this. > > Also, you might need to be smarter about the Instruction check if you > expect ConstantExpr casts or any other such use of the declaration. > > Luke > >> >> >> Function* const strcpy = m.getFunction("strcpy"); >> for (Value::use_iterator i = strcpy->use_begin(), e = strcpy- >>> use_end(); i != e; ++i) >> if (Instruction* const use = dyn_cast<Instruction>(i)) { >> // Do what you need here >> CallSite call(use); >> ... >> } >> >> If you want to know how to use InstVisitor for other purposes, you >> just derive a class from the InstVisitor template, and overload the >> visit routines that you want. >> >> class StrcpyVisitor : public InstVisitor<StrcpyVisitor> { >> void handleStrcpy(CallSite strcpy); >> string strcpyName; >> public: >> void visitCallInst(CallInst& call) { >> if (call.getName() == strcpyName) >> handleStrcpy(&call); >> } >> void visitInvokeInst(InvokeInst& invoke) { >> if (call.getName() == strcpyName) >> handleStrcpy(&invoke); >> } >> }; >> >> Then, you probably want to inherit from ModulePass, or FunctionPass, >> or BasicBlockPass, or whatever makes sense, and in the relevant >> runOnX(X& x) callback you say: >> >> bool runOnX(X& x) { >> visit(x); >> return true/false/something_computed; >> } >> >> Hope this helps, >> Luke
Brice, As Luke said, you can find all *uses* of the function name 'strcpy' by iterating over all the uses. If you just need to replace one function with another one without changing the arguments being passed, that is enough even for indirect calls (within the code being compiled, not external code) because you will find all the places where the function address is taken. If you want to modify the arguments being passed, you need to find the actual call sites, which requires the call graph (include/Analysis/ CallGraph.h). --Vikram Associate Professor, Computer Science University of Illinois at Urbana-Champaign http://llvm.org/~vadve On Apr 14, 2009, at 1:13 PM, Luke Dalessandro wrote:> > On Apr 14, 2009, at 1:49 PM, Luke Dalessandro wrote: > >> >> On Apr 14, 2009, at 12:48 PM, Brice Lin wrote: >> >>> I just read the LLVM Programmer's Manual, which mentions (but >>> specifically does not include any details of) the InstVisitor >>> template. Could someone please provide an example of how to use this >>> template to find (as an example) all CallSites for the function >>> strcpy? >> >> If this is really what you want to do, then the easiest method is to >> just get the declaration of the strcpy function, and iterate over its >> uses. > > I guess I should note that the "use iteration" will only work for > direct calls. If you are concerned with indirect calls you need an > alias analysis or call graph or some such thing. There are lots of > ways to deal with this. > > Also, you might need to be smarter about the Instruction check if you > expect ConstantExpr casts or any other such use of the declaration. > > Luke > >> >> >> Function* const strcpy = m.getFunction("strcpy"); >> for (Value::use_iterator i = strcpy->use_begin(), e = strcpy- >>> use_end(); i != e; ++i) >> if (Instruction* const use = dyn_cast<Instruction>(i)) { >> // Do what you need here >> CallSite call(use); >> ... >> } >> >> If you want to know how to use InstVisitor for other purposes, you >> just derive a class from the InstVisitor template, and overload the >> visit routines that you want. >> >> class StrcpyVisitor : public InstVisitor<StrcpyVisitor> { >> void handleStrcpy(CallSite strcpy); >> string strcpyName; >> public: >> void visitCallInst(CallInst& call) { >> if (call.getName() == strcpyName) >> handleStrcpy(&call); >> } >> void visitInvokeInst(InvokeInst& invoke) { >> if (call.getName() == strcpyName) >> handleStrcpy(&invoke); >> } >> }; >> >> Then, you probably want to inherit from ModulePass, or FunctionPass, >> or BasicBlockPass, or whatever makes sense, and in the relevant >> runOnX(X& x) callback you say: >> >> bool runOnX(X& x) { >> visit(x); >> return true/false/something_computed; >> } >> >> Hope this helps, >> Luke >> >>> >>> >>> Thanks, >>> Brice Lin >>> _______________________________________________ >>> 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 > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Brice Lin wrote:> Thanks for providing me with those examples. My rather inefficient > pass, which inherits from ModulePass, currently iterates through the > Module, Functions, and BasicBlocks multiple times (once to find > strcpy, another to find strcat, and so on for various other > functions). If I only care about the direct calls, would I benefit > more from switching to multiple use_iterators or the InstVisitor > template?I think use_iterators are probably the best for you if that's all you want. It is the most efficient because you only touch the actual users of each function, and it leads to really clear code. On the other hand, it works best in a ModulePass setting. If you want something for a smaller granularity the InstVisitor is probably as good a choice, as your runOnX function just ends up calling visit(x). Luke> > - Brice > > On Tue, Apr 14, 2009 at 1:13 PM, Luke Dalessandro > <luked at cs.rochester.edu> wrote: >> On Apr 14, 2009, at 1:49 PM, Luke Dalessandro wrote: >> >> I guess I should note that the "use iteration" will only work for >> direct calls. If you are concerned with indirect calls you need an >> alias analysis or call graph or some such thing. There are lots of >> ways to deal with this. >> >> Also, you might need to be smarter about the Instruction check if you >> expect ConstantExpr casts or any other such use of the declaration. >> >> Luke >> >>> >>> Function* const strcpy = m.getFunction("strcpy"); >>> for (Value::use_iterator i = strcpy->use_begin(), e = strcpy- >>>> use_end(); i != e; ++i) >>> if (Instruction* const use = dyn_cast<Instruction>(i)) { >>> // Do what you need here >>> CallSite call(use); >>> ... >>> } >>> >>> If you want to know how to use InstVisitor for other purposes, you >>> just derive a class from the InstVisitor template, and overload the >>> visit routines that you want. >>> >>> class StrcpyVisitor : public InstVisitor<StrcpyVisitor> { >>> void handleStrcpy(CallSite strcpy); >>> string strcpyName; >>> public: >>> void visitCallInst(CallInst& call) { >>> if (call.getName() == strcpyName) >>> handleStrcpy(&call); >>> } >>> void visitInvokeInst(InvokeInst& invoke) { >>> if (call.getName() == strcpyName) >>> handleStrcpy(&invoke); >>> } >>> }; >>> >>> Then, you probably want to inherit from ModulePass, or FunctionPass, >>> or BasicBlockPass, or whatever makes sense, and in the relevant >>> runOnX(X& x) callback you say: >>> >>> bool runOnX(X& x) { >>> visit(x); >>> return true/false/something_computed; >>> } >>> >>> Hope this helps, >>> Luke > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev