|
|
@@ -1 +1,65 @@
|
|
|
+(** Dimension reduction: transform multi-dimensional arrays to one-dimensional
|
|
|
+ arrays, and pass original array dimensions in function calls. *)
|
|
|
+
|
|
|
+(**
|
|
|
+ This phase lowers multi-dimensional ararys to one-dimensional arrays. This
|
|
|
+ transformation is done in two steps.
|
|
|
+
|
|
|
+ In the first step, function calls and function parameter lists are modified.
|
|
|
+ For function calls, array dimensions are passed as explicit arguments before
|
|
|
+ the array argument itself. Naturally, function declarations need to be
|
|
|
+ modified accordingly, adding explicit parameters for array dimensions.
|
|
|
+
|
|
|
+ Note that we need not create new variable declarations for array
|
|
|
+ declarations here. This is already done during the desugaring phase
|
|
|
+ ({!Desug} explains the reason for this).
|
|
|
+
|
|
|
+ In the second step, statements and expressions involving multi-dimensional
|
|
|
+ array referencing are transformed such that they reference a one-dimensional
|
|
|
+ array. Variable declarations with type [ArrayDims] are transformed into
|
|
|
+ variables of type [Array], thus removing the dimensionality information.
|
|
|
+ Allocation statements become one-dimensional allocations with a length that
|
|
|
+ is the product of all array dimensions. Indexing multi-dimensional arrays is
|
|
|
+ changed such that arrays are accessed in row-major order.
|
|
|
+
|
|
|
+{v void foo(int[a, b, c] p) \{
|
|
|
+ int n; int m; int k; int[n, m, k] q; // n, m, k are added during desugaring
|
|
|
+ n = 5;
|
|
|
+ m = 10;
|
|
|
+ k = 3;
|
|
|
+ q = __allocate(n, m, k);
|
|
|
+ q[x, y, z] = p[x, y, z];
|
|
|
+ foo(q);
|
|
|
+\} v}
|
|
|
+
|
|
|
+ step 1:
|
|
|
+
|
|
|
+{v void foo(int a, int b, int c, int[] p) \{ // Array parameter
|
|
|
+ int n; int m; int k; int[n, m, k] q;
|
|
|
+ n = 5;
|
|
|
+ m = 10;
|
|
|
+ k = 3;
|
|
|
+ q = __allocate(n, m, k);
|
|
|
+ q[x, y, z] = p[x, y, z];
|
|
|
+ foo(n, m, k, q); // Array argument
|
|
|
+\} v}
|
|
|
+
|
|
|
+ step 2:
|
|
|
+
|
|
|
+{v void foo(int[a, b, c] p) \{
|
|
|
+ int n; int m; int k; int[] q; // Removing dimension information
|
|
|
+ n = 5;
|
|
|
+ m = 10;
|
|
|
+ k = 3;
|
|
|
+ q = __allocate(n * m * k); // Allocation
|
|
|
+ q[((x * m) + y) * k + z] = p[((x * b) + y) * c + z]; // Indexing
|
|
|
+ foo(n, m, k, q);
|
|
|
+\} v}
|
|
|
+
|
|
|
+ Note that when array dimensions are constant integer values, an array index
|
|
|
+ may be simplified to a single constant value during contant propagation.
|
|
|
+ *)
|
|
|
+
|
|
|
+
|
|
|
+(** Main phase function, called by {!Main}. *)
|
|
|
val phase : Main.phase_func
|