(** Dimension reduction: transform multi-dimensional arrays to one-dimensional arrays, and pass original array dimensions in function calls. *) (** This phase lowers multi-dimensional arrays 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