------- Additional Comments From rakdver at gcc dot gnu dot org 2005-09-20 13:33 ------- k*stridev?[2] cannot be moved more at the moment. The loops looks like
for (k = ...) for (j = ...) { if (i >= i1) continue; do { tmp = k * stridevx[2]; ... } while (i < i1) } Note that if i >= i1, the load of stridevx[2] is never executed. And it is possible that it will trap. Thus, we can only move it to point where we are sure that we do not make it executed unconditionally. I.e. it is legal to move it out of the innermost loop, but not out of the outer ones. There are two optimization improvements that could help (and as this case is fairly common, I will leave this PR open as an enhancement request). The first optimization is predicated invariant motion. I.e. we cannot move stridevx[2] out of the second loop, but we can move the expression (i < i1 ? stridevx[2] : undefined) out of it, and it has the same value in all interesting cases. The second optimization is invariant exit motion. I.e. we can replace do { code1; if (invariant) break; code2; } while (something); with if (invariant) { code1; } else { do { code1; code2; } while (something); } This could be achieved through loop unswitching (for non-innermost loops), or as a separate optimization. Note however that for this optimization to be useful for invariant motion, it would either have to be iterated with it, or, at the expense of significant complications, to be implemented within invariant motion. -- What |Removed |Added ---------------------------------------------------------------------------- Severity|normal |enhancement Status|UNCONFIRMED |NEW Ever Confirmed| |1 Last reconfirmed|0000-00-00 00:00:00 |2005-09-20 13:33:54 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23970