| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- (** Rudimentary constant propagation and constant folding on generated
- variables. *)
- (** The compiler sometimes generates variables of the form [foo$$1], to make
- sure that expressions are only executed once. In many cases, this leads to
- over-complex constructions with more variable definitions den necessary, for
- example when converting for-loops to while-loops. We use the knowledge of
- these variables being only assigned once, by propagating the constant values
- to their occurrences, and then apply arithmetic simplification to operators
- to reduce the size and complexity of the generated code. Note that this can
- only be applied to constants. For variables in general, some form of
- liveness analysis would be required (e.g. first convert to Static Single
- Assignment form). Expressions can only be propagated when they have no side
- effects, i.e. when they do not contain function calls. The current
- implementation only propagates [Bool|Int|Float] constants and simple
- variable uses ([VarUse]).
- Constant propagation is merged with some some arithmetic simplification here,
- specifically targeting optimization oppertunities created bij earlier
- constant propagation. This is utilized, for example, in array index
- calculation when array dimensions are constant.
- The following example demonstrates the effectivity of this phase. An array
- assignment is transformed into a for-loop, which is transformed into a
- while-loop. Note that the condition of the while-loop body is also
- simplified.
- {v void foo() \{
- int[2, 2] arr = [[1, 2], 3];
- \} v}
- After desugaring and array dimension reduction this becomes:
- {v void foo() \{
- int i$4$5;
- int stop$$6;
- int step$$7;
- int arr$dim$$1;
- int arr$dim$$2;
- int const$$1;
- int const$$2;
- int const$$3;
- int[] arr;
- arr$dim$$1 = 2;
- arr$dim$$2 = 2;
- const$$1 = 1;
- const$$2 = 2;
- const$$3 = 3;
- arr = __allocate((arr$dim$$1 * arr$dim$$2));
- arr[((0 * arr$dim$$2) + 0)] = const$$1;
- arr[((0 * arr$dim$$2) + 1)] = const$$2;
- i$4$5 = 0;
- stop$$6 = arr$dim$$2;
- step$$7 = 1;
- while (((step$$7 > 0) ? (i$4$5 < stop$$6) : (i$4$5 > stop$$6))) \{
- arr[((1 * arr$dim$$2) + i$4$5)] = const$$3;
- i$4$5 = (i$4$5 + step$$7);
- \}
- \} v}
- Constant propagation reduces this to:
- {v void foo() \{
- int i$4$5;
- int[] arr;
- arr = __allocate(4);
- arr[0] = 1;
- arr[1] = 2;
- i$4$5 = 0;
- while ((i$4$5 < 2)) \{
- arr[(2 + i$4$5)] = 3;
- i$4$5 = (i$4$5 + 1);
- \}
- \} v}
- *)
- (** Constant propagation traversal. Exported for use in {!Unroll}. *)
- val propagate_consts : Types.node -> Types.node
- (** Main phase function, called by {!Main}. Calls {!propagate_consts}. *)
- val phase : Main.phase_func
|