| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- (** Unroll for-loops with constant boundaries. *)
- (** When initializing arrays with scalar values, the desugaring phase creates
- for-loops, that are later transformed into while-loops. This has an effect
- on the stack size, which grows because of the increase in variables. The
- readability of generated code is also affected, since while-loops are very
- verbose. Constant propagation helps somewhat, but the loops still exist.
- This loop unrolling phase recognizes while-loops that are generated from
- for-loops. If the upper bound, lower bound, and step variable of the loop
- are constant integers, the loop is replaced with occurrences of its body for
- each iteration value. Afterwards, the constant propagation traversal is
- executed again to utilise new possibilities for constant folding, which are
- generated by replacing the loop counter variable with a constant value. An
- example follows:
- {v void foo() \{
- int[2, 3] arr = 1;
- \} v}
- After desugaring and constant propagation, this has been transformed into:
- {v void foo() \{
- int _i_6;
- int _i_9;
- int[] arr;
- arr = __allocate(6);
- _i_6 = 0;
- while ((_i_6 < 2)) \{
- _i_9 = 0;
- while ((_i_9 < 3)) \{
- arr[((_i_6 * 3) + _i_9)] = 1;
- _i_9 = (_i_9 + 1);
- \}
- _i_6 = (_i_6 + 1);
- \}
- \} v}
- Now, the loops are unrolled (first the inner loop, then the outer loop) and
- constant folding is applied to [arr[((_i_6 * 3) + _i_9)]] in each
- iteration:
- {v void foo() \{
- int[] arr;
- arr = __allocate(6);
- arr[0] = 1;
- arr[1] = 1;
- arr[2] = 1;
- arr[3] = 1;
- arr[4] = 1;
- arr[5] = 1;
- \} v}
- A simple heuristic is applied to decide whether a recognised for-loop will
- be unrolled: the resulting number of statements must not be larger than 25.
- Note that since programmer-defined for-loops are also transformed into
- while-loops, these are recognized by the compiler as well (as long as the
- loop has constant boundaries). For example:
- {v extern void printInt(int val);
- export int main() \{
- for (int i = 0, 10, 2) \{
- printInt(i);
- \}
- return 0;
- \} v}
- which is transformed into:
- {v extern void printInt(int val);
- export int main() \{
- printInt(0);
- printInt(2);
- printInt(4);
- printInt(6);
- printInt(8);
- return 0;
- \} v}
- *)
- (** Main phase function, called by {!Main}. *)
- val phase : Main.phase_func
|