diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b07c70c66f3..acf1987cebe 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,18 @@ +2014-04-14 Eric Botcazou + + * snames.ads-tmpl (Name_Ivdep): New pragma-related name. + * sem_prag.adb (Analyze_Pragma) : Add support + for Ivdep hint. + * gnat_rm.texi (Implementation Defined Pragmas): Document new Ivdep + hint for Loop_Optimize. + * gnat_ugn.texi (Vectorization of loops): Mention new Ivdep hint. + * gcc-interface/trans.c (Pragma_to_gnu) : Deal + with new Ivdep hint. + * gcc-interface/ada-tree.h (LOOP_STMT_IVDEP): New macro. + * gcc-interface/trans.c (Pragma_to_gnu) : Deal + with new Ivdep hint. + (gnat_gimplify_stmt) : Propagate the loop hints. + 2014-04-14 Eric Botcazou Robert Dewar diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h index c1b45effcdb..5ea386f860c 100644 --- a/gcc/ada/gcc-interface/ada-tree.h +++ b/gcc/ada/gcc-interface/ada-tree.h @@ -6,7 +6,7 @@ * * * C Header File * * * - * Copyright (C) 1992-2013, Free Software Foundation, Inc. * + * Copyright (C) 1992-2014, Free Software Foundation, Inc. * * * * GNAT is free software; you can redistribute it and/or modify it under * * terms of the GNU General Public License as published by the Free Soft- * @@ -504,10 +504,11 @@ do { \ #define LOOP_STMT_TOP_UPDATE_P(NODE) TREE_LANG_FLAG_1 (LOOP_STMT_CHECK (NODE)) /* Optimization hints on loops. */ -#define LOOP_STMT_NO_UNROLL(NODE) TREE_LANG_FLAG_2 (LOOP_STMT_CHECK (NODE)) -#define LOOP_STMT_UNROLL(NODE) TREE_LANG_FLAG_3 (LOOP_STMT_CHECK (NODE)) -#define LOOP_STMT_NO_VECTOR(NODE) TREE_LANG_FLAG_4 (LOOP_STMT_CHECK (NODE)) -#define LOOP_STMT_VECTOR(NODE) TREE_LANG_FLAG_5 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_IVDEP(NODE) TREE_LANG_FLAG_2 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_NO_UNROLL(NODE) TREE_LANG_FLAG_3 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_UNROLL(NODE) TREE_LANG_FLAG_4 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_NO_VECTOR(NODE) TREE_LANG_FLAG_5 (LOOP_STMT_CHECK (NODE)) +#define LOOP_STMT_VECTOR(NODE) TREE_LANG_FLAG_6 (LOOP_STMT_CHECK (NODE)) #define EXIT_STMT_COND(NODE) TREE_OPERAND_CHECK_CODE (NODE, EXIT_STMT, 0) #define EXIT_STMT_LABEL(NODE) TREE_OPERAND_CHECK_CODE (NODE, EXIT_STMT, 1) diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 59358ff3028..3ab503fb14b 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1268,10 +1268,14 @@ Pragma_to_gnu (Node_Id gnat_node) Present (gnat_temp); gnat_temp = Next (gnat_temp)) { - tree gnu_loop_stmt = gnu_loop_stack ->last ()->stmt; + tree gnu_loop_stmt = gnu_loop_stack->last ()->stmt; switch (Chars (Expression (gnat_temp))) { + case Name_Ivdep: + LOOP_STMT_IVDEP (gnu_loop_stmt) = 1; + break; + case Name_No_Unroll: LOOP_STMT_NO_UNROLL (gnu_loop_stmt) = 1; break; @@ -7747,13 +7751,20 @@ gnat_gimplify_stmt (tree *stmt_p) tree gnu_cond = LOOP_STMT_COND (stmt); tree gnu_update = LOOP_STMT_UPDATE (stmt); tree gnu_end_label = LOOP_STMT_LABEL (stmt); - tree t; /* Build the condition expression from the test, if any. */ if (gnu_cond) - gnu_cond - = build3 (COND_EXPR, void_type_node, gnu_cond, alloc_stmt_list (), - build1 (GOTO_EXPR, void_type_node, gnu_end_label)); + { + /* Deal with the optimization hints. */ + if (LOOP_STMT_IVDEP (stmt)) + gnu_cond = build2 (ANNOTATE_EXPR, TREE_TYPE (gnu_cond), gnu_cond, + build_int_cst (integer_type_node, + annot_expr_ivdep_kind)); + + gnu_cond + = build3 (COND_EXPR, void_type_node, gnu_cond, NULL_TREE, + build1 (GOTO_EXPR, void_type_node, gnu_end_label)); + } /* Set to emit the statements of the loop. */ *stmt_p = NULL_TREE; @@ -7782,7 +7793,7 @@ gnat_gimplify_stmt (tree *stmt_p) if (gnu_update && !LOOP_STMT_TOP_UPDATE_P (stmt)) append_to_statement_list (gnu_update, stmt_p); - t = build1 (GOTO_EXPR, void_type_node, gnu_start_label); + tree t = build1 (GOTO_EXPR, void_type_node, gnu_start_label); SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (gnu_end_label)); append_to_statement_list (t, stmt_p); diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi index 138551df327..34ac0e17aa9 100644 --- a/gcc/ada/gnat_rm.texi +++ b/gcc/ada/gnat_rm.texi @@ -4417,7 +4417,7 @@ Syntax: @smallexample @c ada pragma Loop_Optimize (OPTIMIZATION_HINT @{, OPTIMIZATION_HINT@}); -OPTIMIZATION_HINT ::= No_Unroll | Unroll | No_Vector | Vector +OPTIMIZATION_HINT ::= Ivdep | No_Unroll | Unroll | No_Vector | Vector @end smallexample @noindent @@ -4426,8 +4426,13 @@ programmer to specify optimization hints for the enclosing loop. The hints are not mutually exclusive and can be freely mixed, but not all combinations will yield a sensible outcome. -There are four supported optimization hints for a loop: +There are five supported optimization hints for a loop: + @itemize @bullet +@item Ivdep + +The programmer asserts that there are no loop-carried dependencies which would prevent consecutive iterations of the loop from being executed simultaneously. + @item No_Unroll The loop must not be unrolled. This is a strong hint: the compiler will not diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi index b484665eab4..2d9c61865d9 100644 --- a/gcc/ada/gnat_ugn.texi +++ b/gcc/ada/gnat_ugn.texi @@ -10780,6 +10780,38 @@ preferably to other optimizations by means of pragma @code{Loop_Optimize}: placed immediately within the loop will convey the appropriate hint to the compiler for this loop. +It is also possible to help the compiler generate better vectorized code +for a given loop by asserting that there are no loop-carried dependencies +in the loop. Consider for example the procedure: + +@smallexample @c ada + type Arr is array (1 .. 4) of Long_Float; + + procedure Add (X, Y : not null access Arr; R : not null access Arr) is + begin + for I in Arr'Range loop + R(I) := X(I) + Y(I); + end loop; + end; +@end smallexample + +@noindent +By default, the compiler cannot unconditionally vectorize the loop because +assigning to a component of the array designated by R in one iteration could +change the value read from the components of the arrays designated by X or Y +in a later iteration. As a result, the compiler will generate two versions +of the loop in the object code, one vectorized and the other not vectorized, +as well as a test to select the appropriate version at run time. This can +be overcome by another hint: + +@smallexample @c ada + pragma Loop_Optimize (Ivdep); +@end smallexample + +@noindent +placed immediately within the loop will tell the compiler that it can safely +omit the non-vectorized version of the loop as well as the run-time test. + @node Other Optimization Switches @subsection Other Optimization Switches @cindex Optimization Switches diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb index b3590040109..42f080de4da 100644 --- a/gcc/ada/sem_prag.adb +++ b/gcc/ada/sem_prag.adb @@ -16560,7 +16560,8 @@ package body Sem_Prag is -- pragma Loop_Optimize ( OPTIMIZATION_HINT {, OPTIMIZATION_HINT } ); - -- OPTIMIZATION_HINT ::= No_Unroll | Unroll | No_Vector | Vector + -- OPTIMIZATION_HINT ::= + -- Ivdep | No_Unroll | Unroll | No_Vector | Vector when Pragma_Loop_Optimize => Loop_Optimize : declare Hint : Node_Id; @@ -16572,7 +16573,7 @@ package body Sem_Prag is Hint := First (Pragma_Argument_Associations (N)); while Present (Hint) loop - Check_Arg_Is_One_Of (Hint, + Check_Arg_Is_One_Of (Hint, Name_Ivdep, Name_No_Unroll, Name_Unroll, Name_No_Vector, Name_Vector); Next (Hint); end loop; diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl index c8831b3f212..b4fcb54ccb2 100644 --- a/gcc/ada/snames.ads-tmpl +++ b/gcc/ada/snames.ads-tmpl @@ -730,6 +730,7 @@ package Snames is Name_Increases : constant Name_Id := N + $; Name_Info : constant Name_Id := N + $; Name_Internal : constant Name_Id := N + $; + Name_Ivdep : constant Name_Id := N + $; Name_Link_Name : constant Name_Id := N + $; Name_Lowercase : constant Name_Id := N + $; Name_Max_Entry_Queue_Depth : constant Name_Id := N + $; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0a741fb0b68..deada3ec6cf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-04-14 Eric Botcazou + + * gnat.dg/vect11.ad[sb]: New test. + 2014-04-14 Richard Biener * g++.dg/tree-ssa/forwprop-switch.C: New testcase. diff --git a/gcc/testsuite/gnat.dg/vect11.adb b/gcc/testsuite/gnat.dg/vect11.adb new file mode 100644 index 00000000000..c8c8a0cb6eb --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect11.adb @@ -0,0 +1,33 @@ +-- { dg-do compile { target i?86-*-* x86_64-*-* } } +-- { dg-options "-O3 -msse2 -fdump-tree-optimized" } + +package body Vect11 is + + function "+" (X, Y : Sarray) return Sarray is + R : Sarray; + begin + for I in Sarray'Range loop + R(I) := X(I) + Y(I); + end loop; + return R; + end; + + procedure Add (X, Y : Sarray; R : out Sarray) is + begin + for I in Sarray'Range loop + R(I) := X(I) + Y(I); + end loop; + end; + + procedure Add (X, Y : not null access Sarray; R : not null access Sarray) is + begin + for I in Sarray'Range loop + pragma Loop_Optimize (Ivdep); + R(I) := X(I) + Y(I); + end loop; + end; + +end Vect11; + +-- { dg-final { scan-tree-dump-not "goto" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/vect11.ads b/gcc/testsuite/gnat.dg/vect11.ads new file mode 100644 index 00000000000..f3ceac111a1 --- /dev/null +++ b/gcc/testsuite/gnat.dg/vect11.ads @@ -0,0 +1,11 @@ +package Vect11 is + + -- Constrained array types are vectorizable + type Sarray is array (1 .. 4) of Float; + for Sarray'Alignment use 16; + + function "+" (X, Y : Sarray) return Sarray; + procedure Add (X, Y : Sarray; R : out Sarray); + procedure Add (X, Y : not null access Sarray; R : not null access Sarray); + +end Vect11;