Hi, As a follow up of this thread I've made a patch that implements a simple approach to propagate the function return values as described previously. It can transform e.g. the following program: define i32 @f(...) nounwind { (...) %cond = select i1 %tobool, i32 2, i32 3 ; <i32> [#uses=1] ret i32 %cond } define i32 @g(...) nounwind { entry: %call = call i32 (...)* @f() ; <i32> [#uses=1] switch i32 %call, label %sw.default [ i32 5, label %sw.bb i32 2, label %sw.bb1 i32 3, label %sw.bb2 ] sw.bb: ; preds = %entry ret i32 -1 sw.bb1: ; preds = %entry ret i32 3 sw.bb2: ; preds = %entry ret i32 55 sw.default: ; preds = %entry ret i32 0 } into: define i32 @g(...) nounwind { entry: %call = call i32 (...)* @f() ; <i32> [#uses=1] %cond = icmp eq i32 %call, 2 ; <i1> [#uses=1] %retval = select i1 %cond, i32 3, i32 55 ; <i32> [#uses=1] ret i32 %retval } This kind of transformation isn't currently done by LLVM (note that here this pass is only removing case statements. other transformations are not of my responsibility :). The patch is available at http://web.ist.utl.pt/nuno.lopes/llvm_function_ret_infer.txt I would love to ear some feedback, so that this pass can eventually be merged to the LLVM tree. In particular I'm not sure if there's a better way to track the possible return values of each function (e.g. is there any code that I can reuse?) Thanks, Nuno
On Tue, Sep 16, 2008 at 1:59 PM, Nuno Lopes <nunoplopes at sapo.pt> wrote:> Hi, > This kind of transformation isn't currently done by LLVM (note that here > this pass is only removing case statements. other transformations are not of > my responsibility :). > The patch is available at > http://web.ist.utl.pt/nuno.lopes/llvm_function_ret_infer.txt > I would love to ear some feedback, so that this pass can eventually be > merged to the LLVM tree. In particular I'm not sure if there's a better way > to track the possible return values of each function (e.g. is there any code > that I can reuse?)AnalyzeFunction can use BB->getTerminator() rather than iterating over all instructions to find the terminator. After you Analyze all the functions, why not just iterator on the uses of the functions you found you could transform rather than on ever instruction in the module? It seems you should be able to handle any comparison with a constant by using the min or max of your set as appropriate to the cmp. Andrew
> On Tue, Sep 16, 2008 at 1:59 PM, Nuno Lopes <nunoplopes at sapo.pt> wrote: >> Hi, >> This kind of transformation isn't currently done by LLVM (note that here >> this pass is only removing case statements. other transformations are not >> of >> my responsibility :). >> The patch is available at >> http://web.ist.utl.pt/nuno.lopes/llvm_function_ret_infer.txt >> I would love to ear some feedback, so that this pass can eventually be >> merged to the LLVM tree. In particular I'm not sure if there's a better >> way >> to track the possible return values of each function (e.g. is there any >> code >> that I can reuse?) > > AnalyzeFunction can use BB->getTerminator() rather than iterating over > all instructions to find the terminator. > > After you Analyze all the functions, why not just iterator on the uses > of the functions you found you could transform rather than on ever > instruction in the module? > > It seems you should be able to handle any comparison with a constant > by using the min or max of your set as appropriate to the cmp.Hi, Thank you for your review. I've updated the patch to reflect your suggestions. I've also completed the ICmp instruction folding. Regards, Nuno