You are entirely correct, I hadn't thought that through enough. So I backtracked and have just merged what Bingfeng Mei has done with your code and have now a corrected version of the loop unrolling.
What I did was directly modified tree_unroll_loop to handle the case of a perfect unroll or not internally and then used something similar to what you had done around that. I added what I think is needed to stop unrolling of those loops in later passes. I'll be starting my tests but I can port it to 4.5 if you are interested to see what I did. Jc On Thu, Oct 15, 2009 at 6:00 AM, Zdenek Dvorak <rakd...@kam.mff.cuni.cz> wrote: > Hi, > >> I faced a similar issue a while ago. I filed a bug report >> (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36712) In the end, >> I implemented a simple tree-level unrolling pass in our port >> which uses all the existing infrastructure. It works quite well for >> our purpose, but I hesitated to submit the patch because it contains >> our not-very-elegannt #prgama unroll implementation. > > could you please do so anyway? Even if there are some issues with the > #prgama unroll implementation, it could serve as a basis of a usable > patch. > >> /* Perfect unrolling of a loop */ >> static void tree_unroll_perfect_loop (struct loop *loop, unsigned factor, >> edge exit) >> { >> ... >> } >> >> >> >> /* Go through all the loops: >> 1. Determine unrolling factor >> 2. Unroll loops in different conditions >> -- perfect loop: no extra copy of original loop >> -- other loops: the original version of loops to execute the >> remaining iterations >> */ >> static unsigned int rest_of_tree_unroll (void) >> { > ... >> tree niters = number_of_exit_cond_executions(loop); >> >> bool perfect_unrolling = false; >> if(niters != NULL_TREE && niters!= chrec_dont_know && >> TREE_CODE(niters) == INTEGER_CST){ >> int num_iters = tree_low_cst(niters, 1); >> if((num_iters % unroll_factor) == 0) >> perfect_unrolling = true; >> } >> >> /* If no. of iterations can be divided by unrolling factor, we have >> perfect unrolling */ >> if(perfect_unrolling){ >> tree_unroll_perfect_loop(loop, unroll_factor, >> single_dom_exit(loop)); >> } >> else{ >> tree_unroll_loop (loop, unroll_factor, single_dom_exit (loop), >> &desc); >> } > > It would be better to move this test to tree_unroll_loop, and not > duplicate its code in tree_unroll_perfect_loop. > > Zdenek >