builtins.def (BUILT_IN_STACK_ALLOC): Remove.
authorRichard Henderson <rth@redhat.com>
Wed, 11 Aug 2004 04:16:07 +0000 (21:16 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 11 Aug 2004 04:16:07 +0000 (21:16 -0700)
        * builtins.def (BUILT_IN_STACK_ALLOC): Remove.
        * builtins.c (expand_builtin) <BUILT_IN_STACK_ALLOC>: Remove.
        * dwarf2out.c (loc_descriptor): Handle PARALLEL here ...
        (add_location_or_const_value_attribute): ... not here.  Use
        loc_descriptor_from_tree if possible.
        (loc_descriptor_from_tree_1): Rename from loc_descriptor_from_tree.
        Simplify address handling.  Handle DECL_VALUE_EXPR.  Handle register
        values specially.
        (loc_descriptor_from_tree): New.  Update callers.
        * expr.c (expand_var): Ignore DECL_VALUE_EXPR variables.
        * gimplify.c (gimplify_decl_expr): Lower variable sized types to
        pointer plus dereference.  Set DECL_VALUE_EXPR.  Set save_stack.
        (gimplify_call_expr): Do not recognize BUILT_IN_STACK_ALLOC
        and BUILT_IN_STACK_RESTORE.
        (gimplify_expr): Lower DECL_VALUE_EXPR decls.
        * stmt.c (expand_stack_alloc): Remove.
        * tree-mudflap.c (mx_register_decls): Don't look for
        BUILT_IN_STACK_ALLOC.
        * tree-nested.c (convert_local_reference): Likewise.
        * tree.h (DECL_VALUE_EXPR): New.
ada/
        * utils.c (gnat_install_builtins): Remove __builtin_stack_alloc,
        add __builtin_alloca.
fortran/
        * f95-lang.c (gfc_init_builtin_functions): Remove
         __builtin_stack_alloc, add __builtin_alloca.
        * trans-array.c (gfc_trans_auto_array_allocation): Use DECL_EXPR.
        * trans-decl.c (gfc_trans_auto_character_variable): Likewise.

From-SVN: r85794

16 files changed:
gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/utils.c
gcc/builtins.c
gcc/builtins.def
gcc/dwarf2out.c
gcc/expr.c
gcc/fortran/ChangeLog
gcc/fortran/f95-lang.c
gcc/fortran/trans-array.c
gcc/fortran/trans-decl.c
gcc/gimplify.c
gcc/stmt.c
gcc/tree-mudflap.c
gcc/tree-nested.c
gcc/tree.h

index a51da9b7310715a0e286b89599700e6c937ec605..ffa4aeeaa88edafe74100446605dfec5cfcdf6ed 100644 (file)
@@ -1,3 +1,26 @@
+2004-08-10  Richard Henderson  <rth@redhat.com>
+
+       * builtins.def (BUILT_IN_STACK_ALLOC): Remove.
+       * builtins.c (expand_builtin) <BUILT_IN_STACK_ALLOC>: Remove.
+       * dwarf2out.c (loc_descriptor): Handle PARALLEL here ...
+       (add_location_or_const_value_attribute): ... not here.  Use
+       loc_descriptor_from_tree if possible.
+       (loc_descriptor_from_tree_1): Rename from loc_descriptor_from_tree.
+       Simplify address handling.  Handle DECL_VALUE_EXPR.  Handle register
+       values specially.
+       (loc_descriptor_from_tree): New.  Update callers.
+       * expr.c (expand_var): Ignore DECL_VALUE_EXPR variables.
+       * gimplify.c (gimplify_decl_expr): Lower variable sized types to
+       pointer plus dereference.  Set DECL_VALUE_EXPR.  Set save_stack.
+       (gimplify_call_expr): Do not recognize BUILT_IN_STACK_ALLOC
+       and BUILT_IN_STACK_RESTORE.
+       (gimplify_expr): Lower DECL_VALUE_EXPR decls.
+       * stmt.c (expand_stack_alloc): Remove.
+       * tree-mudflap.c (mx_register_decls): Don't look for
+       BUILT_IN_STACK_ALLOC.
+       * tree-nested.c (convert_local_reference): Likewise.
+       * tree.h (DECL_VALUE_EXPR): New.
+
 2004-08-10  Richard Henderson  <rth@redhat.com>
 
        * stor-layout.c (round_up): Check for 0/1 before dividing.
index 071390196ef23a485f8e096b1e922b20552828b1..9cb2dfdb4a91cef2e65d38dacfa3c340d5bf41bd 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-10  Richard Henderson  <rth@redhat.com>
+
+       * utils.c (gnat_install_builtins): Remove __builtin_stack_alloc,
+       add __builtin_alloca.
+
 2004-08-10  Richard Henderson  <rth@redhat.com>
 
        * config-lang.in (boot_language): Yes.
index 46c5639480b6e1768cb4168ef96d9aef17f186b0..4f2362981c5f003903ae4d360ffd9585416f9556 100644 (file)
@@ -481,6 +481,9 @@ gnat_install_builtins ()
   gnat_define_builtin ("__builtin_clzll", ftype, BUILT_IN_CLZLL, "clzll",
                       true);
 
+  /* The init_trampoline and adjust_trampoline builtins aren't used directly.
+     They are inserted during lowering of nested functions.  */
+
   tmp = tree_cons (NULL_TREE, ptr_void_type_node, void_list_node);
   tmp = tree_cons (NULL_TREE, ptr_void_type_node, tmp);
   tmp = tree_cons (NULL_TREE, ptr_void_type_node, tmp);
@@ -493,21 +496,24 @@ gnat_install_builtins ()
   gnat_define_builtin ("__builtin_adjust_trampoline", ftype,
                       BUILT_IN_ADJUST_TRAMPOLINE, "adjust_trampoline", true);
 
-  tmp = tree_cons (NULL_TREE, ptr_void_type_node, void_list_node);
-  tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
-  ftype = build_function_type (ptr_void_type_node, tmp);
-  gnat_define_builtin ("__builtin_stack_alloc", ftype, BUILT_IN_STACK_ALLOC,
-                      "stack_alloc", false);
+  /* The stack_save, stack_restore, and alloca builtins aren't used directly.
+     They are inserted during gimplification to implement variable sized stack
+     allocation.  */
 
-  /* The stack_save and stack_restore builtins aren't used directly.  They
-     are inserted during gimplification to implement stack_alloc calls.  */
   ftype = build_function_type (ptr_void_type_node, void_list_node);
   gnat_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
                       "stack_save", false);
+
   tmp = tree_cons (NULL_TREE, ptr_void_type_node, void_list_node);
   ftype = build_function_type (void_type_node, tmp);
   gnat_define_builtin ("__builtin_stack_restore", ftype,
                       BUILT_IN_STACK_RESTORE, "stack_restore", false);
+
+  tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
+  ftype = build_function_type (ptr_void_type_node, tmp);
+  gnat_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA,
+                      "alloca", false);
+
 }
 
 /* Create the predefined scalar types such as `integer_type_node' needed
index bb32f1202e94efe9c4bc8fb385fc15bed345e6ea..fb852ff0b55d4db45ce107ae461ad364a3b3d1f1 100644 (file)
@@ -5756,11 +5756,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
        return target;
       break;
 
-    case BUILT_IN_STACK_ALLOC:
-      expand_stack_alloc (TREE_VALUE (arglist),
-                         TREE_VALUE (TREE_CHAIN (arglist)));
-      return const0_rtx;
-
     case BUILT_IN_STACK_SAVE:
       return expand_stack_save ();
 
index d660f8d590e1fbab1ac927692b73ae56ba295260..1cfbf7129994efc06cf6252207a1def53db2c3ea 100644 (file)
@@ -607,7 +607,6 @@ DEF_GCC_BUILTIN        (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN
 DEF_GCC_BUILTIN        (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
-DEF_GCC_BUILTIN        (BUILT_IN_STACK_ALLOC, "stack_alloc", BT_FN_VOID_PTR_SIZE, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_STACK_SAVE, "stack_save", BT_FN_PTR, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_STACK_RESTORE, "stack_restore", BT_FN_VOID_PTR, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_STDARG_START, "stdarg_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
index 46b3b512660460320e747858d5e74fefc4c4891e..242a653b278bcba7c7ebb7a680d6271aba7539d7 100644 (file)
@@ -3907,7 +3907,8 @@ static int is_based_loc (rtx);
 static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode, bool);
 static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
 static dw_loc_descr_ref loc_descriptor (rtx, bool);
-static dw_loc_descr_ref loc_descriptor_from_tree (tree, int);
+static dw_loc_descr_ref loc_descriptor_from_tree_1 (tree, int);
+static dw_loc_descr_ref loc_descriptor_from_tree (tree);
 static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
 static tree field_type (tree);
 static unsigned int simple_type_align_in_bits (tree);
@@ -8805,34 +8806,38 @@ loc_descriptor (rtx rtl, bool can_use_fbreg)
       if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
        {
          loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0), can_use_fbreg);
+         break;
        }
-      /* Multiple parts.  */
-      else
-       {
-         rtvec par_elems = XVEC (XEXP (rtl, 1), 0);
-         int num_elem = GET_NUM_ELEM (par_elems);
-         enum machine_mode mode;
-         int i;
 
-         /* Create the first one, so we have something to add to.  */
-         loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
-                                      can_use_fbreg);
-         mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
-         add_loc_descr (&loc_result,
-                        new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
-         for (i = 1; i < num_elem; i++)
-           {
-             dw_loc_descr_ref temp;
+      rtl = XEXP (rtl, 1);
+      /* FALLTHRU */
 
-             temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
+    case PARALLEL:
+      {
+       rtvec par_elems = XVEC (rtl, 0);
+       int num_elem = GET_NUM_ELEM (par_elems);
+       enum machine_mode mode;
+       int i;
+
+       /* Create the first one, so we have something to add to.  */
+       loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
                                     can_use_fbreg);
-             add_loc_descr (&loc_result, temp);
-             mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
-             add_loc_descr (&loc_result,
-                            new_loc_descr (DW_OP_piece,
-                                           GET_MODE_SIZE (mode), 0));
-           }
-       }
+       mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
+       add_loc_descr (&loc_result,
+                      new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
+       for (i = 1; i < num_elem; i++)
+         {
+           dw_loc_descr_ref temp;
+
+           temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
+                                  can_use_fbreg);
+           add_loc_descr (&loc_result, temp);
+           mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
+           add_loc_descr (&loc_result,
+                          new_loc_descr (DW_OP_piece,
+                                         GET_MODE_SIZE (mode), 0));
+         }
+      }
       break;
 
     default:
@@ -8843,15 +8848,16 @@ loc_descriptor (rtx rtl, bool can_use_fbreg)
 }
 
 /* Similar, but generate the descriptor from trees instead of rtl.  This comes
-   up particularly with variable length arrays.  If ADDRESSP is nonzero, we are
-   looking for an address.  Otherwise, we return a value.  If we can't make a
-   descriptor, return 0.  */
+   up particularly with variable length arrays.  WANT_ADDRESS is 2 if this is
+   a top-level invocation of loc_descriptor_from_tree; is 1 if this is not a
+   top-level invocation, and we require the address of LOC; is 0 if we require
+   the value of LOC.  */
 
 static dw_loc_descr_ref
-loc_descriptor_from_tree (tree loc, int addressp)
+loc_descriptor_from_tree_1 (tree loc, int want_address)
 {
   dw_loc_descr_ref ret, ret1;
-  int indirect_p = 0;
+  int have_address = 0;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (loc));
   enum dwarf_location_atom op;
 
@@ -8882,19 +8888,12 @@ loc_descriptor_from_tree (tree loc, int addressp)
       return 0;
 
     case ADDR_EXPR:
-      /* We can support this only if we can look through conversions and
-        find an INDIRECT_EXPR.  */
-      for (loc = TREE_OPERAND (loc, 0);
-          TREE_CODE (loc) == CONVERT_EXPR || TREE_CODE (loc) == NOP_EXPR
-          || TREE_CODE (loc) == NON_LVALUE_EXPR
-          || TREE_CODE (loc) == VIEW_CONVERT_EXPR
-          || TREE_CODE (loc) == SAVE_EXPR;
-          loc = TREE_OPERAND (loc, 0))
-       ;
+      /* If we already want an address, there's nothing we can do.  */
+      if (want_address)
+       return 0;
 
-       return (TREE_CODE (loc) == INDIRECT_REF
-              ? loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp)
-              : 0);
+      /* Otherwise, process the argument and look for the address.  */
+      return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 1);
 
     case VAR_DECL:
       if (DECL_THREAD_LOCAL (loc))
@@ -8928,47 +8927,63 @@ loc_descriptor_from_tree (tree loc, int addressp)
          ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
          add_loc_descr (&ret, ret1);
 
-         indirect_p = 1;
+         have_address = 1;
          break;
        }
-      /* Fall through.  */
+      /* FALLTHRU */
 
     case PARM_DECL:
+      if (DECL_VALUE_EXPR (loc))
+       return loc_descriptor_from_tree_1 (DECL_VALUE_EXPR (loc), want_address);
+      /* FALLTHRU */
+
     case RESULT_DECL:
       {
        rtx rtl = rtl_for_decl_location (loc);
 
        if (rtl == NULL_RTX)
          return 0;
+        else if (GET_CODE (rtl) == CONST_INT)
+         {
+           HOST_WIDE_INT val = INTVAL (rtl);
+           if (TYPE_UNSIGNED (TREE_TYPE (loc)))
+             val &= GET_MODE_MASK (DECL_MODE (loc));
+           ret = int_loc_descriptor (val);
+         }
+       else if (GET_CODE (rtl) == CONST_STRING)
+         return 0;
        else if (CONSTANT_P (rtl))
          {
            ret = new_loc_descr (DW_OP_addr, 0, 0);
            ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
            ret->dw_loc_oprnd1.v.val_addr = rtl;
-           indirect_p = 1;
          }
        else
          {
-           enum machine_mode mode = GET_MODE (rtl);
+           enum machine_mode mode;
+
+           /* Certain constructs can only be represented at top-level.  */
+           if (want_address == 2)
+             return loc_descriptor (rtl, true);
 
+           mode = GET_MODE (rtl);
            if (MEM_P (rtl))
              {
-               indirect_p = 1;
                rtl = XEXP (rtl, 0);
+               have_address = 1;
              }
-
            ret = mem_loc_descriptor (rtl, mode, true);
          }
       }
       break;
 
     case INDIRECT_REF:
-      ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
-      indirect_p = 1;
+      ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
+      have_address = 1;
       break;
 
     case COMPOUND_EXPR:
-      return loc_descriptor_from_tree (TREE_OPERAND (loc, 1), addressp);
+      return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), want_address);
 
     case NOP_EXPR:
     case CONVERT_EXPR:
@@ -8976,7 +8991,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
     case VIEW_CONVERT_EXPR:
     case SAVE_EXPR:
     case MODIFY_EXPR:
-      return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp);
+      return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), want_address);
 
     case COMPONENT_REF:
     case BIT_FIELD_REF:
@@ -8994,7 +9009,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
        if (obj == loc)
          return 0;
 
-       ret = loc_descriptor_from_tree (obj, 1);
+       ret = loc_descriptor_from_tree_1 (obj, 1);
        if (ret == 0
            || bitpos % BITS_PER_UNIT != 0 || bitsize % BITS_PER_UNIT != 0)
          return 0;
@@ -9002,13 +9017,10 @@ loc_descriptor_from_tree (tree loc, int addressp)
        if (offset != NULL_TREE)
          {
            /* Variable offset.  */
-           add_loc_descr (&ret, loc_descriptor_from_tree (offset, 0));
+           add_loc_descr (&ret, loc_descriptor_from_tree_1 (offset, 0));
            add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
          }
 
-       if (!addressp)
-         indirect_p = 1;
-
        bytepos = bitpos / BITS_PER_UNIT;
        if (bytepos > 0)
          add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst, bytepos, 0));
@@ -9017,6 +9029,8 @@ loc_descriptor_from_tree (tree loc, int addressp)
            add_loc_descr (&ret, int_loc_descriptor (bytepos));
            add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
          }
+
+       have_address = 1;
        break;
       }
 
@@ -9033,15 +9047,12 @@ loc_descriptor_from_tree (tree loc, int addressp)
        rtx rtl = lookup_constant_def (loc);
        enum machine_mode mode;
 
-       if (!MEM_P (rtl))
+       if (!rtl || !MEM_P (rtl))
          return 0;
        mode = GET_MODE (rtl);
        rtl = XEXP (rtl, 0);
-
-       rtl = targetm.delegitimize_address (rtl);
-
-       indirect_p = 1;
        ret = mem_loc_descriptor (rtl, mode, true);
+       have_address = 1;
        break;
       }
 
@@ -9096,7 +9107,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
       if (TREE_CODE (TREE_OPERAND (loc, 1)) == INTEGER_CST
          && host_integerp (TREE_OPERAND (loc, 1), 0))
        {
-         ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
+         ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
          if (ret == 0)
            return 0;
 
@@ -9148,8 +9159,8 @@ loc_descriptor_from_tree (tree loc, int addressp)
       goto do_binop;
 
     do_binop:
-      ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
-      ret1 = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
+      ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
+      ret1 = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), 0);
       if (ret == 0 || ret1 == 0)
        return 0;
 
@@ -9171,7 +9182,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
       goto do_unop;
 
     do_unop:
-      ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
+      ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
       if (ret == 0)
        return 0;
 
@@ -9187,7 +9198,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
         loc = build3 (COND_EXPR, TREE_TYPE (loc),
                      build2 (code, integer_type_node,
                              TREE_OPERAND (loc, 0), TREE_OPERAND (loc, 1)),
-                     TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0));
+                      TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0));
       }
 
       /* ... fall through ...  */
@@ -9195,12 +9206,12 @@ loc_descriptor_from_tree (tree loc, int addressp)
     case COND_EXPR:
       {
        dw_loc_descr_ref lhs
-         = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0);
+         = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), 0);
        dw_loc_descr_ref rhs
-         = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0);
+         = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 2), 0);
        dw_loc_descr_ref bra_node, jump_node, tmp;
 
-       ret = loc_descriptor_from_tree (TREE_OPERAND (loc, 0), 0);
+       ret = loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 0), 0);
        if (ret == 0 || lhs == 0 || rhs == 0)
          return 0;
 
@@ -9236,11 +9247,11 @@ loc_descriptor_from_tree (tree loc, int addressp)
     }
 
   /* Show if we can't fill the request for an address.  */
-  if (addressp && indirect_p == 0)
+  if (want_address && !have_address)
     return 0;
 
   /* If we've got an address and don't want one, dereference.  */
-  if (!addressp && indirect_p > 0)
+  if (!want_address && have_address)
     {
       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
 
@@ -9257,6 +9268,12 @@ loc_descriptor_from_tree (tree loc, int addressp)
   return ret;
 }
 
+static inline dw_loc_descr_ref
+loc_descriptor_from_tree (tree loc)
+{
+  return loc_descriptor_from_tree_1 (loc, 2);
+}
+
 /* Given a value, round it up to the lowest multiple of `boundary'
    which is not less than the value itself.  */
 
@@ -10072,72 +10089,15 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
     }
 
   rtl = rtl_for_decl_location (decl);
-  if (rtl == NULL_RTX)
-    return;
-
-  switch (GET_CODE (rtl))
+  if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING))
     {
-    case CONST_INT:
-    case CONST_DOUBLE:
-    case CONST_VECTOR:
-    case CONST_STRING:
-    case SYMBOL_REF:
-    case LABEL_REF:
-    case CONST:
-    case PLUS:
-      /* DECL_RTL could be (plus (reg ...) (const_int ...)) */
       add_const_value_attribute (die, rtl);
-      break;
-
-    case MEM:
-      if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
-       {
-         /* Need loc_descriptor_from_tree since that's where we know
-            how to handle TLS variables.  Want the object's address
-            since the top-level DW_AT_location assumes such.  See
-            the confusion in loc_descriptor for reference.  */
-         descr = loc_descriptor_from_tree (decl, 1);
-       }
-      else
-       {
-       case REG:
-       case SUBREG:
-       case CONCAT:
-         descr = loc_descriptor (rtl, true);
-       }
-      add_AT_location_description (die, attr, descr);
-      break;
-
-    case PARALLEL:
-      {
-       rtvec par_elems = XVEC (rtl, 0);
-       int num_elem = GET_NUM_ELEM (par_elems);
-       enum machine_mode mode;
-       int i;
-
-       /* Create the first one, so we have something to add to.  */
-       descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0), true);
-       mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
-       add_loc_descr (&descr,
-                      new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
-       for (i = 1; i < num_elem; i++)
-         {
-           dw_loc_descr_ref temp;
-
-           temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0), true);
-           add_loc_descr (&descr, temp);
-           mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
-           add_loc_descr (&descr,
-                          new_loc_descr (DW_OP_piece,
-                                         GET_MODE_SIZE (mode), 0));
-         }
-      }
-      add_AT_location_description (die, DW_AT_location, descr);
-      break;
-
-    default:
-      abort ();
+      return;
     }
+
+  descr = loc_descriptor_from_tree (decl);
+  if (descr)
+    add_AT_location_description (die, attr, descr);
 }
 
 /* If we don't have a copy of this variable in memory for some reason (such
@@ -10254,7 +10214,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
        dw_die_ref ctx, decl_die;
        dw_loc_descr_ref loc;
 
-       loc = loc_descriptor_from_tree (bound, 0);
+       loc = loc_descriptor_from_tree (bound);
        if (loc == NULL)
          break;
 
@@ -11388,7 +11348,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 
       if (cfun->static_chain_decl)
        add_AT_location_description (subr_die, DW_AT_static_link,
-                loc_descriptor_from_tree (cfun->static_chain_decl, 0));
+                loc_descriptor_from_tree (cfun->static_chain_decl));
     }
 
   /* Now output descriptions of the arguments for this function. This gets
index 7741830033ec740cacdf5024302b62e19a222aaa..282bb9af57d9233e11839e92525cc18b47088d81 100644 (file)
@@ -6008,20 +6008,8 @@ expand_var (tree var)
       ? !TREE_ASM_WRITTEN (var)
       : !DECL_RTL_SET_P (var))
     {
-      if (TREE_CODE (var) == VAR_DECL && DECL_DEFER_OUTPUT (var))
-       {
-         /* Prepare a mem & address for the decl.  */
-         rtx x;
-
-         if (TREE_STATIC (var))
-           abort ();
-
-         x = gen_rtx_MEM (DECL_MODE (var),
-                          gen_reg_rtx (Pmode));
-
-         set_mem_attributes (x, var, 1);
-         SET_DECL_RTL (var, x);
-       }
+      if (TREE_CODE (var) == VAR_DECL && DECL_VALUE_EXPR (var))
+       /* Should be ignored.  */;
       else if (lang_hooks.expand_decl (var))
        /* OK.  */;
       else if (TREE_CODE (var) == VAR_DECL && !TREE_STATIC (var))
index 1dd0bc32d026d630747bd99d2aebdc1a800a7e4c..b45197dd191bebe146b68020d6c6d970ae03ef28 100644 (file)
@@ -1,3 +1,10 @@
+2004-08-10  Richard Henderson  <rth@redhat.com>
+
+       * f95-lang.c (gfc_init_builtin_functions): Remove
+        __builtin_stack_alloc, add __builtin_alloca.
+       * trans-array.c (gfc_trans_auto_array_allocation): Use DECL_EXPR.
+       * trans-decl.c (gfc_trans_auto_character_variable): Likewise.
+
 2004-08-10  Paul Brook  <paul@codesourcery.com>
 
        * trans-io.c (transfer_expr): Handle pointters.
index 78bf19a924b80d5e49b215afea4da441fd788ec0..3e8320c3f44de2847b5d61f71a8e51ab6dbb3ba7 100644 (file)
@@ -794,21 +794,23 @@ gfc_init_builtin_functions (void)
   gfc_define_builtin ("__builtin_adjust_trampoline", ftype,
                      BUILT_IN_ADJUST_TRAMPOLINE, "adjust_trampoline", true);
 
-  tmp = tree_cons (NULL_TREE, pvoid_type_node, void_list_node);
-  tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
-  ftype = build_function_type (pvoid_type_node, tmp);
-  gfc_define_builtin ("__builtin_stack_alloc", ftype, BUILT_IN_STACK_ALLOC,
-                     "stack_alloc", false);
+  /* The stack_save, stack_restore, and alloca builtins aren't used directly.
+     They are inserted during gimplification to implement variable sized
+     stack allocation.  */
 
-  /* The stack_save and stack_restore builtins aren't used directly.  They
-     are inserted during gimplification to implement stack_alloc calls.  */
   ftype = build_function_type (pvoid_type_node, void_list_node);
   gfc_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
                      "stack_save", false);
+
   tmp = tree_cons (NULL_TREE, pvoid_type_node, void_list_node);
   ftype = build_function_type (void_type_node, tmp);
   gfc_define_builtin ("__builtin_stack_restore", ftype, BUILT_IN_STACK_RESTORE,
                      "stack_restore", false);
+
+  tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
+  ftype = build_function_type (pvoid_type_node, tmp);
+  gfc_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA,
+                     "alloca", false);
 }
 
 #undef DEFINE_MATH_BUILTIN
index bc825bb00cf1a863199a530972d1fd247afca901..e267ebf2287d528a8d4ccff7eaebf5b3ceec0f05 100644 (file)
@@ -2926,15 +2926,9 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, tree fnbody)
     {
       gfc_trans_init_string_length (sym->ts.cl, &block);
 
-      DECL_DEFER_OUTPUT (decl) = 1;
-
-      /* Generate code to allocate the automatic variable.  It will be
-        freed automatically.  */
-      tmp = gfc_build_addr_expr (NULL, decl);
-      args = gfc_chainon_list (NULL_TREE, tmp);
-      args = gfc_chainon_list (args, sym->ts.cl->backend_decl);
-      tmp = gfc_build_function_call (built_in_decls[BUILT_IN_STACK_ALLOC],
-                                    args);
+      /* Emit a DECL_EXPR for this variable, which will cause the
+        gimplifier to allocate stoage, and all that good stuff.  */
+      tmp = build (DECL_EXPR, TREE_TYPE (decl), decl);
       gfc_add_expr_to_block (&block, tmp);
     }
 
index 5c68cb57348c6e02a882bc2beb84677937fc4157..4710e150fa0178728e32d3ea46168e4b980bd126 100644 (file)
@@ -1626,7 +1626,6 @@ gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody)
 {
   stmtblock_t body;
   tree decl;
-  tree args;
   tree tmp;
 
   assert (sym->backend_decl);
@@ -1639,23 +1638,11 @@ gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody)
 
   decl = sym->backend_decl;
 
-  DECL_DEFER_OUTPUT (decl) = 1;
-
-  /* Since we don't use a DECL_STMT or equivalent, we have to deal
-     with getting these gimplified.  But we can't gimplify it yet since
-     we're still generating statements.
-
-     ??? This should be cleaned up and handled like other front ends.  */
-  gfc_add_expr_to_block (&body, save_expr (DECL_SIZE (decl)));
-  gfc_add_expr_to_block (&body, save_expr (DECL_SIZE_UNIT (decl)));
-
-  /* Generate code to allocate the automatic variable.  It will be freed
-     automatically.  */
-  tmp = gfc_build_addr_expr (NULL, decl);
-  args = gfc_chainon_list (NULL_TREE, tmp);
-  args = gfc_chainon_list (args, sym->ts.cl->backend_decl);
-  tmp = gfc_build_function_call (built_in_decls[BUILT_IN_STACK_ALLOC], args);
+  /* Emit a DECL_EXPR for this variable, which will cause the
+     gimplifier to allocate stoage, and all that good stuff.  */
+  tmp = build (DECL_EXPR, TREE_TYPE (decl), decl);
   gfc_add_expr_to_block (&body, tmp);
+
   gfc_add_expr_to_block (&body, fnbody);
   return gfc_finish_block (&body);
 }
index 3675c8a942f8e917f2bca9e896735e765d6ac626..8a8679b54de83e0d34bb94c403b75090e2335e4d 100644 (file)
@@ -976,20 +976,34 @@ gimplify_decl_expr (tree *stmt_p)
          /* This is a variable-sized decl.  Simplify its size and mark it
             for deferred expansion.  Note that mudflap depends on the format
             of the emitted code: see mx_register_decls().  */
-         tree t, args;
+         tree t, args, addr, ptr_type;
 
          gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
          gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
          gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
 
+         /* All occurences of this decl in final gimplified code will be
+            replaced by indirection.  Setting DECL_VALUE_EXPR does two
+            things: First, it lets the rest of the gimplifier know what
+            replacement to use.  Second, it lets the debug info know 
+            where to find the value.  */
+         ptr_type = build_pointer_type (TREE_TYPE (decl));
+         addr = create_tmp_var (ptr_type, get_name (decl));
+         DECL_IGNORED_P (addr) = 0;
+         t = build_fold_indirect_ref (addr);
+         DECL_VALUE_EXPR (decl) = t;
+
          args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
-         t = build_fold_addr_expr (decl);
-         args = tree_cons (NULL, t, args);
-         t = implicit_built_in_decls[BUILT_IN_STACK_ALLOC];
+         t = built_in_decls[BUILT_IN_ALLOCA];
          t = build_function_call_expr (t, args);
+         t = fold_convert (ptr_type, t);
+         t = build2 (MODIFY_EXPR, void_type_node, addr, t);
 
          gimplify_and_add (t, stmt_p);
-         DECL_DEFER_OUTPUT (decl) = 1;
+
+         /* Indicate that we need to restore the stack level when the
+            enclosing BIND_EXPR is exited.  */
+         gimplify_ctxp->save_stack = true;
        }
 
       if (init && init != error_mark_node)
@@ -1834,20 +1848,7 @@ gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
   decl = get_callee_fndecl (*expr_p);
   if (decl && DECL_BUILT_IN (decl))
     {
-      tree new;
-
-      /* If it is allocation of stack, record the need to restore the memory
-        when the enclosing bind_expr is exited.  */
-      if (DECL_FUNCTION_CODE (decl) == BUILT_IN_STACK_ALLOC)
-       gimplify_ctxp->save_stack = true;
-
-      /* If it is restore of the stack, reset it, since it means we are
-        regimplifying the bind_expr.  Note that we use the fact that
-        for try_finally_expr, try part is processed first.  */
-      if (DECL_FUNCTION_CODE (decl) == BUILT_IN_STACK_RESTORE)
-       gimplify_ctxp->save_stack = false;
-
-      new = simplify_builtin (*expr_p, !want_value);
+      tree new = simplify_builtin (*expr_p, !want_value);
 
       if (new && new != *expr_p)
        {
@@ -3781,9 +3782,19 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
                abort ();
 #endif
              ret = GS_ERROR;
+             break;
            }
-         else
-           ret = GS_ALL_DONE;
+
+         /* If this is a local variable sized decl, it must be accessed
+            indirectly.  Perform that substitution.  */
+         if (DECL_VALUE_EXPR (tmp))
+           {
+             *expr_p = unshare_expr (DECL_VALUE_EXPR (tmp));
+             ret = GS_OK;
+             break;
+           }
+
+         ret = GS_ALL_DONE;
          break;
 
        case SSA_NAME:
index 8164c2d269f53b2d3010bed20710efbd4fe14aaf..86d4fe98dd36e79829bc32a6e6c29f238e361117 100644 (file)
@@ -2042,40 +2042,6 @@ expand_decl (tree decl)
     }
 }
 \f
-/* Emit code to allocate T_SIZE bytes of dynamic stack space for ALLOC.  */
-void
-expand_stack_alloc (tree alloc, tree t_size)
-{
-  rtx address, dest, size;
-  tree var, type;
-
-  if (TREE_CODE (alloc) != ADDR_EXPR)
-    abort ();
-  var = TREE_OPERAND (alloc, 0);
-  if (TREE_CODE (var) != VAR_DECL)
-    abort ();
-
-  type = TREE_TYPE (var);
-
-  /* Compute the variable's size, in bytes.  */
-  size = expand_expr (t_size, NULL_RTX, VOIDmode, 0);
-  free_temp_slots ();
-
-  /* Allocate space on the stack for the variable.  */
-  address = XEXP (DECL_RTL (var), 0);
-  dest = allocate_dynamic_stack_space (size, address, TYPE_ALIGN (type));
-  if (dest != address)
-    emit_move_insn (address, dest);
-
-  /* Indicate the alignment we actually gave this variable.  */
-#ifdef STACK_BOUNDARY
-  DECL_ALIGN (var) = STACK_BOUNDARY;
-#else
-  DECL_ALIGN (var) = BIGGEST_ALIGNMENT;
-#endif
-  DECL_USER_ALIGN (var) = 0;
-}
-
 /* Emit code to save the current value of stack.  */
 rtx
 expand_stack_save (void)
index bd1762005302ebd0e2210b051bd288b8058f8301..4f8e1742f2d694e391b6fad97d6fe69972b7f4b8 100644 (file)
@@ -897,6 +897,8 @@ mx_register_decls (tree decl, tree *stmt_list)
           && TREE_ADDRESSABLE (decl)
           /* The type of the variable must be complete.  */
           && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl))
+         /* The decl hasn't been decomposed somehow.  */
+         && DECL_VALUE_EXPR (decl) == NULL
           /* Don't process the same decl twice.  */
           && ! mf_marked_p (decl))
         {
@@ -904,73 +906,7 @@ mx_register_decls (tree decl, tree *stmt_list)
           tree unregister_fncall, unregister_fncall_params;
           tree register_fncall, register_fncall_params;
 
-          if (DECL_DEFER_OUTPUT (decl))
-            {
-              /* Oh no ... it's probably a variable-length array (VLA).
-                 The size and address cannot be computed by merely
-                 looking at the DECL.  See gimplify_decl_stmt for the
-                 method by which VLA declarations turn into calls to
-                 BUILT_IN_STACK_ALLOC.  We assume that multiple
-                 VLAs declared later in the same block get allocation 
-                 code later than the others.  */
-              tree stack_alloc_call = NULL_TREE;
-
-              while(! tsi_end_p (initially_stmts))
-                {
-                  tree t = tsi_stmt (initially_stmts);
-
-                  tree call = NULL_TREE;
-                  if (TREE_CODE (t) == CALL_EXPR)
-                    call = t;
-                  else if (TREE_CODE (t) == MODIFY_EXPR &&
-                           TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
-                    call = TREE_OPERAND (t, 1);
-                  else if (TREE_CODE (t) == TRY_FINALLY_EXPR)
-                    {
-                      /* We hope that this is the try/finally block sometimes
-                         constructed by gimplify_bind_expr() for a BIND_EXPR
-                         that contains VLAs.  This very naive recursion
-                         appears to be sufficient.  */
-                      initially_stmts = tsi_start (TREE_OPERAND (t, 0));
-                    }
-
-                  if (call != NULL_TREE)
-                    {
-                      if (TREE_CODE (TREE_OPERAND(call, 0)) == ADDR_EXPR &&
-                          TREE_OPERAND (TREE_OPERAND (call, 0), 0) ==
-                                implicit_built_in_decls [BUILT_IN_STACK_ALLOC])
-                        {
-                          tree stack_alloc_args = TREE_OPERAND (call, 1);
-                          tree stack_alloc_op1 = TREE_VALUE (stack_alloc_args);
-                          tree stack_alloc_op2 = TREE_VALUE (TREE_CHAIN (stack_alloc_args));
-                          
-                          if (TREE_CODE (stack_alloc_op1) == ADDR_EXPR &&
-                              TREE_OPERAND (stack_alloc_op1, 0) == decl)
-                            {
-                              /* Got it! */
-                              size = stack_alloc_op2;
-                              stack_alloc_call = call;
-                              /* Advance iterator to point past this allocation call.  */
-                              tsi_next (&initially_stmts);
-                              break;
-                            }
-                        }
-                    }
-
-                  tsi_next (&initially_stmts);
-                }
-
-              if (stack_alloc_call == NULL_TREE)
-                {
-                  warning ("mudflap cannot handle variable-sized declaration `%s'",
-                         IDENTIFIER_POINTER (DECL_NAME (decl)));
-                  break;
-                }
-            }
-          else
-            {
-              size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
-            }
+         size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl)));
 
           /* (& VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */
           unregister_fncall_params =
index e884260d2b3951c52bb66f9c7df7e45d34fa92b1..7ae506e8558f0c2ad82401ceb6b384c1bb5100d9 100644 (file)
@@ -855,7 +855,7 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
 {
   struct walk_stmt_info *wi = data;
   struct nesting_info *info = wi->info;
-  tree t = *tp, field, x, y;
+  tree t = *tp, field, x;
 
   switch (TREE_CODE (t))
     {
@@ -909,40 +909,6 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
       }
       break;
 
-    case CALL_EXPR:
-      *walk_subtrees = 1;
-
-      /* Ready for some fun?  We need to recognize
-           __builtin_stack_alloc (&x, n)
-        and insert
-           FRAME.x = &x
-        after that.  X should have use_pointer_in_frame set.  We can't
-        do this any earlier, since we can't meaningfully evaluate &x.  */
-
-      x = get_callee_fndecl (t);
-      if (!x || DECL_BUILT_IN_CLASS (x) != BUILT_IN_NORMAL)
-       break;
-      if (DECL_FUNCTION_CODE (x) != BUILT_IN_STACK_ALLOC)
-       break;
-      t = TREE_VALUE (TREE_OPERAND (t, 1));
-      if (TREE_CODE (t) != ADDR_EXPR)
-       abort ();
-      t = TREE_OPERAND (t, 0);
-      if (TREE_CODE (t) != VAR_DECL)
-       abort ();
-      field = lookup_field_for_decl (info, t, NO_INSERT);
-      if (!field)
-       break;
-      if (!use_pointer_in_frame (t))
-       abort ();
-
-      x = build_addr (t);
-      y = get_frame_field (info, info->context, field, &wi->tsi);
-      x = build (MODIFY_EXPR, void_type_node, y, x);
-      SET_EXPR_LOCUS (x, EXPR_LOCUS (tsi_stmt (wi->tsi)));
-      tsi_link_after (&wi->tsi, x, TSI_SAME_STMT);
-      break;
-
     case REALPART_EXPR:
     case IMAGPART_EXPR:
     case COMPONENT_REF:
index a75a0ea23db953b17cb0d0f156d75df4fba43717..0d6d5608310ab4e19ed7ddcc57e419d8afd6b461 100644 (file)
@@ -2027,6 +2027,13 @@ struct tree_binfo GTY (())
    entire function.  */
 #define DECL_SAVED_TREE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.saved_tree)
 
+/* In a VAR_DECL or PARM_DECL, the location at which the value may be found,
+   if transformations have made this more complicated than evaluating the
+   decl itself.  This should only be used for debugging; once this field has
+   been set, the decl itself may not legitimately appear in the function.  */
+#define DECL_VALUE_EXPR(NODE) \
+  (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl.saved_tree)
+
 /* List of FUNCTION_DECLs inlined into this function's body.  */
 #define DECL_INLINED_FNS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inlined_fns)
 
@@ -2278,7 +2285,8 @@ struct tree_decl GTY(())
     int GTY ((tag ("VAR_DECL"))) i;
   } GTY ((desc ("TREE_CODE((tree) &(%0))"))) u2;
 
-  /* In a FUNCTION_DECL, this is DECL_SAVED_TREE.  */
+  /* In a FUNCTION_DECL, this is DECL_SAVED_TREE.
+     In a VAR_DECL or PARM_DECL, this is DECL_VALUE_EXPR.  */
   tree saved_tree;
 
   /* In a FUNCTION_DECL, these are function data which is to be kept
@@ -3353,7 +3361,6 @@ extern void expand_label (tree);
 extern void expand_goto (tree);
 extern void expand_asm (tree, int);
 
-extern void expand_stack_alloc (tree, tree);
 extern rtx expand_stack_save (void);
 extern void expand_stack_restore (tree);
 extern void expand_return (tree);