aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backend/CSE3analysis.v38
-rw-r--r--backend/CSE3analysisaux.ml57
-rw-r--r--backend/CSE3analysisproof.v53
-rw-r--r--driver/Clflags.ml2
-rw-r--r--driver/Compopts.v3
-rw-r--r--driver/Driver.ml2
-rw-r--r--test/monniaux/loop_nest/polybench.h202
-rw-r--r--test/monniaux/loop_nest/syrk.h54
8 files changed, 370 insertions, 41 deletions
diff --git a/backend/CSE3analysis.v b/backend/CSE3analysis.v
index 7316c9a9..cd7e3d84 100644
--- a/backend/CSE3analysis.v
+++ b/backend/CSE3analysis.v
@@ -282,12 +282,14 @@ Section OPERATIONS.
Definition oper2 (dst : reg) (op: sym_op)(args : list reg)
(rel : RELATION.t) : RELATION.t :=
- let rel' := kill_reg dst rel in
match eq_find {| eq_lhs := dst;
eq_op := op;
eq_args:= args |} with
- | Some id => PSet.add id rel'
- | None => rel'
+ | Some id =>
+ if PSet.contains rel id
+ then rel
+ else PSet.add id (kill_reg dst rel)
+ | None => kill_reg dst rel
end.
Definition oper1 (dst : reg) (op: sym_op) (args : list reg)
@@ -307,12 +309,6 @@ Section OPERATIONS.
| Some eq_id => PSet.add eq_id (kill_reg dst rel)
| None => kill_reg dst rel
end.
-
- Definition is_trivial_sym_op sop :=
- match sop with
- | SOp op => is_trivial_op op
- | SLoad _ _ => false
- end.
Definition oper (dst : reg) (op: sym_op) (args : list reg)
(rel : RELATION.t) : RELATION.t :=
@@ -324,18 +320,18 @@ Section OPERATIONS.
| _ => kill_reg dst rel
end
else
- if is_trivial_sym_op op
- then kill_reg dst rel
- else
- let args' := forward_move_l rel args in
- match rhs_find op args' rel with
- | Some r =>
- if Compopts.optim_CSE3_glb tt
- then RELATION.glb (move r dst rel)
- (oper1 dst op args' rel)
- else oper1 dst op args' rel
- | None => oper1 dst op args' rel
- end.
+ let args' := forward_move_l rel args in
+ match rhs_find op args' rel with
+ | Some r =>
+ if Compopts.optim_CSE3_glb tt
+ then RELATION.glb (move r dst rel)
+ (RELATION.glb (oper1 dst op args' rel)
+ (oper1 dst op args rel))
+ else RELATION.glb (oper1 dst op args' rel)
+ (oper1 dst op args rel)
+ | None => RELATION.glb (oper1 dst op args' rel)
+ (oper1 dst op args rel)
+ end.
Definition clever_kill_store
(chunk : memory_chunk) (addr: addressing) (args : list reg)
diff --git a/backend/CSE3analysisaux.ml b/backend/CSE3analysisaux.ml
index 3990b765..8c83dc2e 100644
--- a/backend/CSE3analysisaux.ml
+++ b/backend/CSE3analysisaux.ml
@@ -39,12 +39,12 @@ let print_reg channel i =
let print_eq channel (lhs, sop, args) =
match sop with
| SOp op ->
- Printf.printf "%a = %a\n" print_reg lhs (PrintOp.print_operation print_reg) (op, args)
+ Printf.printf "%a = %a" print_reg lhs (PrintOp.print_operation print_reg) (op, args)
| SLoad(chunk, addr) ->
- Printf.printf "%a = %s @ %a\n" print_reg lhs (string_of_chunk chunk)
+ Printf.printf "%a = %s @ %a" print_reg lhs (string_of_chunk chunk)
(PrintOp.print_addressing print_reg) (addr, args);;
-let pp_set oc s =
+let pp_intset oc s =
Printf.fprintf oc "{ ";
List.iter (fun i -> Printf.fprintf oc "%d; " (P.to_int i)) (PSet.elements s);
Printf.fprintf oc "}";;
@@ -70,6 +70,38 @@ let pp_option pp oc = function
let is_trivial eq =
(eq.eq_op = SOp Op.Omove) && (eq.eq_args = [eq.eq_lhs]);;
+let rec pp_list separator pp_item chan = function
+ | [] -> ()
+ | [h] -> pp_item chan h
+ | h::t ->
+ pp_item chan h;
+ output_string chan separator;
+ pp_list separator pp_item chan t;;
+
+let pp_set separator pp_item chan s =
+ pp_list separator pp_item chan (PSet.elements s);;
+
+let pp_equation hints chan x =
+ match PTree.get x hints.hint_eq_catalog with
+ | None -> output_string chan "???"
+ | Some eq ->
+ print_eq chan (P.to_int eq.eq_lhs, eq.eq_op, List.map P.to_int eq.eq_args);;
+
+let pp_relation hints chan rel =
+ pp_set "; " (pp_equation hints) chan rel;;
+
+let pp_relation_b hints chan = function
+ | None -> output_string chan "bot"
+ | Some rel -> pp_relation hints chan rel;;
+
+let pp_results f (invariants : RB.t PMap.t) hints chan =
+ let max_pc = P.to_int (RTL.max_pc_function f) in
+ for pc=max_pc downto 1
+ do
+ Printf.fprintf chan "%d: %a\n" pc
+ (pp_relation_b hints) (PMap.get (P.of_int pc) invariants)
+ done
+
let preanalysis (tenv : typing_env) (f : RTL.coq_function) =
let cur_eq_id = ref 0
and cur_catalog = ref PTree.empty
@@ -81,7 +113,7 @@ let preanalysis (tenv : typing_env) (f : RTL.coq_function) =
let eq_find_oracle node eq =
assert (not (is_trivial eq));
let o = Hashtbl.find_opt eq_table (flatten_eq eq) in
- (if !Clflags.option_debug_compcert > 1
+ (if !Clflags.option_debug_compcert > 5
then Printf.printf "@%d: eq_find %a -> %a\n" (P.to_int node)
pp_eq eq (pp_option pp_P) o);
o
@@ -90,9 +122,9 @@ let preanalysis (tenv : typing_env) (f : RTL.coq_function) =
match Hashtbl.find_opt rhs_table (sop, List.map P.to_int args) with
| None -> PSet.empty
| Some s -> s in
- (if !Clflags.option_debug_compcert > 1
+ (if !Clflags.option_debug_compcert > 5
then Printf.printf "@%d: rhs_find %a = %a\n"
- (P.to_int node) pp_rhs (sop, args) pp_set o);
+ (P.to_int node) pp_rhs (sop, args) pp_intset o);
o in
let mutating_eq_find_oracle node eq : P.t option =
let (flat_eq_lhs, flat_eq_op, flat_eq_args) as flat_eq = flatten_eq eq in
@@ -124,7 +156,7 @@ let preanalysis (tenv : typing_env) (f : RTL.coq_function) =
Some coq_id
end
in
- (if !Clflags.option_debug_compcert > 1
+ (if !Clflags.option_debug_compcert > 5
then Printf.printf "@%d: mutating_eq_find %a -> %a\n" (P.to_int node)
pp_eq eq (pp_option pp_P) o);
o
@@ -140,7 +172,10 @@ let preanalysis (tenv : typing_env) (f : RTL.coq_function) =
} tenv f
with None -> failwith "CSE3analysisaux analysis failed, try re-running with -fno-cse3"
| Some invariants ->
- invariants,
- { hint_eq_catalog = !cur_catalog;
- hint_eq_find_oracle= eq_find_oracle;
- hint_eq_rhs_oracle = rhs_find_oracle };;
+ let hints = { hint_eq_catalog = !cur_catalog;
+ hint_eq_find_oracle= eq_find_oracle;
+ hint_eq_rhs_oracle = rhs_find_oracle } in
+ (if !Clflags.option_debug_compcert > 1
+ then pp_results f invariants hints stdout);
+ invariants, hints
+;;
diff --git a/backend/CSE3analysisproof.v b/backend/CSE3analysisproof.v
index 66b199cc..ea4d37ca 100644
--- a/backend/CSE3analysisproof.v
+++ b/backend/CSE3analysisproof.v
@@ -699,6 +699,28 @@ Section SOUNDNESS.
+ congruence.
Qed.
+
+ Lemma arglist_idem_write:
+ forall { A : Type} args (rs : Regmap.t A) dst,
+ (rs # dst <- (rs # dst)) ## args = rs ## args.
+ Proof.
+ induction args; trivial.
+ intros. cbn.
+ f_equal; trivial.
+ apply Regmap.gsident.
+ Qed.
+
+ Lemma sem_rhs_idem_write:
+ forall sop args rs dst m v,
+ sem_rhs sop args rs m v ->
+ sem_rhs sop args (rs # dst <- (rs # dst)) m v.
+ Proof.
+ intros.
+ unfold sem_rhs in *.
+ rewrite arglist_idem_write.
+ assumption.
+ Qed.
+
Theorem oper2_sound:
forall no dst sop args rel rs m v,
sem_rel rel rs m ->
@@ -726,6 +748,17 @@ Section SOUNDNESS.
rewrite Regmap.gss.
apply sem_rhs_depends_on_args_only; auto.
}
+ intros INi.
+ destruct (PSet.contains rel e) eqn:CONTAINSe.
+ { pose proof (REL e {| eq_lhs := dst; eq_op := sop; eq_args := args |} CONTAINSe H) as RELe.
+ pose proof (REL i eq CONTAINS INi) as RELi.
+ unfold sem_eq in *.
+ cbn in RELe.
+ replace v with (rs # dst) by (eapply sem_rhs_det; eassumption).
+ rewrite Regmap.gsident.
+ apply sem_rhs_idem_write.
+ assumption.
+ }
rewrite PSet.gaddo in CONTAINS by congruence.
apply (kill_reg_sound rel rs m dst v REL i eq); auto.
Qed.
@@ -821,11 +854,7 @@ Section SOUNDNESS.
subst.
rewrite <- (forward_move_sound rel rs m r) by auto.
apply move_sound; auto.
- - destruct (is_trivial_sym_op sop).
- {
- apply kill_reg_sound; auto.
- }
- destruct rhs_find as [src |] eqn:RHS_FIND.
+ - destruct rhs_find as [src |] eqn:RHS_FIND.
+ destruct (Compopts.optim_CSE3_glb tt).
* apply sem_rel_glb; split.
** pose proof (rhs_find_sound no sop (forward_move_l (ctx:=ctx) rel args) rel src rs m REL RHS_FIND) as SOUND.
@@ -833,12 +862,18 @@ Section SOUNDNESS.
2: eassumption.
rewrite <- (sem_rhs_det SOUND RHS).
apply move_sound; auto.
+ ** apply sem_rel_glb; split.
+ *** apply oper1_sound; auto.
+ apply forward_move_rhs_sound; auto.
+ *** apply oper1_sound; auto.
+ * apply sem_rel_glb; split.
** apply oper1_sound; auto.
apply forward_move_rhs_sound; auto.
- * ** apply oper1_sound; auto.
- apply forward_move_rhs_sound; auto.
- + apply oper1_sound; auto.
- apply forward_move_rhs_sound; auto.
+ ** apply oper1_sound; auto.
+ + apply sem_rel_glb; split.
+ * apply oper1_sound; auto.
+ apply forward_move_rhs_sound; auto.
+ * apply oper1_sound; auto.
Qed.
Hint Resolve oper_sound : cse3.
diff --git a/driver/Clflags.ml b/driver/Clflags.ml
index 9df58903..6c82ac62 100644
--- a/driver/Clflags.ml
+++ b/driver/Clflags.ml
@@ -27,11 +27,13 @@ let option_ftailcalls = ref true
let option_fconstprop = ref true
let option_fcse = ref true
let option_fcse2 = ref false
+
let option_fcse3 = ref true
let option_fcse3_alias_analysis = ref true
let option_fcse3_across_calls = ref false
let option_fcse3_across_merges = ref true
let option_fcse3_glb = ref true
+let option_fcse3_trivial_ops = ref false
let option_fredundancy = ref true
(** Options relative to superblock scheduling *)
diff --git a/driver/Compopts.v b/driver/Compopts.v
index 540e8922..0c90ee52 100644
--- a/driver/Compopts.v
+++ b/driver/Compopts.v
@@ -54,6 +54,9 @@ Parameter optim_CSE3_across_merges: unit -> bool.
(** Flag -fcse3-glb *)
Parameter optim_CSE3_glb: unit -> bool.
+(** Flag -fcse3-trivial-ops. For DMonniaux's common subexpression elimination, simplify trivial operations as well. *)
+Parameter optim_CSE3_trivial_ops: unit -> bool.
+
(** Flag -fmove-loop-invariants. *)
Parameter optim_move_loop_invariants: unit -> bool.
diff --git a/driver/Driver.ml b/driver/Driver.ml
index 12f50762..5d2c839f 100644
--- a/driver/Driver.ml
+++ b/driver/Driver.ml
@@ -202,6 +202,7 @@ Processing options:
-fcse3-across-calls Propagate CSE3 information across function calls [off]
-fcse3-across-merges Propagate CSE3 information across control-flow merges [on]
-fcse3-glb Refine CSE3 information using greatest lower bounds [on]
+ -fcse3-trivial-ops Replace trivial operations as well using CSE3 [off]
-fmove-loop-invariants Perform loop-invariant code motion [off]
-fredundancy Perform redundancy elimination [on]
-fpostpass Perform postpass scheduling (only for K1 architecture) [on]
@@ -415,6 +416,7 @@ let cmdline_actions =
@ f_opt "cse3-across-calls" option_fcse3_across_calls
@ f_opt "cse3-across-merges" option_fcse3_across_merges
@ f_opt "cse3-glb" option_fcse3_glb
+ @ f_opt "cse3-trivial-ops" option_fcse3_trivial_ops
@ f_opt "move-loop-invariants" option_fmove_loop_invariants
@ f_opt "redundancy" option_fredundancy
@ f_opt "postpass" option_fpostpass
diff --git a/test/monniaux/loop_nest/polybench.h b/test/monniaux/loop_nest/polybench.h
new file mode 100644
index 00000000..7d092e45
--- /dev/null
+++ b/test/monniaux/loop_nest/polybench.h
@@ -0,0 +1,202 @@
+/**
+ * polybench.h: This file is part of the PolyBench/C 3.2 test suite.
+ *
+ *
+ * Contact: Louis-Noel Pouchet <pouchet@cse.ohio-state.edu>
+ * Web address: http://polybench.sourceforge.net
+ */
+/*
+ * Polybench header for instrumentation.
+ *
+ * Programs must be compiled with `-I utilities utilities/polybench.c'
+ *
+ * Optionally, one can define:
+ *
+ * -DPOLYBENCH_TIME, to report the execution time,
+ * OR (exclusive):
+ * -DPOLYBENCH_PAPI, to use PAPI H/W counters (defined in polybench.c)
+ *
+ *
+ * See README or utilities/polybench.c for additional options.
+ *
+ */
+#ifndef POLYBENCH_H
+# define POLYBENCH_H
+
+# include <stdlib.h>
+
+/* Array padding. By default, none is used. */
+# ifndef POLYBENCH_PADDING_FACTOR
+/* default: */
+# define POLYBENCH_PADDING_FACTOR 0
+# endif
+
+
+/* C99 arrays in function prototype. By default, do not use. */
+# ifdef POLYBENCH_USE_C99_PROTO
+# define POLYBENCH_C99_SELECT(x,y) y
+# else
+/* default: */
+# define POLYBENCH_C99_SELECT(x,y) x
+# endif
+
+
+/* Scalar loop bounds in SCoPs. By default, use parametric loop bounds. */
+# ifdef POLYBENCH_USE_SCALAR_LB
+# define POLYBENCH_LOOP_BOUND(x,y) x
+# else
+/* default: */
+# define POLYBENCH_LOOP_BOUND(x,y) y
+# endif
+
+
+/* Macros to reference an array. Generic for heap and stack arrays
+ (C99). Each array dimensionality has his own macro, to be used at
+ declaration or as a function argument.
+ Example:
+ int b[x] => POLYBENCH_1D_ARRAY(b, x)
+ int A[N][N] => POLYBENCH_2D_ARRAY(A, N, N)
+*/
+# ifndef POLYBENCH_STACK_ARRAYS
+# define POLYBENCH_ARRAY(x) *x
+# define POLYBENCH_FREE_ARRAY(x) free((void*)x);
+# define POLYBENCH_DECL_VAR(x) (*x)
+# else
+# define POLYBENCH_ARRAY(x) x
+# define POLYBENCH_FREE_ARRAY(x)
+# define POLYBENCH_DECL_VAR(x) x
+# endif
+/* Macros for using arrays in the function prototypes. */
+# define POLYBENCH_1D(var, dim1,ddim1) var[POLYBENCH_C99_SELECT(dim1,ddim1) + POLYBENCH_PADDING_FACTOR]
+# define POLYBENCH_2D(var, dim1, dim2, ddim1, ddim2) var[POLYBENCH_C99_SELECT(dim1,ddim1) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim2,ddim2) + POLYBENCH_PADDING_FACTOR]
+# define POLYBENCH_3D(var, dim1, dim2, dim3, ddim1, ddim2, ddim3) var[POLYBENCH_C99_SELECT(dim1,ddim1) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim2,ddim2) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim3,ddim3) + POLYBENCH_PADDING_FACTOR]
+# define POLYBENCH_4D(var, dim1, dim2, dim3, dim4, ddim1, ddim2, ddim3, ddim4) var[POLYBENCH_C99_SELECT(dim1,ddim1) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim2,ddim2) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim3,ddim3) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim4,ddim4) + POLYBENCH_PADDING_FACTOR]
+# define POLYBENCH_5D(var, dim1, dim2, dim3, dim4, dim5, ddim1, ddim2, ddim3, ddim4, ddim5) var[POLYBENCH_C99_SELECT(dim1,ddim1) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim2,ddim2) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim3,ddim3) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim4,ddim4) + POLYBENCH_PADDING_FACTOR][POLYBENCH_C99_SELECT(dim5,ddim5) + POLYBENCH_PADDING_FACTOR]
+
+
+/* Macros to allocate heap arrays.
+ Example:
+ polybench_alloc_2d_array(N, M, double) => allocates N x M x sizeof(double)
+ and returns a pointer to the 2d array
+ */
+# define POLYBENCH_ALLOC_1D_ARRAY(n1, type) \
+ (type(*)[n1 + POLYBENCH_PADDING_FACTOR])polybench_alloc_data (n1 + POLYBENCH_PADDING_FACTOR, sizeof(type))
+# define POLYBENCH_ALLOC_2D_ARRAY(n1, n2, type) \
+ (type(*)[n1 + POLYBENCH_PADDING_FACTOR][n2 + POLYBENCH_PADDING_FACTOR])polybench_alloc_data ((n1 + POLYBENCH_PADDING_FACTOR) * (n2 + POLYBENCH_PADDING_FACTOR), sizeof(type))
+# define POLYBENCH_ALLOC_3D_ARRAY(n1, n2, n3, type) \
+ (type(*)[n1 + POLYBENCH_PADDING_FACTOR][n2 + POLYBENCH_PADDING_FACTOR][n3 + POLYBENCH_PADDING_FACTOR])polybench_alloc_data ((n1 + POLYBENCH_PADDING_FACTOR) * (n2 + POLYBENCH_PADDING_FACTOR) * (n3 + POLYBENCH_PADDING_FACTOR), sizeof(type))
+# define POLYBENCH_ALLOC_4D_ARRAY(n1, n2, n3, n4, type) \
+ (type(*)[n1 + POLYBENCH_PADDING_FACTOR][n2 + POLYBENCH_PADDING_FACTOR][n3 + POLYBENCH_PADDING_FACTOR][n4 + POLYBENCH_PADDING_FACTOR])polybench_alloc_data ((n1 + POLYBENCH_PADDING_FACTOR) * (n2 + POLYBENCH_PADDING_FACTOR) * (n3 + POLYBENCH_PADDING_FACTOR) * (n4 + POLYBENCH_PADDING_FACTOR), sizeof(type))
+# define POLYBENCH_ALLOC_5D_ARRAY(n1, n2, n3, n4, n5, type) \
+ (type(*)[n1 + POLYBENCH_PADDING_FACTOR][n2 + POLYBENCH_PADDING_FACTOR][n3 + POLYBENCH_PADDING_FACTOR][n4 + POLYBENCH_PADDING_FACTOR][n5 + POLYBENCH_PADDING_FACTOR])polybench_alloc_data ((n1 + POLYBENCH_PADDING_FACTOR) * (n2 + POLYBENCH_PADDING_FACTOR) * (n3 + POLYBENCH_PADDING_FACTOR) * (n4 + POLYBENCH_PADDING_FACTOR) * (n5 + POLYBENCH_PADDING_FACTOR), sizeof(type))
+
+/* Macros for array declaration. */
+# ifndef POLYBENCH_STACK_ARRAYS
+# define POLYBENCH_1D_ARRAY_DECL(var, type, dim1, ddim1) \
+ type POLYBENCH_1D(POLYBENCH_DECL_VAR(var), dim1, ddim1); \
+ var = POLYBENCH_ALLOC_1D_ARRAY(POLYBENCH_C99_SELECT(dim1, ddim1), type);
+# define POLYBENCH_2D_ARRAY_DECL(var, type, dim1, dim2, ddim1, ddim2) \
+ type POLYBENCH_2D(POLYBENCH_DECL_VAR(var), dim1, dim2, ddim1, ddim2); \
+ var = POLYBENCH_ALLOC_2D_ARRAY(POLYBENCH_C99_SELECT(dim1, ddim1), POLYBENCH_C99_SELECT(dim2, ddim2), type);
+# define POLYBENCH_3D_ARRAY_DECL(var, type, dim1, dim2, dim3, ddim1, ddim2, ddim3) \
+ type POLYBENCH_3D(POLYBENCH_DECL_VAR(var), dim1, dim2, dim3, ddim1, ddim2, ddim3); \
+ var = POLYBENCH_ALLOC_3D_ARRAY(POLYBENCH_C99_SELECT(dim1, ddim1), POLYBENCH_C99_SELECT(dim2, ddim2), POLYBENCH_C99_SELECT(dim3, ddim3), type);
+# define POLYBENCH_4D_ARRAY_DECL(var, type, dim1, dim2, dim3, dim4, ddim1, ddim2, ddim3, ddim4) \
+ type POLYBENCH_4D(POLYBENCH_DECL_VAR(var), dim1, dim2, ,dim3, dim4, ddim1, ddim2, ddim3, ddim4); \
+ var = POLYBENCH_ALLOC_4D_ARRAY(POLYBENCH_C99_SELECT(dim1, ddim1), POLYBENCH_C99_SELECT(dim2, ddim2), POLYBENCH_C99_SELECT(dim3, ddim3), POLYBENCH_C99_SELECT(dim4, ddim4), type);
+# define POLYBENCH_5D_ARRAY_DECL(var, type, dim1, dim2, dim3, dim4, dim5, ddim1, ddim2, ddim3, ddim4, ddim5) \
+ type POLYBENCH_5D(POLYBENCH_DECL_VAR(var), dim1, dim2, dim3, dim4, dim5, ddim1, ddim2, ddim3, ddim4, ddim5); \
+ var = POLYBENCH_ALLOC_5D_ARRAY(POLYBENCH_C99_SELECT(dim1, ddim1), POLYBENCH_C99_SELECT(dim2, ddim2), POLYBENCH_C99_SELECT(dim3, ddim3), POLYBENCH_C99_SELECT(dim4, ddim4), POLYBENCH_C99_SELECT(dim5, ddim5), type);
+# else
+# define POLYBENCH_1D_ARRAY_DECL(var, type, dim1, ddim1) \
+ type POLYBENCH_1D(POLYBENCH_DECL_VAR(var), dim1, ddim1);
+# define POLYBENCH_2D_ARRAY_DECL(var, type, dim1, dim2, ddim1, ddim2) \
+ type POLYBENCH_2D(POLYBENCH_DECL_VAR(var), dim1, dim2, ddim1, ddim2);
+# define POLYBENCH_3D_ARRAY_DECL(var, type, dim1, dim2, dim3, ddim1, ddim2, ddim3) \
+ type POLYBENCH_3D(POLYBENCH_DECL_VAR(var), dim1, dim2, dim3, ddim1, ddim2, ddim3);
+# define POLYBENCH_4D_ARRAY_DECL(var, type, dim1, dim2, dim3, dim4, ddim1, ddim2, ddim3, ddim4) \
+ type POLYBENCH_4D(POLYBENCH_DECL_VAR(var), dim1, dim2, dim3, dim4, ddim1, ddim2, ddim3, ddim4);
+# define POLYBENCH_5D_ARRAY_DECL(var, type, dim1, dim2, dim3, dim4, dim5, ddim1, ddim2, ddim3, ddim4, ddim5) \
+ type POLYBENCH_5D(POLYBENCH_DECL_VAR(var), dim1, dim2, dim3, dim4, dim5, ddim1, ddim2, ddim3, ddim4, ddim5);
+# endif
+
+
+/* Dead-code elimination macros. Use argc/argv for the run-time check. */
+# ifndef POLYBENCH_DUMP_ARRAYS
+# define POLYBENCH_DCE_ONLY_CODE if (argc > 42 && ! strcmp(argv[0], ""))
+# else
+# define POLYBENCH_DCE_ONLY_CODE
+# endif
+
+# define polybench_prevent_dce(func) \
+ POLYBENCH_DCE_ONLY_CODE \
+ func
+
+
+/* Performance-related instrumentation. See polybench.c */
+# define polybench_start_instruments
+# define polybench_stop_instruments
+# define polybench_print_instruments
+
+
+/* PAPI support. */
+# ifdef POLYBENCH_PAPI
+extern const unsigned int polybench_papi_eventlist[];
+# undef polybench_start_instruments
+# undef polybench_stop_instruments
+# undef polybench_print_instruments
+# define polybench_set_papi_thread_report(x) \
+ polybench_papi_counters_threadid = x;
+# define polybench_start_instruments \
+ polybench_prepare_instruments(); \
+ polybench_papi_init(); \
+ int evid; \
+ for (evid = 0; polybench_papi_eventlist[evid] != 0; evid++) \
+ { \
+ if (polybench_papi_start_counter(evid)) \
+ continue; \
+
+# define polybench_stop_instruments \
+ polybench_papi_stop_counter(evid); \
+ } \
+ polybench_papi_close(); \
+
+# define polybench_print_instruments polybench_papi_print();
+# endif
+
+
+/* Timing support. */
+# if defined(POLYBENCH_TIME) || defined(POLYBENCH_GFLOPS)
+# undef polybench_start_instruments
+# undef polybench_stop_instruments
+# undef polybench_print_instruments
+# define polybench_start_instruments polybench_timer_start();
+# define polybench_stop_instruments polybench_timer_stop();
+# define polybench_print_instruments polybench_timer_print();
+extern double polybench_program_total_flops;
+extern void polybench_timer_start();
+extern void polybench_timer_stop();
+extern void polybench_timer_print();
+# endif
+
+/* Function declaration. */
+# ifdef POLYBENCH_TIME
+extern void polybench_timer_start();
+extern void polybench_timer_stop();
+extern void polybench_timer_print();
+# endif
+
+# ifdef POLYBENCH_PAPI
+extern void polybench_prepare_instruments();
+extern int polybench_papi_start_counter(int evid);
+extern void polybench_papi_stop_counter(int evid);
+extern void polybench_papi_init();
+extern void polybench_papi_close();
+extern void polybench_papi_print();
+# endif
+
+/* Function prototypes. */
+extern void* polybench_alloc_data(unsigned long long int n, int elt_size);
+
+
+#endif /* !POLYBENCH_H */
diff --git a/test/monniaux/loop_nest/syrk.h b/test/monniaux/loop_nest/syrk.h
new file mode 100644
index 00000000..c753ff3b
--- /dev/null
+++ b/test/monniaux/loop_nest/syrk.h
@@ -0,0 +1,54 @@
+/**
+ * syrk.h: This file is part of the PolyBench/C 3.2 test suite.
+ *
+ *
+ * Contact: Louis-Noel Pouchet <pouchet@cse.ohio-state.edu>
+ * Web address: http://polybench.sourceforge.net
+ */
+#ifndef SYRK_H
+# define SYRK_H
+
+/* Default to STANDARD_DATASET. */
+# if !defined(MINI_DATASET) && !defined(SMALL_DATASET) && !defined(LARGE_DATASET) && !defined(EXTRALARGE_DATASET)
+# define STANDARD_DATASET
+# endif
+
+/* Do not define anything if the user manually defines the size. */
+# if !defined(NI) && !defined(NJ)
+/* Define the possible dataset sizes. */
+# ifdef MINI_DATASET
+# define NI 32
+# define NJ 32
+# endif
+
+# ifdef SMALL_DATASET
+# define NI 128
+# define NJ 128
+# endif
+
+# ifdef STANDARD_DATASET /* Default if unspecified. */
+# define NI 1024
+# define NJ 1024
+# endif
+
+# ifdef LARGE_DATASET
+# define NI 2000
+# define NJ 2000
+# endif
+
+# ifdef EXTRALARGE_DATASET
+# define NI 4000
+# define NJ 4000
+# endif
+# endif /* !N */
+
+# define _PB_NI POLYBENCH_LOOP_BOUND(NI,ni)
+# define _PB_NJ POLYBENCH_LOOP_BOUND(NJ,nj)
+
+# ifndef DATA_TYPE
+# define DATA_TYPE double
+# define DATA_PRINTF_MODIFIER "%0.2lf "
+# endif
+
+
+#endif /* !SYRK */