From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16694 invoked by alias); 7 Nov 2011 22:03:09 -0000 Received: (qmail 16569 invoked by uid 22791); 7 Nov 2011 22:02:49 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_TM,TW_TX X-Spam-Check-By: sourceware.org Received: from mail-ey0-f175.google.com (HELO mail-ey0-f175.google.com) (209.85.215.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 Nov 2011 22:02:26 +0000 Received: by eyd9 with SMTP id 9so4754883eyd.20 for ; Mon, 07 Nov 2011 14:02:24 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.17.34 with SMTP id l2mr9599301obd.2.1320703344100; Mon, 07 Nov 2011 14:02:24 -0800 (PST) Received: by 10.182.17.232 with HTTP; Mon, 7 Nov 2011 14:02:23 -0800 (PST) In-Reply-To: References: Date: Mon, 07 Nov 2011 22:10:00 -0000 Message-ID: Subject: Re: Mark objects death at end of scope From: Richard Guenther To: Michael Matz Cc: gcc-patches@gcc.gnu.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-11/txt/msg01078.txt.bz2 On Mon, Nov 7, 2011 at 4:57 PM, Michael Matz wrote: > Hi, > > On Thu, 3 Nov 2011, Richard Guenther wrote: > >> Otherwise the patch looks ok, but given the Ada issue let's wait until >> that is sorted out in some way. =A0That also gives others the chance to >> comment on the patch. > > So, this is what I came up with. =A0As discussed I didn't do the uintptr_t > case and didn't use auto_var_in_fn_p (but added a DECL_CONTEXT check). > I've added the gimple_clobber_p helper and used it in some places and now > dump the clobbers as > =A0lhs =3D{v} {CLOBBER} > > I haven't yet worked on the whole try/finally optimizations. > > Regstrapped (all default langs, now with Ada) on x86_64-linux. =A0Okay for > trunk? Ok. Thanks, Richard. > Ciao, > Michael. > > =A0 =A0 =A0 =A0* gengtype.c (write_field_root): Avoid out-of-scope access= of newv. > > =A0 =A0 =A0 =A0* tree-stdarg.c (execute_optimize_stdarg): Accept clobbers. > > =A0 =A0 =A0 =A0* tree.h (TREE_CLOBBER_P): New macro. > =A0 =A0 =A0 =A0* gimple.h (gimple_clobber_p): New inline function. > =A0 =A0 =A0 =A0* gimplify.c (gimplify_bind_expr): Add clobbers for all va= riables > =A0 =A0 =A0 =A0that go out of scope and live in memory. > =A0 =A0 =A0 =A0* tree-ssa-operands.c (get_expr_operands): Transfer volati= lity also > =A0 =A0 =A0 =A0for constructors. > =A0 =A0 =A0 =A0* cfgexpand.c (decl_to_stack_part): New static variable. > =A0 =A0 =A0 =A0(add_stack_var): Allocate it, and remember mapping. > =A0 =A0 =A0 =A0(fini_vars_expansion): Deallocate it. > =A0 =A0 =A0 =A0(stack_var_conflict_p): Add early outs. > =A0 =A0 =A0 =A0(visit_op, visit_conflict, add_scope_conflicts_1, > =A0 =A0 =A0 =A0add_scope_conflicts): New static functions. > =A0 =A0 =A0 =A0(expand_used_vars_for_block): Don't call add_stack_var_con= flict, tidy. > =A0 =A0 =A0 =A0(expand_used_vars): Add scope conflicts. > =A0 =A0 =A0 =A0(expand_gimple_stmt_1): Expand clobbers to nothing. > =A0 =A0 =A0 =A0(expand_debug_expr): Ditto. > > =A0 =A0 =A0 =A0* tree-pretty-print.c (dump_generic_node): Dump clobbers n= icely. > =A0 =A0 =A0 =A0* tree-ssa-live.c (remove_unused_locals): Remove clobbers = that > =A0 =A0 =A0 =A0refer to otherwise unused locals. > =A0 =A0 =A0 =A0* tree-sra.c (build_accesses_from_assign): Ignore clobbers. > =A0 =A0 =A0 =A0* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Clobb= ers of > =A0 =A0 =A0 =A0SSA names aren't necessary. > =A0 =A0 =A0 =A0(propagate_necessity): Accept and ignore constructors on t= he rhs, > =A0 =A0 =A0 =A0tidy. > =A0 =A0 =A0 =A0* gimple.c (walk_gimple_op): Accept constructors like mem_= rhs. > =A0 =A0 =A0 =A0* tree-ssa-structalias.c (find_func_aliases): Clobbers don= 't store > =A0 =A0 =A0 =A0any known value. > =A0 =A0 =A0 =A0* tree-ssa-sccvn.c (vn_reference_lookup_3): Ditto, in part= icular they > =A0 =A0 =A0 =A0don't zero-initialize something. > =A0 =A0 =A0 =A0* tree-ssa-phiopt.c (cond_if_else_store_replacement_1): Ig= nore > =A0 =A0 =A0 =A0clobber RHS, we don't want PHI nodes with those. > > testsuite/ > =A0 =A0 =A0 =A0* gcc.dg/tree-ssa/20031015-1.c: Adjust. > =A0 =A0 =A0 =A0* g++.dg/tree-ssa/ehcleanup-1.C: Ditto. > =A0 =A0 =A0 =A0* g++.dg/eh/builtin1.C: Rewrite to not use local variables. > =A0 =A0 =A0 =A0* g++.dg/eh/builtin2.C: Ditto. > =A0 =A0 =A0 =A0* g++.dg/eh/builtin3.C: Ditto. > > Index: gengtype.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gengtype.c.orig =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ gengtype.c =A02011-11-07 16:12:35.000000000 +0100 > @@ -3650,14 +3650,13 @@ write_field_root (outf_p f, pair_p v, ty > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0int has_length, struct fileloc *line, = const char *if_marked, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0bool emit_pch, type_p field_type, cons= t char *field_name) > =A0{ > + =A0struct pair newv; > =A0 /* If the field reference is relative to V, rather than to some > =A0 =A0 =A0subcomponent of V, we can mark any subarrays with a single str= ide. > =A0 =A0 =A0We're effectively treating the field as a global variable in i= ts > =A0 =A0 =A0own right. =A0*/ > =A0 if (v && type =3D=3D v->type) > =A0 =A0 { > - =A0 =A0 =A0struct pair newv; > - > =A0 =A0 =A0 newv =3D *v; > =A0 =A0 =A0 newv.type =3D field_type; > =A0 =A0 =A0 newv.name =3D ACONCAT ((v->name, ".", field_name, NULL)); > Index: tree.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree.h =A0 =A0 =A0(revision 180833) > +++ tree.h =A0 =A0 =A0(working copy) > @@ -1637,6 +1637,14 @@ struct GTY(()) tree_vec { > =A0#define CONSTRUCTOR_BITFIELD_P(NODE) \ > =A0 (DECL_BIT_FIELD (FIELD_DECL_CHECK (NODE)) && DECL_MODE (NODE) !=3D BL= Kmode) > > +/* True if NODE is a clobber right hand side, an expression of indetermi= nate > + =A0 value that clobbers the LHS in a copy instruction. =A0We use a vola= tile > + =A0 empty CONSTRUCTOR for this, as it matches most of the necessary sem= antic. > + =A0 In particular the volatile flag causes us to not prematurely remove > + =A0 such clobber instructions. =A0*/ > +#define TREE_CLOBBER_P(NODE) \ > + =A0(TREE_CODE (NODE) =3D=3D CONSTRUCTOR && TREE_THIS_VOLATILE (NODE)) > + > =A0/* A single element of a CONSTRUCTOR. VALUE holds the actual value of = the > =A0 =A0element. INDEX can optionally design the position of VALUE: in arr= ays, > =A0 =A0it is the index where VALUE has to be placed; in structures, it is= the > Index: gimple.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gimple.h.orig =A0 =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ gimple.h =A0 =A02011-11-07 16:12:35.000000000 +0100 > @@ -2000,6 +2000,14 @@ gimple_assign_cast_p (gimple s) > =A0 return false; > =A0} > > +/* Return true if S is a clobber statement. =A0*/ > + > +static inline bool > +gimple_clobber_p (gimple s) > +{ > + =A0return gimple_assign_single_p (s) > + =A0 =A0 =A0 =A0 && TREE_CLOBBER_P (gimple_assign_rhs1 (s)); > +} > > =A0/* Return true if GS is a GIMPLE_CALL. =A0*/ > > Index: gimplify.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gimplify.c.orig =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ gimplify.c =A02011-11-07 16:12:35.000000000 +0100 > @@ -1127,7 +1127,8 @@ gimplify_bind_expr (tree *expr_p, gimple > =A0 bool old_save_stack =3D gimplify_ctxp->save_stack; > =A0 tree t; > =A0 gimple gimple_bind; > - =A0gimple_seq body; > + =A0gimple_seq body, cleanup; > + =A0gimple stack_save; > > =A0 tree temp =3D voidify_wrapper_expr (bind_expr, NULL); > > @@ -1173,22 +1174,50 @@ gimplify_bind_expr (tree *expr_p, gimple > =A0 gimplify_stmt (&BIND_EXPR_BODY (bind_expr), &body); > =A0 gimple_bind_set_body (gimple_bind, body); > > + =A0cleanup =3D NULL; > + =A0stack_save =3D NULL; > =A0 if (gimplify_ctxp->save_stack) > =A0 =A0 { > - =A0 =A0 =A0gimple stack_save, stack_restore, gs; > - =A0 =A0 =A0gimple_seq cleanup, new_body; > + =A0 =A0 =A0gimple stack_restore; > > =A0 =A0 =A0 /* Save stack on entry and restore it on exit. =A0Add a try_f= inally > =A0 =A0 =A0 =A0 block to achieve this. =A0Note that mudflap depends on the > =A0 =A0 =A0 =A0 format of the emitted code: see mx_register_decls(). =A0*/ > =A0 =A0 =A0 build_stack_save_restore (&stack_save, &stack_restore); > > - =A0 =A0 =A0cleanup =3D new_body =3D NULL; > =A0 =A0 =A0 gimplify_seq_add_stmt (&cleanup, stack_restore); > + =A0 =A0} > + > + =A0/* Add clobbers for all variables that go out of scope. =A0*/ > + =A0for (t =3D BIND_EXPR_VARS (bind_expr); t ; t =3D DECL_CHAIN (t)) > + =A0 =A0{ > + =A0 =A0 =A0if (TREE_CODE (t) =3D=3D VAR_DECL > + =A0 =A0 =A0 =A0 && !is_global_var (t) > + =A0 =A0 =A0 =A0 && DECL_CONTEXT (t) =3D=3D current_function_decl > + =A0 =A0 =A0 =A0 && !DECL_HARD_REGISTER (t) > + =A0 =A0 =A0 =A0 && !TREE_THIS_VOLATILE (t) > + =A0 =A0 =A0 =A0 && !DECL_HAS_VALUE_EXPR_P (t) > + =A0 =A0 =A0 =A0 /* Only care for variables that have to be in memory. = =A0Others > + =A0 =A0 =A0 =A0 =A0 =A0will be rewritten into SSA names, hence moved to= the top-level. =A0*/ > + =A0 =A0 =A0 =A0 && needs_to_live_in_memory (t)) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 tree clobber =3D build_constructor (TREE_TYPE (t), NULL= ); > + =A0 =A0 =A0 =A0 TREE_THIS_VOLATILE (clobber) =3D 1; > + =A0 =A0 =A0 =A0 gimplify_seq_add_stmt (&cleanup, gimple_build_assign (t= , clobber)); > + =A0 =A0 =A0 } > + =A0 =A0} > + > + =A0if (cleanup) > + =A0 =A0{ > + =A0 =A0 =A0gimple gs; > + =A0 =A0 =A0gimple_seq new_body; > + > + =A0 =A0 =A0new_body =3D NULL; > =A0 =A0 =A0 gs =3D gimple_build_try (gimple_bind_body (gimple_bind), clea= nup, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GIMPLE_TRY_FINALL= Y); > > - =A0 =A0 =A0gimplify_seq_add_stmt (&new_body, stack_save); > + =A0 =A0 =A0if (stack_save) > + =A0 =A0 =A0 gimplify_seq_add_stmt (&new_body, stack_save); > =A0 =A0 =A0 gimplify_seq_add_stmt (&new_body, gs); > =A0 =A0 =A0 gimple_bind_set_body (gimple_bind, new_body); > =A0 =A0 } > Index: cfgexpand.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- cfgexpand.c.orig =A0 =A02011-11-07 15:56:25.000000000 +0100 > +++ cfgexpand.c 2011-11-07 16:12:35.000000000 +0100 > @@ -135,7 +135,7 @@ set_rtl (tree t, rtx x) > =A0 =A0 =A0 =A0 =A0/* If we don't yet have something recorded, just recor= d it now. =A0*/ > =A0 =A0 =A0 =A0 =A0if (!DECL_RTL_SET_P (var)) > =A0 =A0 =A0 =A0 =A0 =A0SET_DECL_RTL (var, x); > - =A0 =A0 =A0 =A0 /* If we have it set alrady to "multiple places" don't > + =A0 =A0 =A0 =A0 /* If we have it set already to "multiple places" don't > =A0 =A0 =A0 =A0 =A0 =A0 change this. =A0*/ > =A0 =A0 =A0 =A0 =A0else if (DECL_RTL (var) =3D=3D pc_rtx) > =A0 =A0 =A0 =A0 =A0 =A0; > @@ -184,6 +184,7 @@ struct stack_var > =A0static struct stack_var *stack_vars; > =A0static size_t stack_vars_alloc; > =A0static size_t stack_vars_num; > +static struct pointer_map_t *decl_to_stack_part; > > =A0/* An array of indices such that stack_vars[stack_vars_sorted[i]].size > =A0 =A0is non-decreasing. =A0*/ > @@ -262,7 +263,11 @@ add_stack_var (tree decl) > =A0 =A0 =A0 stack_vars > =A0 =A0 =A0 =A0=3D XRESIZEVEC (struct stack_var, stack_vars, stack_vars_a= lloc); > =A0 =A0 } > + =A0if (!decl_to_stack_part) > + =A0 =A0decl_to_stack_part =3D pointer_map_create (); > + > =A0 v =3D &stack_vars[stack_vars_num]; > + =A0* (size_t *)pointer_map_insert (decl_to_stack_part, decl) =3D stack_= vars_num; > > =A0 v->decl =3D decl; > =A0 v->size =3D tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1); > @@ -309,6 +314,14 @@ stack_var_conflict_p (size_t x, size_t y > =A0{ > =A0 struct stack_var *a =3D &stack_vars[x]; > =A0 struct stack_var *b =3D &stack_vars[y]; > + =A0if (x =3D=3D y) > + =A0 =A0return false; > + =A0/* Partitions containing an SSA name result from gimple registers > + =A0 =A0 with things like unsupported modes. =A0They are top-level and > + =A0 =A0 hence conflict with everything else. =A0*/ > + =A0if (TREE_CODE (a->decl) =3D=3D SSA_NAME || TREE_CODE (b->decl) =3D= =3D SSA_NAME) > + =A0 =A0return true; > + > =A0 if (!a->conflicts || !b->conflicts) > =A0 =A0 return false; > =A0 return bitmap_bit_p (a->conflicts, y); > @@ -379,6 +392,163 @@ add_alias_set_conflicts (void) > =A0 =A0 } > =A0} > > +/* Callback for walk_stmt_ops. =A0If OP is a decl touched by add_stack_v= ar > + =A0 enter its partition number into bitmap DATA. =A0*/ > + > +static bool > +visit_op (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data) > +{ > + =A0bitmap active =3D (bitmap)data; > + =A0op =3D get_base_address (op); > + =A0if (op > + =A0 =A0 =A0&& DECL_P (op) > + =A0 =A0 =A0&& DECL_RTL_IF_SET (op) =3D=3D pc_rtx) > + =A0 =A0{ > + =A0 =A0 =A0size_t *v =3D (size_t *) pointer_map_contains (decl_to_stack= _part, op); > + =A0 =A0 =A0if (v) > + =A0 =A0 =A0 bitmap_set_bit (active, *v); > + =A0 =A0} > + =A0return false; > +} > + > +/* Callback for walk_stmt_ops. =A0If OP is a decl touched by add_stack_v= ar > + =A0 record conflicts between it and all currently active other partitio= ns > + =A0 from bitmap DATA. =A0*/ > + > +static bool > +visit_conflict (gimple stmt ATTRIBUTE_UNUSED, tree op, void *data) > +{ > + =A0bitmap active =3D (bitmap)data; > + =A0op =3D get_base_address (op); > + =A0if (op > + =A0 =A0 =A0&& DECL_P (op) > + =A0 =A0 =A0&& DECL_RTL_IF_SET (op) =3D=3D pc_rtx) > + =A0 =A0{ > + =A0 =A0 =A0size_t *v =3D > + =A0 =A0 =A0 (size_t *) pointer_map_contains (decl_to_stack_part, op); > + =A0 =A0 =A0if (v && bitmap_set_bit (active, *v)) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 size_t num =3D *v; > + =A0 =A0 =A0 =A0 bitmap_iterator bi; > + =A0 =A0 =A0 =A0 unsigned i; > + =A0 =A0 =A0 =A0 gcc_assert (num < stack_vars_num); > + =A0 =A0 =A0 =A0 EXECUTE_IF_SET_IN_BITMAP (active, 0, i, bi) > + =A0 =A0 =A0 =A0 =A0 add_stack_var_conflict (num, i); > + =A0 =A0 =A0 } > + =A0 =A0} > + =A0return false; > +} > + > +/* Helper routine for add_scope_conflicts, calculating the active partit= ions > + =A0 at the end of BB, leaving the result in WORK. =A0We're called to ge= nerate > + =A0 conflicts when FOR_CONFLICT is true, otherwise we're just tracking > + =A0 liveness. =A0*/ > + > +static void > +add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict) > +{ > + =A0edge e; > + =A0edge_iterator ei; > + =A0gimple_stmt_iterator gsi; > + =A0bool (*visit)(gimple, tree, void *); > + > + =A0bitmap_clear (work); > + =A0FOR_EACH_EDGE (e, ei, bb->preds) > + =A0 =A0bitmap_ior_into (work, (bitmap)e->src->aux); > + > + =A0if (for_conflict) > + =A0 =A0{ > + =A0 =A0 =A0/* We need to add conflicts for everything life at the start= of > + =A0 =A0 =A0 =A0 this block. =A0Unlike classical lifeness for named obje= cts we can't > + =A0 =A0 =A0 =A0rely on seeing a def/use of the names we're interested i= n. > + =A0 =A0 =A0 =A0There might merely be indirect loads/stores. =A0We'd not= add any > + =A0 =A0 =A0 =A0conflicts for such partitions. =A0*/ > + =A0 =A0 =A0bitmap_iterator bi; > + =A0 =A0 =A0unsigned i; > + =A0 =A0 =A0EXECUTE_IF_SET_IN_BITMAP (work, 0, i, bi) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 unsigned j; > + =A0 =A0 =A0 =A0 bitmap_iterator bj; > + =A0 =A0 =A0 =A0 EXECUTE_IF_SET_IN_BITMAP (work, i, j, bj) > + =A0 =A0 =A0 =A0 =A0 add_stack_var_conflict (i, j); > + =A0 =A0 =A0 } > + =A0 =A0 =A0visit =3D visit_conflict; > + =A0 =A0} > + =A0else > + =A0 =A0visit =3D visit_op; > + > + =A0for (gsi =3D gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) > + =A0 =A0{ > + =A0 =A0 =A0gimple stmt =3D gsi_stmt (gsi); > + =A0 =A0 =A0if (!is_gimple_debug (stmt)) > + =A0 =A0 =A0 walk_stmt_load_store_addr_ops (stmt, work, visit, visit, vi= sit); > + =A0 =A0} > + =A0for (gsi =3D gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) > + =A0 =A0{ > + =A0 =A0 =A0gimple stmt =3D gsi_stmt (gsi); > + > + =A0 =A0 =A0if (gimple_clobber_p (stmt)) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 tree lhs =3D gimple_assign_lhs (stmt); > + =A0 =A0 =A0 =A0 size_t *v; > + =A0 =A0 =A0 =A0 /* Nested function lowering might introduce LHSs > + =A0 =A0 =A0 =A0 =A0 =A0that are COMPONENT_REFs. =A0*/ > + =A0 =A0 =A0 =A0 if (TREE_CODE (lhs) !=3D VAR_DECL) > + =A0 =A0 =A0 =A0 =A0 continue; > + =A0 =A0 =A0 =A0 if (DECL_RTL_IF_SET (lhs) =3D=3D pc_rtx > + =A0 =A0 =A0 =A0 =A0 =A0 && (v =3D (size_t *) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 pointer_map_contains (decl_to_stack_par= t, lhs))) > + =A0 =A0 =A0 =A0 =A0 bitmap_clear_bit (work, *v); > + =A0 =A0 =A0 } > + =A0 =A0 =A0else if (!is_gimple_debug (stmt)) > + =A0 =A0 =A0 walk_stmt_load_store_addr_ops (stmt, work, visit, visit, vi= sit); > + =A0 =A0} > +} > + > +/* Generate stack partition conflicts between all partitions that are > + =A0 simultaneously live. =A0*/ > + > +static void > +add_scope_conflicts (void) > +{ > + =A0basic_block bb; > + =A0bool changed; > + =A0bitmap work =3D BITMAP_ALLOC (NULL); > + > + =A0/* We approximate the life range of a stack variable by taking the f= irst > + =A0 =A0 mention of its name as starting point(s), and by the end-of-sco= pe > + =A0 =A0 death clobber added by gimplify as ending point(s) of the range. > + =A0 =A0 This overapproximates in the case we for instance moved an addr= ess-taken > + =A0 =A0 operation upward, without also moving a dereference to it upwar= ds. > + =A0 =A0 But it's conservatively correct as a variable never can hold va= lues > + =A0 =A0 before its name is mentioned at least once. > + > + =A0 =A0 We then do a mostly classical bitmap lifeness algorithm. =A0*/ > + > + =A0FOR_ALL_BB (bb) > + =A0 =A0bb->aux =3D BITMAP_ALLOC (NULL); > + > + =A0changed =3D true; > + =A0while (changed) > + =A0 =A0{ > + =A0 =A0 =A0changed =3D false; > + =A0 =A0 =A0FOR_EACH_BB (bb) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 bitmap active =3D (bitmap)bb->aux; > + =A0 =A0 =A0 =A0 add_scope_conflicts_1 (bb, work, false); > + =A0 =A0 =A0 =A0 if (bitmap_ior_into (active, work)) > + =A0 =A0 =A0 =A0 =A0 changed =3D true; > + =A0 =A0 =A0 } > + =A0 =A0} > + > + =A0FOR_EACH_BB (bb) > + =A0 =A0add_scope_conflicts_1 (bb, work, true); > + > + =A0BITMAP_FREE (work); > + =A0FOR_ALL_BB (bb) > + =A0 =A0BITMAP_FREE (bb->aux); > +} > + > =A0/* A subroutine of partition_stack_vars. =A0A comparison function for = qsort, > =A0 =A0sorting an array of indices by the properties of the object. =A0*/ > > @@ -1095,11 +1265,8 @@ expand_one_var (tree var, bool toplevel, > =A0static void > =A0expand_used_vars_for_block (tree block, bool toplevel) > =A0{ > - =A0size_t i, j, old_sv_num, this_sv_num, new_sv_num; > =A0 tree t; > > - =A0old_sv_num =3D toplevel ? 0 : stack_vars_num; > - > =A0 /* Expand all variables at this level. =A0*/ > =A0 for (t =3D BLOCK_VARS (block); t ; t =3D DECL_CHAIN (t)) > =A0 =A0 if (TREE_USED (t) > @@ -1107,24 +1274,9 @@ expand_used_vars_for_block (tree block, > =A0 =A0 =A0 =A0 =A0 =A0|| !DECL_NONSHAREABLE (t))) > =A0 =A0 =A0 expand_one_var (t, toplevel, true); > > - =A0this_sv_num =3D stack_vars_num; > - > =A0 /* Expand all variables at containing levels. =A0*/ > =A0 for (t =3D BLOCK_SUBBLOCKS (block); t ; t =3D BLOCK_CHAIN (t)) > =A0 =A0 expand_used_vars_for_block (t, false); > - > - =A0/* Since we do not track exact variable lifetimes (which is not even > - =A0 =A0 possible for variables whose address escapes), we mirror the bl= ock > - =A0 =A0 tree in the interference graph. =A0Here we cause all variables = at this > - =A0 =A0 level, and all sublevels, to conflict. =A0*/ > - =A0if (old_sv_num < this_sv_num) > - =A0 =A0{ > - =A0 =A0 =A0new_sv_num =3D stack_vars_num; > - > - =A0 =A0 =A0for (i =3D old_sv_num; i < new_sv_num; ++i) > - =A0 =A0 =A0 for (j =3D i < this_sv_num ? i : this_sv_num; j-- > old_sv_= num ;) > - =A0 =A0 =A0 =A0 add_stack_var_conflict (i, j); > - =A0 =A0} > =A0} > > =A0/* A subroutine of expand_used_vars. =A0Walk down through the BLOCK tr= ee > @@ -1312,6 +1464,8 @@ fini_vars_expansion (void) > =A0 XDELETEVEC (stack_vars_sorted); > =A0 stack_vars =3D NULL; > =A0 stack_vars_alloc =3D stack_vars_num =3D 0; > + =A0pointer_map_destroy (decl_to_stack_part); > + =A0decl_to_stack_part =3D NULL; > =A0} > > =A0/* Make a fair guess for the size of the stack frame of the function > @@ -1466,6 +1620,7 @@ expand_used_vars (void) > > =A0 if (stack_vars_num > 0) > =A0 =A0 { > + =A0 =A0 =A0add_scope_conflicts (); > =A0 =A0 =A0 /* Due to the way alias sets work, no variables with non-conf= licting > =A0 =A0 =A0 =A0 alias sets may be assigned the same address. =A0Add confl= icts to > =A0 =A0 =A0 =A0 reflect this. =A0*/ > @@ -1974,8 +2129,13 @@ expand_gimple_stmt_1 (gimple stmt) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D=3D GIMPLE_SINGLE_RHS); > =A0 =A0 =A0 =A0 =A0 =A0if (gimple_has_location (stmt) && CAN_HAVE_LOCATIO= N_P (rhs)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0SET_EXPR_LOCATION (rhs, gimple_location (stmt)= ); > - =A0 =A0 =A0 =A0 =A0 expand_assignment (lhs, rhs, > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gimple_assig= n_nontemporal_move_p (stmt)); > + =A0 =A0 =A0 =A0 =A0 if (TREE_CLOBBER_P (rhs)) > + =A0 =A0 =A0 =A0 =A0 =A0 /* This is a clobber to mark the going out of s= cope for > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0this LHS. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 ; > + =A0 =A0 =A0 =A0 =A0 else > + =A0 =A0 =A0 =A0 =A0 =A0 expand_assignment (lhs, rhs, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gimple_a= ssign_nontemporal_move_p (stmt)); > =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0else > =A0 =A0 =A0 =A0 =A0{ > @@ -3165,7 +3325,9 @@ expand_debug_expr (tree exp) > =A0 =A0 =A0 /* Fall through. =A0*/ > > =A0 =A0 case CONSTRUCTOR: > - =A0 =A0 =A0if (TREE_CODE (TREE_TYPE (exp)) =3D=3D VECTOR_TYPE) > + =A0 =A0 =A0if (TREE_CLOBBER_P (exp)) > + =A0 =A0 =A0 return NULL; > + =A0 =A0 =A0else if (TREE_CODE (TREE_TYPE (exp)) =3D=3D VECTOR_TYPE) > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0unsigned i; > =A0 =A0 =A0 =A0 =A0tree val; > Index: tree-pretty-print.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-pretty-print.c.orig =A0 =A02011-10-27 14:48:01.000000000 +0200 > +++ tree-pretty-print.c 2011-11-07 16:19:17.000000000 +0100 > @@ -1271,8 +1271,10 @@ dump_generic_node (pretty_printer *buffe > =A0 =A0 =A0 =A0bool is_array_init =3D false; > =A0 =A0 =A0 =A0double_int curidx =3D double_int_zero; > =A0 =A0 =A0 =A0pp_character (buffer, '{'); > - =A0 =A0 =A0 if (TREE_CODE (TREE_TYPE (node)) =3D=3D RECORD_TYPE > - =A0 =A0 =A0 =A0 =A0 || TREE_CODE (TREE_TYPE (node)) =3D=3D UNION_TYPE) > + =A0 =A0 =A0 if (TREE_CLOBBER_P (node)) > + =A0 =A0 =A0 =A0 pp_string (buffer, "CLOBBER"); > + =A0 =A0 =A0 else if (TREE_CODE (TREE_TYPE (node)) =3D=3D RECORD_TYPE > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|| TREE_CODE (TREE_TYPE (node)) =3D=3D U= NION_TYPE) > =A0 =A0 =A0 =A0 =A0is_struct_init =3D true; > =A0 =A0 =A0 =A0 else if (TREE_CODE (TREE_TYPE (node)) =3D=3D ARRAY_TYPE > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && TYPE_DOMAIN (TREE_TYPE (node)) > Index: tree-stdarg.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-stdarg.c.orig =A02011-11-07 15:56:25.000000000 +0100 > +++ tree-stdarg.c =A0 =A0 =A0 2011-11-07 16:12:35.000000000 +0100 > @@ -872,8 +872,11 @@ execute_optimize_stdarg (void) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (get_gimple_rhs_class (gimple_assig= n_rhs_code (stmt)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D=3D GIMPLE_SINGLE_RHS) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Check for ap =3D{v} {}. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (TREE_CLOBBER_P (rhs)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Check for ap[0].field =3D t= emp. =A0*/ > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (va_list_counter_struct_op (= &si, lhs, rhs, true)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else if (va_list_counter_struct= _op (&si, lhs, rhs, true)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0continue; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Check for temp =3D ap[0].fi= eld. =A0*/ > Index: tree-ssa-live.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-live.c.orig =A0 =A0 =A0 =A02011-11-07 15:56:25.000000000 +01= 00 > +++ tree-ssa-live.c =A0 =A0 2011-11-07 16:12:35.000000000 +0100 > @@ -688,6 +688,7 @@ remove_unused_locals (void) > =A0 referenced_var_iterator rvi; > =A0 bitmap global_unused_vars =3D NULL; > =A0 unsigned srcidx, dstidx, num; > + =A0bool have_local_clobbers =3D false; > > =A0 /* Removing declarations from lexical blocks when not optimizing is > =A0 =A0 =A0not only a waste of time, it actually causes differences in st= ack > @@ -720,6 +721,12 @@ remove_unused_locals (void) > =A0 =A0 =A0 =A0 =A0if (is_gimple_debug (stmt)) > =A0 =A0 =A0 =A0 =A0 =A0continue; > > + =A0 =A0 =A0 =A0 if (gimple_clobber_p (stmt)) > + =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 have_local_clobbers =3D true; > + =A0 =A0 =A0 =A0 =A0 =A0 continue; > + =A0 =A0 =A0 =A0 =A0 } > + > =A0 =A0 =A0 =A0 =A0if (b) > =A0 =A0 =A0 =A0 =A0 =A0TREE_USED (b) =3D true; > > @@ -753,6 +760,41 @@ remove_unused_locals (void) > =A0 =A0 =A0 =A0 =A0TREE_USED (e->goto_block) =3D true; > =A0 =A0 } > > + =A0/* We do a two-pass approach about the out-of-scope clobbers. =A0We = want > + =A0 =A0 to remove them if they are the only references to a local varia= ble, > + =A0 =A0 but we want to retain them when there's any other. =A0So the fi= rst pass > + =A0 =A0 ignores them, and the second pass (if there were any) tries to = remove > + =A0 =A0 them. =A0*/ > + =A0if (have_local_clobbers) > + =A0 =A0FOR_EACH_BB (bb) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 gimple_stmt_iterator gsi; > + > + =A0 =A0 =A0 for (gsi =3D gsi_start_bb (bb); !gsi_end_p (gsi);) > + =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 gimple stmt =3D gsi_stmt (gsi); > + =A0 =A0 =A0 =A0 =A0 tree b =3D gimple_block (stmt); > + > + =A0 =A0 =A0 =A0 =A0 if (gimple_clobber_p (stmt)) > + =A0 =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 tree lhs =3D gimple_assign_lhs (stmt); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 lhs =3D get_base_address (lhs); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (TREE_CODE (lhs) =3D=3D SSA_NAME) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 lhs =3D SSA_NAME_VAR (lhs); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (DECL_P (lhs) && (!var_ann (lhs) || !is_= used_p (lhs))) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 unlink_stmt_vdef (stmt); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gsi_remove (&gsi, true); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 release_defs (stmt); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (b) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 TREE_USED (b) =3D true; > + =A0 =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0 =A0 gsi_next (&gsi); > + =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0} > + > =A0 cfun->has_local_explicit_reg_vars =3D false; > > =A0 /* Remove unmarked local vars from local_decls. =A0*/ > Index: tree-sra.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-sra.c.orig =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ tree-sra.c =A02011-11-07 16:12:35.000000000 +0100 > @@ -1103,7 +1103,9 @@ build_accesses_from_assign (gimple stmt) > =A0 tree lhs, rhs; > =A0 struct access *lacc, *racc; > > - =A0if (!gimple_assign_single_p (stmt)) > + =A0if (!gimple_assign_single_p (stmt) > + =A0 =A0 =A0/* Scope clobbers don't influence scalarization. =A0*/ > + =A0 =A0 =A0|| gimple_clobber_p (stmt)) > =A0 =A0 return false; > > =A0 lhs =3D gimple_assign_lhs (stmt); > Index: tree-ssa-dce.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-dce.c.orig 2011-11-07 15:56:25.000000000 +0100 > +++ tree-ssa-dce.c =A0 =A0 =A02011-11-07 16:12:35.000000000 +0100 > @@ -351,6 +351,12 @@ mark_stmt_if_obviously_necessary (gimple > =A0 =A0 =A0 =A0mark_stmt_necessary (stmt, true); > =A0 =A0 =A0 break; > > + =A0 =A0case GIMPLE_ASSIGN: > + =A0 =A0 =A0if (TREE_CODE (gimple_assign_lhs (stmt)) =3D=3D SSA_NAME > + =A0 =A0 =A0 =A0 && TREE_CLOBBER_P (gimple_assign_rhs1 (stmt))) > + =A0 =A0 =A0 return; > + =A0 =A0 =A0break; > + > =A0 =A0 default: > =A0 =A0 =A0 break; > =A0 =A0 } > @@ -917,19 +923,17 @@ propagate_necessity (struct edge_list *e > =A0 =A0 =A0 =A0 =A0else if (gimple_assign_single_p (stmt)) > =A0 =A0 =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0 =A0 =A0tree rhs; > - =A0 =A0 =A0 =A0 =A0 =A0 bool rhs_aliased =3D false; > =A0 =A0 =A0 =A0 =A0 =A0 =A0/* If this is a load mark things necessary. = =A0*/ > =A0 =A0 =A0 =A0 =A0 =A0 =A0rhs =3D gimple_assign_rhs1 (stmt); > =A0 =A0 =A0 =A0 =A0 =A0 =A0if (TREE_CODE (rhs) !=3D SSA_NAME > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && !is_gimple_min_invariant (rhs)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && !is_gimple_min_invariant (rhs) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && TREE_CODE (rhs) !=3D CONSTRUCTOR) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (!ref_may_be_aliased (rhs)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mark_aliased_reaching_defs_necessa= ry (stmt, rhs); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 rhs_aliased =3D true; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mark_all_reaching_defs_necessary (s= tmt); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0 =A0 =A0 if (rhs_aliased) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 mark_all_reaching_defs_necessary (stmt); > =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0 =A0else if (gimple_code (stmt) =3D=3D GIMPLE_RETURN) > =A0 =A0 =A0 =A0 =A0 =A0{ > @@ -937,7 +941,8 @@ propagate_necessity (struct edge_list *e > =A0 =A0 =A0 =A0 =A0 =A0 =A0/* A return statement may perform a load. =A0*/ > =A0 =A0 =A0 =A0 =A0 =A0 =A0if (rhs > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&& TREE_CODE (rhs) !=3D SSA_NAME > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && !is_gimple_min_invariant (rhs)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && !is_gimple_min_invariant (rhs) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && TREE_CODE (rhs) !=3D CONSTRUCTOR) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (!ref_may_be_aliased (rhs)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mark_aliased_reaching_defs_necessa= ry (stmt, rhs); > @@ -955,6 +960,7 @@ propagate_necessity (struct edge_list *e > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tree op =3D TREE_VALUE (gimple_asm_inp= ut_op (stmt, i)); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (TREE_CODE (op) !=3D SSA_NAME > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&& !is_gimple_min_invariant (o= p) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && TREE_CODE (op) !=3D CONSTRUC= TOR > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&& !ref_may_be_aliased (op)) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mark_aliased_reaching_defs_necessa= ry (stmt, op); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > Index: gimple.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gimple.c.orig =A0 =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ gimple.c =A0 =A02011-11-07 16:12:35.000000000 +0100 > @@ -1471,7 +1471,9 @@ walk_gimple_op (gimple stmt, walk_tree_f > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0 /* If the RHS has more than 1 operand, it is not appr= opriate > =A0 =A0 =A0 =A0 =A0 =A0 =A0for the memory. =A0*/ > - =A0 =A0 =A0 =A0 wi->val_only =3D !is_gimple_mem_rhs (gimple_assign_rhs1= (stmt)) > + =A0 =A0 =A0 =A0 wi->val_only =3D !(is_gimple_mem_rhs (gimple_assign_rhs= 1 (stmt)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|| TREE_CODE (gimple= _assign_rhs1 (stmt)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D=3D CONSTRUC= TOR) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|| !gimple_assign_sing= le_p (stmt); > =A0 =A0 =A0 =A0 =A0wi->is_lhs =3D true; > =A0 =A0 =A0 =A0} > Index: tree-ssa-structalias.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-structalias.c.orig 2011-11-07 15:56:25.000000000 +0100 > +++ tree-ssa-structalias.c =A0 =A0 =A02011-11-07 16:12:35.000000000 +0100 > @@ -4437,7 +4437,11 @@ find_func_aliases (gimple origt) > =A0 =A0 =A0 tree lhsop =3D gimple_assign_lhs (t); > =A0 =A0 =A0 tree rhsop =3D (gimple_num_ops (t) =3D=3D 2) ? gimple_assign_= rhs1 (t) : NULL; > > - =A0 =A0 =A0if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop))) > + =A0 =A0 =A0if (rhsop && TREE_CLOBBER_P (rhsop)) > + =A0 =A0 =A0 /* Ignore clobbers, they don't actually store anything into > + =A0 =A0 =A0 =A0 =A0the LHS. =A0*/ > + =A0 =A0 =A0 ; > + =A0 =A0 =A0else if (rhsop && AGGREGATE_TYPE_P (TREE_TYPE (lhsop))) > =A0 =A0 =A0 =A0do_structure_copy (lhsop, rhsop); > =A0 =A0 =A0 else > =A0 =A0 =A0 =A0{ > Index: tree-ssa-reassoc.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-reassoc.c.orig =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ tree-ssa-reassoc.c =A02011-11-07 16:12:35.000000000 +0100 > @@ -2869,6 +2869,12 @@ reassociate_bb (basic_block bb) > =A0 =A0 =A0 =A0 =A0rhs1 =3D gimple_assign_rhs1 (stmt); > =A0 =A0 =A0 =A0 =A0rhs2 =3D gimple_assign_rhs2 (stmt); > > + =A0 =A0 =A0 =A0 /* We don't want to destroy reduction like patterns > + =A0 =A0 =A0 =A0 =A0 =A0with reassociation, simply don't start at such > + =A0 =A0 =A0 =A0 =A0 =A0statements. =A0*/ > + =A0 =A0 =A0 =A0 if (is_phi_for_stmt (stmt, rhs1) || is_phi_for_stmt (st= mt, rhs2)) > + =A0 =A0 =A0 =A0 =A0 continue; > + > =A0 =A0 =A0 =A0 =A0/* For non-bit or min/max operations we can't associate > =A0 =A0 =A0 =A0 =A0 =A0 all types. =A0Verify that here. =A0*/ > =A0 =A0 =A0 =A0 =A0if (rhs_code !=3D BIT_IOR_EXPR > Index: tree-ssa-operands.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-operands.c.orig =A0 =A02011-11-07 15:56:25.000000000 +0100 > +++ tree-ssa-operands.c 2011-11-07 16:12:35.000000000 +0100 > @@ -956,6 +956,12 @@ get_expr_operands (gimple stmt, tree *ex > =A0 =A0 =A0 =A0constructor_elt *ce; > =A0 =A0 =A0 =A0unsigned HOST_WIDE_INT idx; > > + =A0 =A0 =A0 /* A volatile constructor is actually TREE_CLOBBER_P, trans= fer > + =A0 =A0 =A0 =A0 =A0the volatility to the statement, don't use TREE_CLOB= BER_P for > + =A0 =A0 =A0 =A0 =A0mirroring the other uses of THIS_VOLATILE in this fi= le. =A0*/ > + =A0 =A0 =A0 if (TREE_THIS_VOLATILE (expr)) > + =A0 =A0 =A0 =A0 gimple_set_has_volatile_ops (stmt, true); > + > =A0 =A0 =A0 =A0for (idx =3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (e= xpr), idx, ce); > =A0 =A0 =A0 =A0 =A0 =A0 idx++) > Index: tree-ssa-sccvn.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-sccvn.c.orig =A0 =A0 =A0 2011-11-07 15:56:25.000000000 +0100 > +++ tree-ssa-sccvn.c =A0 =A02011-11-07 16:12:35.000000000 +0100 > @@ -1388,8 +1388,12 @@ vn_reference_lookup_3 (ao_ref *ref, tree > =A0 if (maxsize =3D=3D -1) > =A0 =A0 return (void *)-1; > > + =A0/* We can't deduce anything useful from clobbers. =A0*/ > + =A0if (gimple_clobber_p (def_stmt)) > + =A0 =A0return (void *)-1; > + > =A0 /* def_stmt may-defs *ref. =A0See if we can derive a value for *ref > - =A0 =A0 from that defintion. > + =A0 =A0 from that definition. > =A0 =A0 =A01) Memset. =A0*/ > =A0 if (is_gimple_reg_type (vr->type) > =A0 =A0 =A0 && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET) > Index: tree-ssa-phiopt.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- tree-ssa-phiopt.c.orig =A0 =A0 =A02011-11-07 15:56:25.000000000 +0100 > +++ tree-ssa-phiopt.c =A0 2011-11-07 16:12:35.000000000 +0100 > @@ -1318,8 +1318,10 @@ cond_if_else_store_replacement_1 (basic_ > > =A0 if (then_assign =3D=3D NULL > =A0 =A0 =A0 || !gimple_assign_single_p (then_assign) > + =A0 =A0 =A0|| gimple_clobber_p (then_assign) > =A0 =A0 =A0 || else_assign =3D=3D NULL > - =A0 =A0 =A0|| !gimple_assign_single_p (else_assign)) > + =A0 =A0 =A0|| !gimple_assign_single_p (else_assign) > + =A0 =A0 =A0|| gimple_clobber_p (else_assign)) > =A0 =A0 return false; > > =A0 lhs =3D gimple_assign_lhs (then_assign); > Index: testsuite/gcc.dg/tree-ssa/20031015-1.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- testsuite/gcc.dg/tree-ssa/20031015-1.c.orig 2011-11-07 15:56:25.00000= 0000 +0100 > +++ testsuite/gcc.dg/tree-ssa/20031015-1.c =A0 =A0 =A02011-11-07 16:12:35= .000000000 +0100 > @@ -13,6 +13,6 @@ main(void) > =A0 return 0; > =A0} > > -/* The VDEF comes from the initial assignment and the asm. =A0*/ > -/* { dg-final { scan-tree-dump-times "DEF" 2 "alias" } } */ > +/* The VDEF comes from the initial assignment, the asm, and the clobber.= =A0*/ > +/* { dg-final { scan-tree-dump-times "DEF" 3 "alias" } } */ > =A0/* { dg-final { cleanup-tree-dump "alias" } } */ > Index: testsuite/g++.dg/tree-ssa/ehcleanup-1.C > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- testsuite/g++.dg/tree-ssa/ehcleanup-1.C.orig =A0 =A0 =A0 =A02011-11-0= 7 15:56:25.000000000 +0100 > +++ testsuite/g++.dg/tree-ssa/ehcleanup-1.C =A0 =A0 2011-11-07 16:12:35.0= 00000000 +0100 > @@ -16,9 +16,9 @@ t (void) > =A0 can_throw (); > =A0} > =A0// We ought to remove implicit cleanup, since destructor is empty. > -// { dg-final { scan-tree-dump-times "Empty EH handler" 1 "ehcleanup1" }= } > +// { dg-final { scan-tree-dump-times "Empty EH handler" 2 "ehcleanup1" }= } > =A0// > =A0// And as a result also contained control flow. > -// { dg-final { scan-tree-dump-times "Removing unreachable" 2 "ehcleanup= 1" } } > +// { dg-final { scan-tree-dump-times "Removing unreachable" 4 "ehcleanup= 1" } } > =A0// > =A0// { dg-final { cleanup-tree-dump "ehcleanup1" } } > Index: testsuite/g++.dg/eh/builtin1.C > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- testsuite/g++.dg/eh/builtin1.C.orig 2011-11-07 15:56:25.000000000 +01= 00 > +++ testsuite/g++.dg/eh/builtin1.C =A0 =A0 =A02011-11-07 16:12:35.0000000= 00 +0100 > @@ -6,20 +6,26 @@ > > =A0extern "C" int printf (const char *, ...); > > -struct A { A (); ~A (); int i; }; > +extern void callme (void) throw(); > > =A0int > -foo () > +foo (int i) > =A0{ > - =A0A a; > - =A0printf ("foo %d\n", a.i); > + =A0try { > + =A0 =A0printf ("foo %d\n", i); > + =A0} catch (...) { > + =A0 =A0callme(); > + =A0} > =A0} > > =A0int > -bar () > +bar (int i) > =A0{ > - =A0A a; > - =A0__builtin_printf ("foo %d\n", a.i); > + =A0try { > + =A0 =A0__builtin_printf ("foo %d\n", i); > + =A0} catch (...) { > + =A0 =A0callme(); > + =A0} > =A0} > > =A0/* { dg-final { scan-tree-dump-times "resx" 2 "eh" } } */ > Index: testsuite/g++.dg/eh/builtin2.C > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- testsuite/g++.dg/eh/builtin2.C.orig 2011-11-07 15:56:25.000000000 +01= 00 > +++ testsuite/g++.dg/eh/builtin2.C =A0 =A0 =A02011-11-07 16:12:35.0000000= 00 +0100 > @@ -5,20 +5,26 @@ > > =A0extern "C" int printf (const char *, ...) throw(); > > -struct A { A (); ~A (); int i; }; > +extern void callme (void) throw(); > > =A0int > -foo () > +foo (int i) > =A0{ > - =A0A a; > - =A0printf ("foo %d\n", a.i); > + =A0try { > + =A0 =A0printf ("foo %d\n", i); > + =A0} catch (...) { > + =A0 =A0callme(); > + =A0} > =A0} > > =A0int > -bar () > +bar (int i) > =A0{ > - =A0A a; > - =A0__builtin_printf ("foo %d\n", a.i); > + =A0try { > + =A0 =A0__builtin_printf ("foo %d\n", i); > + =A0} catch (...) { > + =A0 =A0callme(); > + =A0} > =A0} > > =A0/* { dg-final { scan-tree-dump-times "resx" 0 "eh" } } */ > Index: testsuite/g++.dg/eh/builtin3.C > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- testsuite/g++.dg/eh/builtin3.C.orig 2011-11-07 15:56:25.000000000 +01= 00 > +++ testsuite/g++.dg/eh/builtin3.C =A0 =A0 =A02011-11-07 16:12:35.0000000= 00 +0100 > @@ -3,13 +3,16 @@ > =A0// { dg-do compile } > =A0// { dg-options "-fdump-tree-eh" } > > -struct A { A (); ~A (); int i; }; > +extern void callme (void) throw(); > > =A0int > -bar () > +bar (int i) > =A0{ > - =A0A a; > - =A0__builtin_printf ("foo %d\n", a.i); > + =A0try { > + =A0 =A0__builtin_printf ("foo %d\n", i); > + =A0} catch (...) { > + =A0 =A0callme(); > + =A0} > =A0} > > =A0/* { dg-final { scan-tree-dump-times "resx" 1 "eh" } } */ >