[Patch, Fortran] FINAL (prep patches 1/5): Add _final to intrinsic vtables for CLASS(*)

2012-12-31 Thread Tobias Burnus
This simple patch fixes a wrong indent and adds a _final component to 
the virtual tables generated for intrinsic types.


This patch not only prepares the trunk for finalization support, it also 
avoids ABI issues which a later addition would cause. (For intrinsic 
types, changing the .mod version number will not reliable force a 
recompilation.)


Build on x86-64-gnu-linux.
OK for the trunk?

Tobias
2012-12-31  Tobias Burnus  

	* class.c (gfc_find_intrinsic_vtab): Add _final
	component.

diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 61d65e7..84f383e 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -597,7 +597,7 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
   fclass->refs++;
   fclass->ts.type = BT_UNKNOWN;
   if (!ts->u.derived->attr.unlimited_polymorphic)
-  fclass->attr.abstract = ts->u.derived->attr.abstract;
+	fclass->attr.abstract = ts->u.derived->attr.abstract;
   fclass->f2k_derived = gfc_get_namespace (NULL, 0);
   if (gfc_add_flavor (&fclass->attr, FL_DERIVED,
 	  NULL, &gfc_current_locus) == FAILURE)
@@ -2310,6 +2708,15 @@ gfc_find_intrinsic_vtab (gfc_typespec *ts)
 	  /* Set initializer.  */
 	  c->initializer = gfc_lval_expr_from_sym (copy);
 	  c->ts.interface = copy;
+
+	  /* Add component _final.  */
+	  if (gfc_add_component (vtype, "_final", &c) == FAILURE)
+		goto cleanup;
+	  c->attr.proc_pointer = 1;
+	  c->attr.access = ACCESS_PRIVATE;
+	  c->tb = XCNEW (gfc_typebound_proc);
+	  c->tb->ppc = 1;
+	  c->initializer = gfc_get_null_expr (NULL);
 	}
 	  vtab->ts.u.derived = vtype;
 	  vtab->value = gfc_default_initializer (&vtab->ts);


[Patch, Fortran] FINAL (prep patches 2/5): Add internal STRIDE intrinsic

2012-12-31 Thread Tobias Burnus
The attached patch adds a new - internal only - intrinsic, STRIDE, which 
returns the stride of an array with array descriptor; for an "integer :: 
array(5,5)", the stride of dim=2 is 5.


This new intrinsic is only internally available and will be used by the 
finalization wrapper to handle noncontiguous arrays.


Build on x86-64-gnu-linux.
OK for the trunk?

Tobias
2012-12-31  Tobias Burnus  

	* intrinsic.c (add_functions): New internal intrinsic
	function GFC_PREFIX ("stride").
	* gfortran.h (gfc_isym_id): Add GFC_ISYM_STRIDE.
	* intrinsic.h (gfc_resolve_stride): New prototypes.
	* iresolve.c (gfc_resolve_stride): New function.
	* trans-intrinsic.c (conv_intrinsic_stride): New static
	function.
	(gfc_conv_intrinsic_function): Use it.

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a419af3..027cab6 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -521,6 +521,7 @@ enum gfc_isym_id
   GFC_ISYM_SR_KIND,
   GFC_ISYM_STAT,
   GFC_ISYM_STORAGE_SIZE,
+  GFC_ISYM_STRIDE,
   GFC_ISYM_SUM,
   GFC_ISYM_SYMLINK,
   GFC_ISYM_SYMLNK,
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 274c921..8328b9b 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -2640,6 +2640,14 @@ add_functions (void)
 
   make_generic ("size", GFC_ISYM_SIZE, GFC_STD_F95);
 
+  /* Obtain the stride for a given dimensions; to be used only internally.
+ "make_from_module" makes inaccessible for external users.  */
+  add_sym_2 (GFC_PREFIX ("stride"), GFC_ISYM_STRIDE, CLASS_INQUIRY, ACTUAL_NO,
+	 BT_INTEGER, gfc_index_integer_kind, GFC_STD_GNU,
+	 NULL, NULL, gfc_resolve_stride,
+	 ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL);
+  make_from_module();
+
   add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, ii,
 	 GFC_STD_GNU, gfc_check_sizeof, NULL, NULL,
 	 x, BT_UNKNOWN, 0, REQUIRED);
diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h
index 2635ba6..4540ad8 100644
--- a/gcc/fortran/intrinsic.h
+++ b/gcc/fortran/intrinsic.h
@@ -546,6 +546,7 @@ void gfc_resolve_signal (gfc_expr *, gfc_expr *, gfc_expr *);
 void gfc_resolve_sin (gfc_expr *, gfc_expr *);
 void gfc_resolve_sinh (gfc_expr *, gfc_expr *);
 void gfc_resolve_size (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
+void gfc_resolve_stride (gfc_expr *, gfc_expr *, gfc_expr *);
 void gfc_resolve_spacing (gfc_expr *, gfc_expr *);
 void gfc_resolve_spread (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
 void gfc_resolve_sqrt (gfc_expr *, gfc_expr *);
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
index 3f981d8..c884fc1 100644
--- a/gcc/fortran/iresolve.c
+++ b/gcc/fortran/iresolve.c
@@ -2314,6 +2314,15 @@ gfc_resolve_size (gfc_expr *f, gfc_expr *array ATTRIBUTE_UNUSED,
 
 
 void
+gfc_resolve_stride (gfc_expr *f, gfc_expr *array ATTRIBUTE_UNUSED,
+		  gfc_expr *dim ATTRIBUTE_UNUSED)
+{
+  f->ts.type = BT_INTEGER;
+  f->ts.kind = gfc_index_integer_kind;
+}
+
+
+void
 gfc_resolve_spacing (gfc_expr *f, gfc_expr *x)
 {
   f->ts = x->ts;
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 5a89be1..e0b5f11 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -1657,6 +1657,35 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
 
 
 static void
+conv_intrinsic_stride (gfc_se * se, gfc_expr * expr)
+{
+  gfc_actual_arglist *array_arg;
+  gfc_actual_arglist *dim_arg;
+  gfc_se argse;
+  tree desc, tmp;
+
+  array_arg = expr->value.function.actual;
+  dim_arg = array_arg->next;
+
+  gcc_assert (array_arg->expr->expr_type == EXPR_VARIABLE);
+
+  gfc_init_se (&argse, NULL);
+  gfc_conv_expr_descriptor (&argse, array_arg->expr);
+  gfc_add_block_to_block (&se->pre, &argse.pre);
+  gfc_add_block_to_block (&se->post, &argse.post);
+  desc = argse.expr;
+
+  gcc_assert (dim_arg->expr);
+  gfc_init_se (&argse, NULL);
+  gfc_conv_expr_type (&argse, dim_arg->expr, gfc_array_index_type);
+  gfc_add_block_to_block (&se->pre, &argse.pre);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+			 argse.expr, gfc_index_one_node);
+  se->expr = gfc_conv_descriptor_stride_get (desc, tmp);
+}
+
+
+static void
 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
 {
   tree arg, cabs;
@@ -6806,6 +6835,10 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
   gfc_conv_intrinsic_spacing (se, expr);
   break;
 
+case GFC_ISYM_STRIDE:
+  conv_intrinsic_stride (se, expr);
+  break;
+
 case GFC_ISYM_SUM:
   gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false);
   break;


[Patch, Fortran] FINAL (prep patches 3/5): Auxiliary functions for calling the FINAL wrapper

2012-12-31 Thread Tobias Burnus
This patch adds one auxiliary functions, which will be used when 
invoking the finalization wrapper. It is currently unused.


Build on x86-64-gnu-linux.
OK for the trunk?

Tobias
2012-12-31  Tobias Burnus  

	* trans.c (gfc_build_final_call): New function.
	* trans.h (gfc_build_final_call, gfc_conv_scalar_to_descriptor):
	New function prototypes.
	* trans-expr.c (gfc_conv_scalar_to_descriptor): Renamed from
	conv_scalar_to_descriptor, removed static attribute.
	(gfc_conv_procedure_call): Honor renaming.

diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 452f2bc..ed95739 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -61,8 +61,8 @@ get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
 akind, !(attr.pointer || attr.target));
 }
 
-static tree
-conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
+tree
+gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
 {
   tree desc, type;
 
@@ -4355,8 +4356,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 		  if (TREE_CODE (tmp) == ADDR_EXPR
 			  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp, 0
 			tmp = TREE_OPERAND (tmp, 0);
-		  parmse.expr = conv_scalar_to_descriptor (&parmse, tmp,
-			   fsym->attr);
+		  parmse.expr = gfc_conv_scalar_to_descriptor (&parmse, tmp,
+   fsym->attr);
 		  parmse.expr = gfc_build_addr_expr (NULL_TREE,
 			 parmse.expr);
 		}
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 70f06ff..9296e06 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -1023,6 +1023,116 @@ gfc_deallocate_with_status (tree pointer, tree status, tree errmsg,
 }
 
 
+/* Build a call to a FINAL procedure, which finalizes "var".  */
+
+tree
+gfc_build_final_call (gfc_typespec ts, gfc_expr *final_wrapper, gfc_expr *var,
+		  bool fini_coarray, gfc_expr *class_size)
+{
+  stmtblock_t block;
+  gfc_se se;
+  tree final_fndecl, array, size, tmp;
+
+  gcc_assert (final_wrapper->expr_type == EXPR_VARIABLE);
+  gcc_assert (var);
+
+  gfc_init_se (&se, NULL);
+  gfc_conv_expr (&se, final_wrapper);
+  final_fndecl = se.expr;
+  if (POINTER_TYPE_P (TREE_TYPE (final_fndecl)))
+final_fndecl = build_fold_indirect_ref_loc (input_location, final_fndecl);
+
+  if (ts.type == BT_DERIVED)
+{
+  tree elem_size;
+
+  gcc_assert (!class_size);
+  elem_size = gfc_typenode_for_spec (&ts);
+  elem_size = TYPE_SIZE_UNIT (elem_size);
+  size = fold_convert (gfc_array_index_type, elem_size);
+
+  gfc_init_se (&se, NULL);
+  se.want_pointer = 1;
+  if (var->rank || gfc_expr_attr (var).dimension)
+	{
+	  se.descriptor_only = 1;
+	  gfc_conv_expr_descriptor (&se, var);
+	  array = se.expr;
+	  if (!POINTER_TYPE_P (TREE_TYPE (array)))
+	array = gfc_build_addr_expr (NULL, array);
+	}
+  else
+	{
+	  symbol_attribute attr;
+	  gfc_clear_attr (&attr);
+	  gfc_conv_expr (&se, var);
+	  gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
+	  array = se.expr;
+	  if (TREE_CODE (array) == ADDR_EXPR
+	  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0
+	tmp = TREE_OPERAND (array, 0);
+
+	  gfc_init_se (&se, NULL);
+	  array = gfc_conv_scalar_to_descriptor (&se, array, attr);
+	  array = gfc_build_addr_expr (NULL, array);
+	  gcc_assert (se.post.head == NULL_TREE);
+	}
+}
+  else
+{
+  gfc_expr *array_expr;
+  gcc_assert (class_size);
+  gfc_init_se (&se, NULL);
+  gfc_conv_expr (&se, class_size);
+  gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
+  size = se.expr;
+
+  array_expr = gfc_copy_expr (var);
+  gfc_add_data_component (array_expr);
+  gfc_init_se (&se, NULL);
+  se.want_pointer = 1;
+  if (array_expr->rank || gfc_expr_attr (array_expr).dimension)
+	{
+	  se.descriptor_only = 1;
+	  gfc_conv_expr_descriptor (&se, var);
+	  array = se.expr;
+	  if (! POINTER_TYPE_P (TREE_TYPE (array)))
+	array = gfc_build_addr_expr (NULL, array);
+	}
+  else
+	{
+	  symbol_attribute attr;
+
+	  gfc_clear_attr (&attr);
+	  gfc_conv_expr (&se, array_expr);
+	  gcc_assert (se.pre.head == NULL_TREE && se.post.head == NULL_TREE);
+	  array = se.expr;
+	  if (TREE_CODE (array) == ADDR_EXPR
+	  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (array, 0
+	tmp = TREE_OPERAND (array, 0);
+
+	  /* attr: Argument is neither a pointer/allocatble,
+	 i.e. no copy back needed */
+	  gfc_init_se (&se, NULL);
+	  array = gfc_conv_scalar_to_descriptor (&se, array, attr);
+	  array = gfc_build_addr_expr (NULL, array);
+	  gcc_assert (se.post.head == NULL_TREE);
+	}
+  gfc_free_expr (array_expr);
+}
+
+  gfc_start_block (&block);
+  gfc_add_block_to_block (&block, &se.pre);
+  tmp = build_call_expr_loc (input_location,
+			 final_fndecl, 3, array,
+			 size, fini_coarray ? boolean_true_node
+		: boolean_false_node);
+  gfc_add_block_to_block (&block,

Patch, Fortran] FINAL (prep patches 5/5): Activate the generation of the finalization wrapper

2012-12-31 Thread Tobias Burnus
(Patch 4/5, which adds support for noncontiguous arrays to the 
finalization wrapper follows soon; it works, but I should do a small 
cleanup before submittal.)


Contrary to the other patches in this series, this patch changes the 
generated code - and it changes the ABI. With this patch, the virtual 
table (vtab) gets a "_final" components between _copy and the user's 
type-bound procedures. Additionally, the finalization wrapper is generated.



Note: This patch only adds the finalization wrapper function - it does 
not use it. Thus, there is no user-visible benefit of this patch - 
except for the avoided 4.9 ABI issue.


The risk of this patch is rather low (only ICEs are possible).

The (only? main?) advantage of this patch is that it avoids ABI breakage 
for polymorphic variables immediately after branching 4.8. (Due to two 
recent patches, we have already broken the ABI for 4.8 and bumped the 
.mod version. Thus, this breakage could make use of the already bumped 
.mod file version number.)



Build and regtested on x86-64-gnu-linux.
OK for the 4.8 trunk? – Alternatively: OK for the 4.9 trunk?

* * *

The next step is make use of the finalization wrapper for both calling 
the user's finalization subroutines but also for deallocating 
allocatable components of polymorphic variables/components. 
("polymorphic freeing").


At https://userpage.physik.fu-berlin.de/~tburnus/final/ I have a draft 
patch which handles some of the cases; however, the support is 
incomplete and there are possibly some issues.


One could consider supporting some subset of polymorphic freeing or 
finalization using the user's FINAL subroutines even for 4.8. However, 
it looks more like GCC 4.9 material. Comments?


Tobias
2012-12-31  Tobias Burnus  

	* class.c (gfc_find_derived_vtab): Activate the generation
	of the finalization wrapper.

diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 61d65e7..84f383e 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -2024,9 +2425,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 		 components and the calls to finalization subroutines.
 		 Note: The actual wrapper function can only be generated
 		 at resolution time.  */
-	/* FIXME: Enable ABI-breaking "_final" generation.  */
-	if (0)
-	{
+
 	  if (gfc_add_component (vtype, "_final", &c) == FAILURE)
 		goto cleanup;
 	  c->attr.proc_pointer = 1;
@@ -2034,7 +2433,6 @@ gfc_find_derived_vtab (gfc_symbol *derived)
 	  c->tb = XCNEW (gfc_typebound_proc);
 	  c->tb->ppc = 1;
 	  generate_finalization_wrapper (derived, ns, tname, c);
-	}
 
 	  /* Add procedure pointers for type-bound procedures.  */
 	  if (!derived->attr.unlimited_polymorphic)


[Patch, Fortran] FINAL (prep patches 4/5): Support noncontiguous arrays in the finalization wrapper function

2012-12-31 Thread Tobias Burnus

Dear all,

this lengthy patch supports noncontiguous arrays in the finalization 
wrapper. That encompasses bother the scalarizer (used for finalizing the 
components and for an ELEMENTAL FINAL subroutine) and calling array 
FINAL subroutines. For the latter, the subroutine is directly called if 
possible. Namely, when the element size of the actual type is the same 
as the one of the declared type - and the the FINAL subroutine is either 
assumed-shape without the contiguous attribute or the actual argument is 
contiguous. Otherwise, the code packs the array.


The code is written such that it works for any array rank. I explicitly 
avoided using GFC_MAX_DIMENSIONS to allow for more ranks without 
breaking the ABI.


The code consists of two new blocks of code. The new function 
"finalization_get_offset" which generates the code to translate from an 
element index to the byte offset - and in generate_finalization_wrapper 
to fill the array "strides" and "sizes", where the latter contains the 
multiplied up size, i.e. sizes(0) == 1, sizes(1) = size(array,dim=1), 
sizes(2) = sizes(1)*size(array,dim=2) etc.


Note: Without patch 5/5, this code is never executed.

Build and regtested on x86-64-gnu-linux - and tested (with the not 
submitted patch for invoking the finalizer).

OK for the trunk?

Tobias
2012-12-31  Tobias Burnus  

	* class.c (finalize_component): Used passed offset expr.
	(finalization_get_offset): New static function.
	(finalizer_insert_packed_call, generate_finalization_wrapper): Use it
	to handle noncontiguous arrays.

diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 61d65e7..dae1adc 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -924,14 +924,14 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
 
 /* Generate code equivalent to
CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
-		 + idx * stride, c_ptr), ptr).  */
+		 + offset, c_ptr), ptr).  */
 
 static gfc_code *
-finalization_scalarizer (gfc_symbol *idx, gfc_symbol *array, gfc_symbol *ptr,
-			 gfc_expr *stride, gfc_namespace *sub_ns)
+finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
+			 gfc_expr *offset, gfc_namespace *sub_ns)
 {
   gfc_code *block;
-  gfc_expr *expr, *expr2, *expr3;
+  gfc_expr *expr, *expr2;
 
   /* C_F_POINTER().  */
   block = XCNEW (gfc_code);
@@ -961,6 +961,7 @@ finalization_scalarizer (gfc_symbol *idx, gfc_symbol *array, gfc_symbol *ptr,
 	= gfc_intrinsic_function_by_id (GFC_ISYM_TRANSFER);
   /* Set symtree for -fdump-parse-tree.  */
   gfc_get_sym_tree ("transfer", sub_ns, &expr2->symtree, false);
+  expr2->symtree->n.sym->intmod_sym_id = GFC_ISYM_TRANSFER;
   expr2->symtree->n.sym->attr.flavor = FL_PROCEDURE;
   expr2->symtree->n.sym->attr.intrinsic = 1;
   gfc_commit_symbol (expr2->symtree->n.sym);
@@ -995,21 +996,12 @@ finalization_scalarizer (gfc_symbol *idx, gfc_symbol *array, gfc_symbol *ptr,
   expr->ts.kind = gfc_index_integer_kind;
   expr2->value.function.actual->expr = expr;
 
-  /* Offset calculation: idx * stride (in bytes).  */
-  block->ext.actual->expr = gfc_get_expr ();
-  expr3 = block->ext.actual->expr;
-  expr3->expr_type = EXPR_OP;
-  expr3->value.op.op = INTRINSIC_TIMES;
-  expr3->value.op.op1 = gfc_lval_expr_from_sym (idx);
-  expr3->value.op.op2 = stride;
-  expr3->ts = expr->ts;
-
   /*  + .  */
   block->ext.actual->expr = gfc_get_expr ();
   block->ext.actual->expr->expr_type = EXPR_OP;
   block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
   block->ext.actual->expr->value.op.op1 = expr2;
-  block->ext.actual->expr->value.op.op2 = expr3;
+  block->ext.actual->expr->value.op.op2 = offset;
   block->ext.actual->expr->ts = expr->ts;
 
   /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=.  */
@@ -1021,39 +1013,183 @@ finalization_scalarizer (gfc_symbol *idx, gfc_symbol *array, gfc_symbol *ptr,
 }
 
 
+/* Calculates the offset to the (idx+1)th element of an array, taking the
+   stride into account. It generates the code:
+ offset = 0
+ do idx2 = 1, rank
+   offset = offset + mod (idx, sizes(idx2)) / size(idx2-1) * strides(idx2)
+ end do
+ offset = offset * byte_stride.  */
+
+static gfc_code*
+finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
+			 gfc_symbol *strides, gfc_symbol *sizes,
+			 gfc_symbol *byte_stride, gfc_expr *rank,
+			 gfc_code *block, gfc_namespace *sub_ns)
+{
+  gfc_iterator *iter;
+  gfc_expr *expr, *expr2;
+
+  /* offset = 0.  */
+  block->next = XCNEW (gfc_code);
+  block = block->next;
+  block->op = EXEC_ASSIGN;
+  block->loc = gfc_current_locus;
+  block->expr1 = gfc_lval_expr_from_sym (offset);
+  block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
+
+  /* Create loop.  */
+  iter = gfc_get_iterator ();
+  iter->var = gfc_lval_expr_from_sym (idx2);
+  iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
+  iter->end = gfc_copy_expr (rank);
+  iter->step = gfc_get_int_expr

PING^3: [PATCH] Support -fuse-ld=bfd and -fuse-ld=gold

2012-12-31 Thread H.J. Lu
On Wed, Dec 19, 2012 at 2:20 PM, H.J. Lu  wrote:
> On Wed, Dec 19, 2012 at 1:13 PM, Joseph S. Myers
>  wrote:
>> On Thu, 13 Dec 2012, H.J. Lu wrote:
>>
>>> Hi Joseph,
>>>
>>> Can you review this?
>>
>> I'm still confused as to what's supposed to be reviewed and whether the
>> issues raised in the previous discussions have been properly addressed.
>> Looking at , I
>> don't see the need for the variables named with Var in common.opt, and I'd
>
> Fixed.
>
>> think proper help text would be better than using Undocumented.
>>
>
> Fixed.
>
> Here is the updated patch.  OK for trunk?
>
> Thanks.
>
> --
> H.J.
> --
> 2012-12-19   Nick Clifton  
>  Matthias Klose 
>  Doug Kwan  
>  H.J. Lu  
>
> PR driver/55470
> * collect2.c (main): Support -fuse-ld=bfd and -fuse-ld=gold.
>
> * common.opt: Add fuse-ld=bfd and fuse-ld=gold.
>
> * gcc.c (LINK_COMMAND_SPEC): Pass -fuse-ld=* to collect2.
>
> * opts.c (comman_handle_option): Ignore -fuse-ld=bfd and
> -fuse-ld=gold.
>
> * doc/invoke.texi: Document -fuse-ld=bfd and -fuse-ld=gold.

Ping.

-- 
H.J.


[PATCH] Fix vectorizer ICE (PR tree-optimization/55831)

2012-12-31 Thread Jakub Jelinek
Hi!

The following testcase ICEs because get_initial_def_for_induction inserts
stmts before gsi_start_bb, which is wrong for basic blocks that start with
labels, as then the labels are in the middle of a basic block.

Ok for trunk?

2012-12-31  Jakub Jelinek  

PR tree-optimization/55831
* tree-vect-loop.c (get_initial_def_for_induction): Use
gsi_after_labels instead of gsi_start_bb.

* gcc.dg/pr55831.c: New test.

--- gcc/tree-vect-loop.c.jj 2012-11-27 14:33:14.0 +0100
+++ gcc/tree-vect-loop.c2012-12-31 15:10:02.211716876 +0100
@@ -3406,7 +3406,7 @@ get_initial_def_for_induction (gimple iv
  build1 (VIEW_CONVERT_EXPR, resvectype, induc_def), NULL_TREE);
   induc_def = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
   gimple_assign_set_lhs (new_stmt, induc_def);
-  si = gsi_start_bb (bb);
+  si = gsi_after_labels (bb);
   gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
   set_vinfo_for_stmt (new_stmt,
  new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
--- gcc/testsuite/gcc.dg/pr55831.c.jj   2012-12-31 15:25:11.484514159 +0100
+++ gcc/testsuite/gcc.dg/pr55831.c  2012-12-31 15:13:35.0 +0100
@@ -0,0 +1,22 @@
+/* PR tree-optimization/55831 */
+/* { dg-do compile } */
+/* { dg-options "-O -fstrict-overflow -ftree-vectorize -Wno-unused-label" } */
+
+int g;
+short p, q;
+
+void
+f (void)
+{
+  short a = p, b = q, i;
+
+  if (a)
+{
+label:
+  for (i = 0; i < 8; i++)
+   b ^= a++;
+
+  if (!b)
+   g = 0;
+}
+}

Jakub


Re: [PATCH] Fix vectorizer ICE (PR tree-optimization/55831)

2012-12-31 Thread Richard Biener
On Mon, Dec 31, 2012 at 4:26 PM, Jakub Jelinek  wrote:
> Hi!
>
> The following testcase ICEs because get_initial_def_for_induction inserts
> stmts before gsi_start_bb, which is wrong for basic blocks that start with
> labels, as then the labels are in the middle of a basic block.
>
> Ok for trunk?

Obvious indeed.

Thanks,
Richard.

> 2012-12-31  Jakub Jelinek  
>
> PR tree-optimization/55831
> * tree-vect-loop.c (get_initial_def_for_induction): Use
> gsi_after_labels instead of gsi_start_bb.
>
> * gcc.dg/pr55831.c: New test.
>
> --- gcc/tree-vect-loop.c.jj 2012-11-27 14:33:14.0 +0100
> +++ gcc/tree-vect-loop.c2012-12-31 15:10:02.211716876 +0100
> @@ -3406,7 +3406,7 @@ get_initial_def_for_induction (gimple iv
>   build1 (VIEW_CONVERT_EXPR, resvectype, induc_def), NULL_TREE);
>induc_def = make_ssa_name (gimple_assign_lhs (new_stmt), new_stmt);
>gimple_assign_set_lhs (new_stmt, induc_def);
> -  si = gsi_start_bb (bb);
> +  si = gsi_after_labels (bb);
>gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
>set_vinfo_for_stmt (new_stmt,
>   new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
> --- gcc/testsuite/gcc.dg/pr55831.c.jj   2012-12-31 15:25:11.484514159 +0100
> +++ gcc/testsuite/gcc.dg/pr55831.c  2012-12-31 15:13:35.0 +0100
> @@ -0,0 +1,22 @@
> +/* PR tree-optimization/55831 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -fstrict-overflow -ftree-vectorize -Wno-unused-label" } 
> */
> +
> +int g;
> +short p, q;
> +
> +void
> +f (void)
> +{
> +  short a = p, b = q, i;
> +
> +  if (a)
> +{
> +label:
> +  for (i = 0; i < 8; i++)
> +   b ^= a++;
> +
> +  if (!b)
> +   g = 0;
> +}
> +}
>
> Jakub


Re: [Patch, Fortran] FINAL (prep patches 2/5): Add internal STRIDE intrinsicg

2012-12-31 Thread Steve Kargl
On Mon, Dec 31, 2012 at 01:17:04PM +0100, Tobias Burnus wrote:
> The attached patch adds a new - internal only - intrinsic, STRIDE, which 
> returns the stride of an array with array descriptor; for an "integer :: 
> array(5,5)", the stride of dim=2 is 5.
> 
> This new intrinsic is only internally available and will be used by the 
> finalization wrapper to handle noncontiguous arrays.
> 

What is the plan for when J3 decides to add a
STRIDE intrinsic to Fortran20xy, which may
have different semantics to what your function
does?

At a minimum, please consider adding a leading
underscore to the function.  This will clearly
never conflict with a future Fortran standard
(unless J3 looses it collected mind).

-- 
Steve


Re: [Patch, Fortran] FINAL (prep patches 2/5): Add internal STRIDE intrinsicg

2012-12-31 Thread Tobias Burnus

Hi Steve,

Steve Kargl:

On Mon, Dec 31, 2012 at 01:17:04PM +0100, Tobias Burnus wrote:

This new intrinsic is only internally available and will be used by the
finalization wrapper to handle noncontiguous arrays.

What is the plan for when J3 decides to add a
STRIDE intrinsic


Well, we then add it. As written, this intrinsic is *only* *internally* 
available.


Actually, I do hope that J3 will add a better access to Fortran's array 
descriptor. Currently, one can do a lot of manipulations from C (since 
ISO/IEC TS 29113:2012) but not from Fortran. The better access from 
Fortran also matches the wish of the UK's BSI Fortran Panel: 
ftp://ftp.nag.co.uk/sc22wg5/N1901-N1950/N1923.pdf (4th non-indent 
paragraph).



At a minimum, please consider adding a leading underscore to the function.


If you had read the patch carefully, you had seen that the intrinsic is 
defined as GFC_PREFIX ("stride"), which expands on most systems to 
"_F._stride".


However, even if I had named it "stride" it were not available as it is 
marked as "make_from_module();". The latter implies that 
gfc_find_function (name)  won't find it. You have to use a symbol which 
has  "sym->intmod_sym_id" set - which is not possible from the user code.


The  "make_from_module();" technique has been added for procedures like 
"c_sizeof" which should be handled via the normal intrinsic handling 
(intrinsic.c, check.c, iresolve.c, trans-intrinsic.c), but where the 
procedure should only be available after using "USE ISO_C_BINDING".


By the way, the symbol also never appears in the tree / assembler as it 
is converted into the respective component access of the array 
descriptor, e.g.  "variable.dim[i].stride".


Tobias


Re: [Patch, Fortran] FINAL (prep patches 2/5): Add internal STRIDE intrinsicg

2012-12-31 Thread Steve Kargl
On Mon, Dec 31, 2012 at 08:19:49PM +0100, Tobias Burnus wrote:
> Hi Steve,
> 
> Steve Kargl:
> > On Mon, Dec 31, 2012 at 01:17:04PM +0100, Tobias Burnus wrote:
> >> This new intrinsic is only internally available and will be used by the
> >> finalization wrapper to handle noncontiguous arrays.
> > What is the plan for when J3 decides to add a
> > STRIDE intrinsic
> 
> Well, we then add it. As written, this intrinsic is *only* *internally* 
> available.
> 
> Actually, I do hope that J3 will add a better access to Fortran's array 
> descriptor. Currently, one can do a lot of manipulations from C (since 
> ISO/IEC TS 29113:2012) but not from Fortran. The better access from 
> Fortran also matches the wish of the UK's BSI Fortran Panel: 
> ftp://ftp.nag.co.uk/sc22wg5/N1901-N1950/N1923.pdf (4th non-indent 
> paragraph).
> 
> > At a minimum, please consider adding a leading underscore to the function.
> 
> If you had read the patch carefully, you had seen that the intrinsic is 
> defined as GFC_PREFIX ("stride"), which expands on most systems to 
> "_F._stride".
> 

Ah, I did miss the GFC_PREFIX declaration.  I was going off
your (mis)description of what you were adding to the list
of intrinsics.  Namely, you stated you were adding a STRIDE
intrinsic when in fact you are adding a GFC_PREFIX("stride")
intrinsic.

-- 
Steve