This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR debug/39267: Scope blocks no longer contains static vars, const and type decls...


Hi,
this patch should solve following problems:

  - Local static variables are not visible from any inline copies or clones.
    We used to produce duplicate decl here to put it into scope block but this
    broke horribly with one decl rule.

    This is demonstrated by my canonical testcase:

	static inline int t(int op)
	{
	  static int counter;
	  int lcounter;
	  for (lcounter = 0; lcounter<op; lcounter++)
	    printf ("%i\n",counter++);
	}
	main()
	{
	 t(5);
	 t(5);
	 t(5);
	 t(5);
	}

    Where counter is not visible in inline copies of t.

  - We no longer copy anything else than VAR_DECL or PARM_DECL from scope blocks
    when inlining or versioning or clonning.  This cause several gdb testsuite
    regresions.

    (Instead we add it into local_decls where it does not serve any purpose
    except for slowing down compiler. Only what needs to be put here are the
    referenced local statics that code was originally invented for but is
    bit overactive.)

  - Debug info require to copy over and over all the dead variables when inlining
    consuming a lot of memory at tramp3d and other C++ stuff.  Because of DECL_UID
    stability we need to do all the copying without -g too.


Patch adds BLOCK_NONLOCALIZED_VARS into BLOCK structure.  This array contains
essentially what would be ABSTRACT_ORIGIN points of declarations we would put
into BLOCK_VARS is we actually duplicated them.
dwarf2out then looks into this list and produce dies as if there was real
copied declarations.  This needs some updating at dwarf2out gen_decl_die.  I
originally had gen_abstract_origin_die function that did all the work but since
it copied part of logic from gen_variable_die and gen_formal_parameter_die I
was affraid that it will quickly get out of sync so I instead updated the
originals.

Blocks are now bigger by the extra pointer, but I believe that the patch should
result in more robust behaviour: in "C" style code blocks are not major
problem, in C++ style code we save a lot of memory by avoiding copies.  Also
debug info gets longer now since we re-add the missing info on types/decls etc.
on tramp3d it is 3.9MB to 4.4MB on .s size.

I originally tried to simply make dwaf2out to look into block's
ABSTRACT_ORIGIN and look for decls missing in the duplicated block, but
this does not work well.  In many cases we produce different
declarations with template instantiation and only during inlining things
get shared and it also makes it difficult to work out of block is emty
or wrapper or not.  The arrays itself don't seem to consume important
portions of memory and I have some extra plans for them.

As to memory consumption it turns:
tree-phinodes.c:157 (allocate_phi_node)            44724096: 3.5%          0: 0.0%          0: 0.0%    1575552: 0.9%     139149
dwarf2out.c:6502 (new_die)                           876304: 0.1%          0: 0.0%   45408272:12.7%    3560352: 1.9%     445044
gimple.c:2071 (gimple_copy)                        52636544: 4.1%          0: 0.0%          0: 0.0%    2683216: 1.5%     459125
tree-ssanames.c:141 (make_ssa_name_fn)             64915320: 5.1%          0: 0.0%     561960: 0.2%    4365152: 2.4%     545644
dwarf2out.c:5806 (add_dwarf_attr)                   1205968: 0.1%   23031792: 4.5%   68668728:19.2%   21444280:11.7%     376553
tree-inline.c:4098 (copy_decl_no_change)          103040080: 8.1%          0: 0.0%     231192: 0.1%    4528472: 2.5%     629951
tree-inline.c:3599 (copy_tree_r)                  180350112:14.2%          0: 0.0%          0: 0.0%   15316976: 8.4%    2195112
Total                                            1273977370        511868468        356959622        182993316         23403029

to:

source location                                     Garbage            Freed             Leak         Overhead            Times
tree-phinodes.c:157 (allocate_phi_node)            44760040: 3.7%          0: 0.0%          0: 0.0%    1577064: 0.9%     139229
tree-inline.c:4149 (copy_decl_no_change)           50610672: 4.1%          0: 0.0%     231024: 0.1%    2024112: 1.1%     316976
gimple.c:2071 (gimple_copy)                        52636544: 4.3%          0: 0.0%          0: 0.0%    2683216: 1.5%     459125
dwarf2out.c:6513 (new_die)                          1028976: 0.1%          0: 0.0%   58723912:15.6%    4596376: 2.6%     574547
tree-ssanames.c:141 (make_ssa_name_fn)             64933680: 5.3%          0: 0.0%     561960: 0.1%    4366376: 2.5%     545797
dwarf2out.c:5817 (add_dwarf_attr)                   1205056: 0.1%   23072112: 4.9%   67941280:18.0%   21379632:12.1%     368382
tree-inline.c:3650 (copy_tree_r)                  180352464:14.7%          0: 0.0%          0: 0.0%   15317216: 8.7%    2195139
Total                                            1222769373        472506789        377633656        176716162         23201436

So overall allocation is smaller, debug info is bigger and we produce a lot less declarations
via copy_decl_no_change.  This improvement happens without -g as well, since we no longer
have problem with stability of DECL_UID.

After IPA situation looks like this:

tree.c:964 (build_int_cst_wide)                        6096: 0.0%          0: 0.0%   14799552: 3.2%    4850464: 5.2%       3650
tree-ssa-operands.c:499 (ssa_operand_alloc)               0: 0.0%   49128528:17.6%   18746850: 4.0%    4581938: 4.9%      13010
tree-inline.c:484 (remap_block)                     4809064: 0.9%          0: 0.0%   23154872: 5.0%    2151072: 2.3%     268884
cp/lex.c:591 (copy_decl)                              23192: 0.0%          0: 0.0%   23770184: 5.1%    2485920: 2.6%      93716
dwarf2out.c:5806 (add_dwarf_attr)                         0: 0.0%   10528616: 3.8%   30906864: 6.6%    8323960: 8.8%     206845
dwarf2out.c:6502 (new_die)                                0: 0.0%          0: 0.0%   32071728: 6.9%    2467056: 2.6%     308382
tree-inline.c:4098 (copy_decl_no_change)           30058968: 5.6%          0: 0.0%   48435896:10.4%    3456496: 3.7%     478233
Total                                             533493506        278665288        465437444         94064110         12104757
to:
tree-inline.c:3650 (copy_tree_r)                   94247944:17.8%          0: 0.0%   11892816: 2.6%    9249768:10.3%    1309723
cp/pt.c:8401 (tsubst_decl)                          3027080: 0.6%          0: 0.0%   12086280: 2.7%     795440: 0.9%      99430
tree.c:964 (build_int_cst_wide)                        6096: 0.0%          0: 0.0%   14799552: 3.3%    4850464: 5.4%       3650
tree-ssa-operands.c:499 (ssa_operand_alloc)               0: 0.0%   49128528:19.6%   18746850: 4.2%    4581938: 5.1%      13010
tree-inline.c:525 (remap_block)                     4395168: 0.8%          0: 0.0%   21579552: 4.8%          0: 0.0%     270570
cp/lex.c:591 (copy_decl)                              23192: 0.0%          0: 0.0%   23770184: 5.3%    2485920: 2.8%      93716
dwarf2out.c:5817 (add_dwarf_attr)                         0: 0.0%   10582440: 4.2%   31008000: 6.9%    8337512: 9.2%     208059
dwarf2out.c:6513 (new_die)                                0: 0.0%          0: 0.0%   43613336: 9.7%    3354872: 3.7%     419359
Total                                             530367442        250608680        449399449         90222475         12030638

So overall memory footprint is smaller depite increase of block sizes and more debug info.

GDB testsuite:

@@ -8443,7 +8588,7 @@
 PASS: gdb.cp/anon-union.exp: print w 3
 PASS: gdb.cp/anon-union.exp: print z 3
 Running ../../../gdb/testsuite/gdb.cp/arg-reference.exp ...
-FAIL: gdb.cp/arg-reference.exp: No false reference
+PASS: gdb.cp/arg-reference.exp: No false reference
 Running ../../../gdb/testsuite/gdb.cp/bool.exp ...
 PASS: gdb.cp/bool.exp: print return_true()
 PASS: gdb.cp/bool.exp: print return_false()
@@ -8515,41 +8660,41 @@
 PASS: gdb.cp/classes.exp: ptype class Base1
 PASS: gdb.cp/classes.exp: ptype class Foo
 PASS: gdb.cp/classes.exp: ptype class Bar
-FAIL: gdb.cp/classes.exp: print g_A.a
-FAIL: gdb.cp/classes.exp: print g_A.x
-FAIL: gdb.cp/classes.exp: print g_B.b
-FAIL: gdb.cp/classes.exp: print g_B.x
-FAIL: gdb.cp/classes.exp: print g_C.c
-FAIL: gdb.cp/classes.exp: print g_C.x
-FAIL: gdb.cp/classes.exp: print g_D.d
-FAIL: gdb.cp/classes.exp: print g_D.x
-FAIL: gdb.cp/classes.exp: print g_E.e
-FAIL: gdb.cp/classes.exp: print g_E.x
-FAIL: gdb.cp/classes.exp: print g_A.b
-FAIL: gdb.cp/classes.exp: print g_B.c
-FAIL: gdb.cp/classes.exp: print g_B.d
-FAIL: gdb.cp/classes.exp: print g_C.b
-FAIL: gdb.cp/classes.exp: print g_C.d
-FAIL: gdb.cp/classes.exp: print g_D.e
-FAIL: gdb.cp/classes.exp: print g_A.y
-FAIL: gdb.cp/classes.exp: print g_B.z
-FAIL: gdb.cp/classes.exp: print g_C.q
-FAIL: gdb.cp/classes.exp: print g_D.p
-FAIL: gdb.cp/classes.exp: call class_param.Aptr_a (&g_A)
-FAIL: gdb.cp/classes.exp: call class_param.Aptr_x (&g_A)
-FAIL: gdb.cp/classes.exp: call class_param.Aptr_a (&g_B)
-FAIL: gdb.cp/classes.exp: call class_param.Aptr_x (&g_B)
-FAIL: gdb.cp/classes.exp: call class_param.Aref_a (g_A)
-FAIL: gdb.cp/classes.exp: call class_param.Aref_x (g_A)
-FAIL: gdb.cp/classes.exp: call class_param.Aref_a (g_B)
-FAIL: gdb.cp/classes.exp: call class_param.Aref_x (g_B)
-FAIL: gdb.cp/classes.exp: call class_param.Aval_a (g_A)
-FAIL: gdb.cp/classes.exp: call class_param.Aval_x (g_A)
-FAIL: gdb.cp/classes.exp: call class_param.Aval_a (g_B)
-FAIL: gdb.cp/classes.exp: call class_param.Aval_x (g_B)
-FAIL: gdb.cp/classes.exp: unrelated class *param
-FAIL: gdb.cp/classes.exp: unrelated class &param
-FAIL: gdb.cp/classes.exp: unrelated class param
+PASS: gdb.cp/classes.exp: print g_A.a
+PASS: gdb.cp/classes.exp: print g_A.x
+PASS: gdb.cp/classes.exp: print g_B.b
+PASS: gdb.cp/classes.exp: print g_B.x
+PASS: gdb.cp/classes.exp: print g_C.c
+PASS: gdb.cp/classes.exp: print g_C.x
+PASS: gdb.cp/classes.exp: print g_D.d
+PASS: gdb.cp/classes.exp: print g_D.x
+PASS: gdb.cp/classes.exp: print g_E.e
+PASS: gdb.cp/classes.exp: print g_E.x
+PASS: gdb.cp/classes.exp: print g_A.b
+PASS: gdb.cp/classes.exp: print g_B.c
+PASS: gdb.cp/classes.exp: print g_B.d
+PASS: gdb.cp/classes.exp: print g_C.b
+PASS: gdb.cp/classes.exp: print g_C.d
+PASS: gdb.cp/classes.exp: print g_D.e
+PASS: gdb.cp/classes.exp: print g_A.y
+PASS: gdb.cp/classes.exp: print g_B.z
+PASS: gdb.cp/classes.exp: print g_C.q
+PASS: gdb.cp/classes.exp: print g_D.p
+PASS: gdb.cp/classes.exp: call class_param.Aptr_a (&g_A)
+PASS: gdb.cp/classes.exp: call class_param.Aptr_x (&g_A)
+PASS: gdb.cp/classes.exp: call class_param.Aptr_a (&g_B)
+PASS: gdb.cp/classes.exp: call class_param.Aptr_x (&g_B)
+PASS: gdb.cp/classes.exp: call class_param.Aref_a (g_A)
+PASS: gdb.cp/classes.exp: call class_param.Aref_x (g_A)
+PASS: gdb.cp/classes.exp: call class_param.Aref_a (g_B)
+PASS: gdb.cp/classes.exp: call class_param.Aref_x (g_B)
+PASS: gdb.cp/classes.exp: call class_param.Aval_a (g_A)
+PASS: gdb.cp/classes.exp: call class_param.Aval_x (g_A)
+PASS: gdb.cp/classes.exp: call class_param.Aval_a (g_B)
+PASS: gdb.cp/classes.exp: call class_param.Aval_x (g_B)
+PASS: gdb.cp/classes.exp: unrelated class *param
+PASS: gdb.cp/classes.exp: unrelated class &param
+PASS: gdb.cp/classes.exp: unrelated class param
 PASS: gdb.cp/classes.exp: continue to enums2(\(\)|)
 PASS: gdb.cp/classes.exp: print obj_with_enum (1)
 PASS: gdb.cp/classes.exp: next
@@ -8567,18 +8712,18 @@
 PASS: gdb.cp/classes.exp: ptype &Bar::z
 PASS: gdb.cp/classes.exp: print (int)pmi == sizeof(int)
 PASS: gdb.cp/classes.exp: print Foo::st
-FAIL: gdb.cp/classes.exp: print bar.st
-FAIL: gdb.cp/classes.exp: print &foo.st
+PASS: gdb.cp/classes.exp: print bar.st
+PASS: gdb.cp/classes.exp: print &foo.st
 PASS: gdb.cp/classes.exp: print &Bar::st
-FAIL: gdb.cp/classes.exp: print *$
+PASS: gdb.cp/classes.exp: print *$
 PASS: gdb.cp/classes.exp: set print static-members off
-FAIL: gdb.cp/classes.exp: print csi without static members
-FAIL: gdb.cp/classes.exp: print cnsi without static members
+PASS: gdb.cp/classes.exp: print csi without static members
+PASS: gdb.cp/classes.exp: print cnsi without static members
 PASS: gdb.cp/classes.exp: set print static-members on
-FAIL: gdb.cp/classes.exp: print csi with static members
-FAIL: gdb.cp/classes.exp: print cnsi with static members
+PASS: gdb.cp/classes.exp: print csi with static members
+PASS: gdb.cp/classes.exp: print cnsi with static members
 PASS: gdb.cp/classes.exp: finish from marker_reg1
-PASS: gdb.cp/classes.exp: calling method for small class
+XFAIL: gdb.cp/classes.exp: calling method for small class (PRMS 2972)
 Running ../../../gdb/testsuite/gdb.cp/cp-relocate.exp ...
 PASS: gdb.cp/cp-relocate.exp: info functions
 PASS: gdb.cp/cp-relocate.exp: get address of int func<1>(int)
@@ -9654,8 +9799,8 @@
 PASS: gdb.cp/formatted-ref.exp: print/x *(&(&i))
 PASS: gdb.cp/formatted-ref.exp: print/x *(&(&e))
 Running ../../../gdb/testsuite/gdb.cp/gdb1355.exp ...
-FAIL: gdb.cp/gdb1355.exp: ptype s1
-FAIL: gdb.cp/gdb1355.exp: print s1
+PASS: gdb.cp/gdb1355.exp: ptype s1
+PASS: gdb.cp/gdb1355.exp: print s1
 Running ../../../gdb/testsuite/gdb.cp/gdb2384.exp ...
 PASS: gdb.cp/gdb2384.exp: set breakpoint (PRMS 2384)
 PASS: gdb.cp/gdb2384.exp: run to breakpoint (PRMS 2384)
@@ -9670,57 +9815,57 @@
 PASS: gdb.cp/inherit.exp: set width 0
 PASS: gdb.cp/inherit.exp: ptype A (FIXME)
 PASS: gdb.cp/inherit.exp: ptype class A (FIXME)
-FAIL: gdb.cp/inherit.exp: ptype g_A (FIXME) // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_A (FIXME)
 PASS: gdb.cp/inherit.exp: ptype B
 PASS: gdb.cp/inherit.exp: ptype class B
-FAIL: gdb.cp/inherit.exp: ptype g_B // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_B
 PASS: gdb.cp/inherit.exp: ptype C
 PASS: gdb.cp/inherit.exp: ptype class C
-FAIL: gdb.cp/inherit.exp: ptype g_C // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_C
 FAIL: gdb.cp/inherit.exp: ptype tagless struct
 FAIL: gdb.cp/inherit.exp: ptype variable of type tagless struct
 PASS: gdb.cp/inherit.exp: ptype D
 PASS: gdb.cp/inherit.exp: ptype class D
-FAIL: gdb.cp/inherit.exp: ptype g_D // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_D
 PASS: gdb.cp/inherit.exp: ptype E
 PASS: gdb.cp/inherit.exp: ptype class E
-FAIL: gdb.cp/inherit.exp: ptype g_E // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_E
 PASS: gdb.cp/inherit.exp: ptype vA
 PASS: gdb.cp/inherit.exp: ptype class vA
-FAIL: gdb.cp/inherit.exp: ptype g_vA // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_vA
 PASS: gdb.cp/inherit.exp: ptype vB
 PASS: gdb.cp/inherit.exp: ptype class vB
-FAIL: gdb.cp/inherit.exp: ptype g_vB // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_vB
 PASS: gdb.cp/inherit.exp: ptype vC
 PASS: gdb.cp/inherit.exp: ptype class vC
-FAIL: gdb.cp/inherit.exp: ptype g_vC // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_vC
 PASS: gdb.cp/inherit.exp: ptype vD
 PASS: gdb.cp/inherit.exp: ptype class vD
-FAIL: gdb.cp/inherit.exp: ptype g_vD // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_vD
 PASS: gdb.cp/inherit.exp: ptype vE
 PASS: gdb.cp/inherit.exp: ptype class vE
-FAIL: gdb.cp/inherit.exp: ptype g_vE // parse failed
+PASS: gdb.cp/inherit.exp: ptype g_vE
 PASS: gdb.cp/inherit.exp: print g_A.A::a
 PASS: gdb.cp/inherit.exp: print g_A.A::x
-FAIL: gdb.cp/inherit.exp: print g_A.a
-FAIL: gdb.cp/inherit.exp: print g_A.x
+PASS: gdb.cp/inherit.exp: print g_A.a
+PASS: gdb.cp/inherit.exp: print g_A.x
 PASS: gdb.cp/inherit.exp: print g_B.A::a
 PASS: gdb.cp/inherit.exp: print g_B.A::x
 PASS: gdb.cp/inherit.exp: print g_B.B::b
 PASS: gdb.cp/inherit.exp: print g_B.B::x
-FAIL: gdb.cp/inherit.exp: print g_B.a
-FAIL: gdb.cp/inherit.exp: print g_B.b
-FAIL: gdb.cp/inherit.exp: print g_B.x
+PASS: gdb.cp/inherit.exp: print g_B.a
+PASS: gdb.cp/inherit.exp: print g_B.b
+PASS: gdb.cp/inherit.exp: print g_B.x
 PASS: gdb.cp/inherit.exp: print g_C.A::a
 PASS: gdb.cp/inherit.exp: print g_C.A::x
 PASS: gdb.cp/inherit.exp: print g_C.C::c
 PASS: gdb.cp/inherit.exp: print g_C.C::x
-FAIL: gdb.cp/inherit.exp: print g_C.a
-FAIL: gdb.cp/inherit.exp: print g_C.c
-FAIL: gdb.cp/inherit.exp: print g_C.x
-FAIL: gdb.cp/inherit.exp: print g_A
-FAIL: gdb.cp/inherit.exp: print g_B
-FAIL: gdb.cp/inherit.exp: print g_C
+PASS: gdb.cp/inherit.exp: print g_C.a
+PASS: gdb.cp/inherit.exp: print g_C.c
+PASS: gdb.cp/inherit.exp: print g_C.x
+PASS: gdb.cp/inherit.exp: print g_A
+PASS: gdb.cp/inherit.exp: print g_B
+PASS: gdb.cp/inherit.exp: print g_C
 PASS: gdb.cp/inherit.exp: print g_A.A::a
 PASS: gdb.cp/inherit.exp: print g_A.A::x
 PASS: gdb.cp/inherit.exp: print g_B.A::a
@@ -9735,23 +9880,23 @@
 KFAIL: gdb.cp/inherit.exp: print g_D.A::x (PRMS: gdb/68)
 PASS: gdb.cp/inherit.exp: print g_D.B::b
 PASS: gdb.cp/inherit.exp: print g_D.B::x
-FAIL: gdb.cp/inherit.exp: print g_D.C::c
-FAIL: gdb.cp/inherit.exp: print g_D.C::x
+PASS: gdb.cp/inherit.exp: print g_D.C::c
+PASS: gdb.cp/inherit.exp: print g_D.C::x
 PASS: gdb.cp/inherit.exp: print g_D.D::d
 PASS: gdb.cp/inherit.exp: print g_D.D::x
 KFAIL: gdb.cp/inherit.exp: print g_E.A::a (PRMS: gdb/68)
 KFAIL: gdb.cp/inherit.exp: print g_E.A::x (PRMS: gdb/68)
 PASS: gdb.cp/inherit.exp: print g_E.B::b
 PASS: gdb.cp/inherit.exp: print g_E.B::x
-FAIL: gdb.cp/inherit.exp: print g_E.C::c
-FAIL: gdb.cp/inherit.exp: print g_E.C::x
+PASS: gdb.cp/inherit.exp: print g_E.C::c
+PASS: gdb.cp/inherit.exp: print g_E.C::x
 PASS: gdb.cp/inherit.exp: print g_E.D::d
 PASS: gdb.cp/inherit.exp: print g_E.D::x
 PASS: gdb.cp/inherit.exp: print g_E.E::e
 PASS: gdb.cp/inherit.exp: print g_E.E::x
-FAIL: gdb.cp/inherit.exp: ptype g_D.b
-FAIL: gdb.cp/inherit.exp: ptype g_D.c
-FAIL: gdb.cp/inherit.exp: ptype g_D.d
+PASS: gdb.cp/inherit.exp: ptype g_D.b
+PASS: gdb.cp/inherit.exp: ptype g_D.c
+PASS: gdb.cp/inherit.exp: ptype g_D.d
 PASS: gdb.cp/inherit.exp: ptype g_A.A::a
 PASS: gdb.cp/inherit.exp: ptype g_A.A::x
 PASS: gdb.cp/inherit.exp: ptype g_B.A::a
@@ -9780,52 +9925,52 @@
 PASS: gdb.cp/inherit.exp: ptype g_E.D::x
 PASS: gdb.cp/inherit.exp: ptype g_E.E::e
 PASS: gdb.cp/inherit.exp: ptype g_E.E::x
-FAIL: gdb.cp/inherit.exp: print g_D
-FAIL: gdb.cp/inherit.exp: print g_E
-FAIL: gdb.cp/inherit.exp: print anonymous union member
-FAIL: gdb.cp/inherit.exp: print variable of type anonymous union
-FAIL: gdb.cp/inherit.exp: print type of anonymous union // parse failed
+PASS: gdb.cp/inherit.exp: print g_D
+PASS: gdb.cp/inherit.exp: print g_E
+PASS: gdb.cp/inherit.exp: print anonymous union member
+PASS: gdb.cp/inherit.exp: print variable of type anonymous union
+FAIL: gdb.cp/inherit.exp: print type of anonymous union // unrecognized line type 1: class_with_anon_union::<anonymous union>;
 PASS: gdb.cp/inherit.exp: print g_vA.vA::va
 PASS: gdb.cp/inherit.exp: print g_vA.vA::vx
-FAIL: gdb.cp/inherit.exp: print g_vA.va
-FAIL: gdb.cp/inherit.exp: print g_vA.vx
-FAIL: gdb.cp/inherit.exp: print g_vB.vA::va
-FAIL: gdb.cp/inherit.exp: print g_vB.vA::vx
+PASS: gdb.cp/inherit.exp: print g_vA.va
+PASS: gdb.cp/inherit.exp: print g_vA.vx
+PASS: gdb.cp/inherit.exp: print g_vB.vA::va
+PASS: gdb.cp/inherit.exp: print g_vB.vA::vx
 PASS: gdb.cp/inherit.exp: print g_vB.vB::vb
 PASS: gdb.cp/inherit.exp: print g_vB.vB::vx
-FAIL: gdb.cp/inherit.exp: print g_vB.va
-FAIL: gdb.cp/inherit.exp: print g_vB.vb
-FAIL: gdb.cp/inherit.exp: print g_vB.vx
-FAIL: gdb.cp/inherit.exp: print g_vC.vA::va
-FAIL: gdb.cp/inherit.exp: print g_vC.vA::vx
+PASS: gdb.cp/inherit.exp: print g_vB.va
+PASS: gdb.cp/inherit.exp: print g_vB.vb
+PASS: gdb.cp/inherit.exp: print g_vB.vx
+PASS: gdb.cp/inherit.exp: print g_vC.vA::va
+PASS: gdb.cp/inherit.exp: print g_vC.vA::vx
 PASS: gdb.cp/inherit.exp: print g_vC.vC::vc
 PASS: gdb.cp/inherit.exp: print g_vC.vC::vx
-FAIL: gdb.cp/inherit.exp: print g_vC.va
-FAIL: gdb.cp/inherit.exp: print g_vC.vc
-FAIL: gdb.cp/inherit.exp: print g_vC.vx
-FAIL: gdb.cp/inherit.exp: print g_vA
-FAIL: gdb.cp/inherit.exp: print g_vB
-FAIL: gdb.cp/inherit.exp: print g_vC
-FAIL: gdb.cp/inherit.exp: print g_vD.vA::va
-FAIL: gdb.cp/inherit.exp: print g_vD.vA::vx
-FAIL: gdb.cp/inherit.exp: print g_vD.vB::vb
-FAIL: gdb.cp/inherit.exp: print g_vD.vB::vx
-FAIL: gdb.cp/inherit.exp: print g_vD.vC::vc
-FAIL: gdb.cp/inherit.exp: print g_vD.vC::vx
+PASS: gdb.cp/inherit.exp: print g_vC.va
+PASS: gdb.cp/inherit.exp: print g_vC.vc
+PASS: gdb.cp/inherit.exp: print g_vC.vx
+PASS: gdb.cp/inherit.exp: print g_vA
+PASS: gdb.cp/inherit.exp: print g_vB (FIXME v3 vtbl ptr)
+PASS: gdb.cp/inherit.exp: print g_vC (FIXME v3 vtbl ptr)
+PASS: gdb.cp/inherit.exp: print g_vD.vA::va
+PASS: gdb.cp/inherit.exp: print g_vD.vA::vx
+PASS: gdb.cp/inherit.exp: print g_vD.vB::vb
+PASS: gdb.cp/inherit.exp: print g_vD.vB::vx
+PASS: gdb.cp/inherit.exp: print g_vD.vC::vc
+PASS: gdb.cp/inherit.exp: print g_vD.vC::vx
 PASS: gdb.cp/inherit.exp: print g_vD.vD::vd
 PASS: gdb.cp/inherit.exp: print g_vD.vD::vx
-FAIL: gdb.cp/inherit.exp: print g_vE.vA::va
+PASS: gdb.cp/inherit.exp: print g_vE.vA::va
 PASS: gdb.cp/inherit.exp: print g_vE.vA::vx
-FAIL: gdb.cp/inherit.exp: print g_vE.vB::vb
-FAIL: gdb.cp/inherit.exp: print g_vE.vB::vx
-FAIL: gdb.cp/inherit.exp: print g_vE.vC::vc
-FAIL: gdb.cp/inherit.exp: print g_vE.vC::vx
-FAIL: gdb.cp/inherit.exp: print g_vE.vD::vd
-FAIL: gdb.cp/inherit.exp: print g_vE.vD::vx
+PASS: gdb.cp/inherit.exp: print g_vE.vB::vb
+PASS: gdb.cp/inherit.exp: print g_vE.vB::vx
+PASS: gdb.cp/inherit.exp: print g_vE.vC::vc
+PASS: gdb.cp/inherit.exp: print g_vE.vC::vx
+PASS: gdb.cp/inherit.exp: print g_vE.vD::vd
+PASS: gdb.cp/inherit.exp: print g_vE.vD::vx
 PASS: gdb.cp/inherit.exp: print g_vE.vE::ve
 PASS: gdb.cp/inherit.exp: print g_vE.vE::vx
-FAIL: gdb.cp/inherit.exp: print g_vD
-FAIL: gdb.cp/inherit.exp: print g_vE
+PASS: gdb.cp/inherit.exp: print g_vD (FIXME v3 vtbl ptr)
+PASS: gdb.cp/inherit.exp: print g_vE (FIXME v3 vtbl ptr)
 Running ../../../gdb/testsuite/gdb.cp/local.exp ...
 PASS: gdb.cp/local.exp: up from marker1
 PASS: gdb.cp/local.exp: ptype l
@@ -10026,16 +10171,16 @@
 Running ../../../gdb/testsuite/gdb.cp/misc.exp ...
 PASS: gdb.cp/misc.exp: deduced language is C++, before full symbols
 PASS: gdb.cp/misc.exp: deduced language is C++, after full symbols
-FAIL: gdb.cp/misc.exp: print s.a for foo struct (known gcc 2.7.2 and earlier bug)
+PASS: gdb.cp/misc.exp: print s.a for foo struct (known gcc 2.7.2 and earlier bug)
 PASS: gdb.cp/misc.exp: print as bool (setup)
 PASS: gdb.cp/misc.exp: print as bool (print 1 == 1)
 PASS: gdb.cp/misc.exp: print as bool (print 1 == 2)
-FAIL: gdb.cp/misc.exp: print a bool var
+PASS: gdb.cp/misc.exp: print a bool var
 PASS: gdb.cp/misc.exp: set a bool var (setup)
-FAIL: gdb.cp/misc.exp: set a bool var (print v_bool)
-FAIL: gdb.cp/misc.exp: print a bool array
+PASS: gdb.cp/misc.exp: set a bool var (print v_bool)
+PASS: gdb.cp/misc.exp: print a bool array
 PASS: gdb.cp/misc.exp: set a bool array elem (setup)
-FAIL: gdb.cp/misc.exp: set a bool array elem (print v_bool_array)
+PASS: gdb.cp/misc.exp: set a bool array elem (print v_bool_array)
 PASS: gdb.cp/misc.exp: print true
 PASS: gdb.cp/misc.exp: print false
 PASS: gdb.cp/misc.exp: 1 + true
@@ -10135,10 +10280,10 @@
 PASS: gdb.cp/overload.exp: list overloaded function with function ptr args - quotes around argument
 PASS: gdb.cp/overload.exp: print overloadNamespace(1)
 PASS: gdb.cp/overload.exp: print overloadNamespace('a')
-FAIL: gdb.cp/overload.exp: print overloadNamespace(dummyInstance)
+PASS: gdb.cp/overload.exp: print overloadNamespace(dummyInstance)
 PASS: gdb.cp/overload.exp: print overloadNamespace(1) in XXX
 PASS: gdb.cp/overload.exp: print overloadNamespace('a') in XXX
-FAIL: gdb.cp/overload.exp: print overloadNamespace(dummyInstance) in XXX
+PASS: gdb.cp/overload.exp: print overloadNamespace(dummyInstance) in XXX
 PASS: gdb.cp/overload.exp: print intToChar(1)
 Running ../../../gdb/testsuite/gdb.cp/ovldbreak.exp ...
 PASS: gdb.cp/ovldbreak.exp: set multiple-symbols ask
@@ -10193,9 +10338,9 @@
 PASS: gdb.cp/ovldbreak.exp: break foo::foofunc
 PASS: gdb.cp/ovldbreak.exp: continue until exit at finish program
 Running ../../../gdb/testsuite/gdb.cp/pass-by-ref.exp ...
-FAIL: gdb.cp/pass-by-ref.exp: call function in obj
-FAIL: gdb.cp/pass-by-ref.exp: call function in derived
-FAIL: gdb.cp/pass-by-ref.exp: call function in container
+PASS: gdb.cp/pass-by-ref.exp: call function in obj
+PASS: gdb.cp/pass-by-ref.exp: call function in derived
+PASS: gdb.cp/pass-by-ref.exp: call function in container
 Running ../../../gdb/testsuite/gdb.cp/pr-1023.exp ...
 PASS: gdb.cp/pr-1023.exp: break myClass::performBlocking
 PASS: gdb.cp/pr-1023.exp: break myClass::performUnblocking
@@ -10300,11 +10445,11 @@
 Running ../../../gdb/testsuite/gdb.cp/templates.exp ...
 PASS: gdb.cp/templates.exp: set multiple-symbols ask
 KFAIL: gdb.cp/templates.exp: ptype T5<int> (PRMS: gdb/1111)
-FAIL: gdb.cp/templates.exp: ptype t5i
+KFAIL: gdb.cp/templates.exp: ptype t5i (PRMS: gdb/1111)
 PASS: gdb.cp/templates.exp: constructor breakpoint
 KFAIL: gdb.cp/templates.exp: destructor breakpoint (PRMS: gdb/1112)
 PASS: gdb.cp/templates.exp: value method breakpoint
-FAIL: gdb.cp/templates.exp: print t5i.value()
+PASS: gdb.cp/templates.exp: print t5i.value()
 PASS: gdb.cp/templates.exp: print fint
 PASS: gdb.cp/templates.exp: print fvpchar
 PASS: gdb.cp/templates.exp: ptype Foo
@@ -10383,40 +10528,40 @@
 PASS: gdb.cp/virtfunc.exp: ptype AD
 PASS: gdb.cp/virtfunc.exp: ptype D
 PASS: gdb.cp/virtfunc.exp: ptype E
-FAIL: gdb.cp/virtfunc.exp: ptype dd // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype ppd // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pAd // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype a // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype b // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype c // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype d // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype e // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype v // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype vb // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pAa // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pAe // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pBe // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pDd // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pDe // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pVa // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pVv // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pVe // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pVd // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pADe // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pEe // parse failed
-FAIL: gdb.cp/virtfunc.exp: ptype pVB // parse failed
-FAIL: gdb.cp/virtfunc.exp: print pAe->f()
-FAIL: gdb.cp/virtfunc.exp: print pAa->f()
-FAIL: gdb.cp/virtfunc.exp: print pDe->vg()
-FAIL: gdb.cp/virtfunc.exp: print pADe->vg()
-FAIL: gdb.cp/virtfunc.exp: print pDd->vg()
-FAIL: gdb.cp/virtfunc.exp: print pEe->vvb()
-FAIL: gdb.cp/virtfunc.exp: print pVB->vvb()
-FAIL: gdb.cp/virtfunc.exp: print pBe->vvb()
-FAIL: gdb.cp/virtfunc.exp: print pDe->vvb()
-FAIL: gdb.cp/virtfunc.exp: print pEe->vd()
-FAIL: gdb.cp/virtfunc.exp: print pEe->fvb()
-FAIL: gdb.cp/virtfunc.exp: print pEe->D::vg()
+PASS: gdb.cp/virtfunc.exp: ptype dd
+PASS: gdb.cp/virtfunc.exp: ptype ppd
+PASS: gdb.cp/virtfunc.exp: ptype pAd
+PASS: gdb.cp/virtfunc.exp: ptype a
+PASS: gdb.cp/virtfunc.exp: ptype b
+PASS: gdb.cp/virtfunc.exp: ptype c
+PASS: gdb.cp/virtfunc.exp: ptype d
+PASS: gdb.cp/virtfunc.exp: ptype e
+PASS: gdb.cp/virtfunc.exp: ptype v
+PASS: gdb.cp/virtfunc.exp: ptype vb
+PASS: gdb.cp/virtfunc.exp: ptype pAa
+PASS: gdb.cp/virtfunc.exp: ptype pAe
+PASS: gdb.cp/virtfunc.exp: ptype pBe
+PASS: gdb.cp/virtfunc.exp: ptype pDd
+PASS: gdb.cp/virtfunc.exp: ptype pDe
+PASS: gdb.cp/virtfunc.exp: ptype pVa
+PASS: gdb.cp/virtfunc.exp: ptype pVv
+PASS: gdb.cp/virtfunc.exp: ptype pVe
+PASS: gdb.cp/virtfunc.exp: ptype pVd
+PASS: gdb.cp/virtfunc.exp: ptype pADe
+PASS: gdb.cp/virtfunc.exp: ptype pEe
+PASS: gdb.cp/virtfunc.exp: ptype pVB
+PASS: gdb.cp/virtfunc.exp: print pAe->f()
+PASS: gdb.cp/virtfunc.exp: print pAa->f()
+PASS: gdb.cp/virtfunc.exp: print pDe->vg()
+PASS: gdb.cp/virtfunc.exp: print pADe->vg()
+PASS: gdb.cp/virtfunc.exp: print pDd->vg()
+PASS: gdb.cp/virtfunc.exp: print pEe->vvb()
+PASS: gdb.cp/virtfunc.exp: print pVB->vvb()
+PASS: gdb.cp/virtfunc.exp: print pBe->vvb()
+PASS: gdb.cp/virtfunc.exp: print pDe->vvb()
+PASS: gdb.cp/virtfunc.exp: print pEe->vd()
+PASS: gdb.cp/virtfunc.exp: print pEe->fvb()
+KFAIL: gdb.cp/virtfunc.exp: print pEe->D::vg() (PRMS: gdb/1064)
 PASS: gdb.cp/virtfunc.exp: next to pAa->f call
 PASS: gdb.cp/virtfunc.exp: next to pDe->vg call
 PASS: gdb.cp/virtfunc.exp: step through thunk into E::vg
 

Bootstrapped/regtested x86_64-linux, OK?

	* tree.h (BLOCK_NONLOCALIZED_VARS, BLOCK_NUM_NONLOCALIZED_VARS,
	BLOCK_NONLOCALIZED_VAR): New macros.
	(tree_block): Add nonlocalized_vars.
	* dwarf2out.c (gen_formal_parameter_die, gen_variable_die, gen_decl_die): Add
	origin argument; allow generation of die with origin at hand only.
	(gen_member_die, gen_type_die_with_usage, force_decl_die,
	declare_in_namespace, gen_namescpace_die, dwarf2out_decl): Update use of gen_*.
	(gen_block_die): Fix checking for unused blocks.
	(process_scope_var): Break out from .... ; work with origins only.
	(decls_for_scope) ... here; process nonlocalized list.
	(dwarf2out_ignore_block): Look for nonlocalized vars.
	* tree-ssa-live.c (remove_unused_scope_block_p): Look for nonlocalized vars.
	(dump_scope_block): Dump them.
	* tree-inline.c (remap_decls): Handle nonlocalized vars.
	(remap_block): Likewise.
	(can_be_nonlocal): New predicate.
	(copy_bind_expr, copy_gimple_bind): Update use of remap_block.
	
Index: tree.h
===================================================================
*** tree.h	(revision 144497)
--- tree.h	(working copy)
*************** struct varray_head_tag;
*** 1968,1973 ****
--- 1968,1976 ----
  
  /* In a BLOCK node.  */
  #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
+ #define BLOCK_NONLOCALIZED_VARS(NODE) (BLOCK_CHECK (NODE)->block.nonlocalized_vars)
+ #define BLOCK_NUM_NONLOCALIZED_VARS(NODE) VEC_length (tree, BLOCK_NONLOCALIZED_VARS (NODE))
+ #define BLOCK_NONLOCALIZED_VAR(NODE,N) VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N)
  #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
  #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
  /* Note: when changing this, make sure to find the places
*************** struct tree_block GTY(())
*** 2022,2027 ****
--- 2025,2032 ----
    location_t locus;
  
    tree vars;
+   VEC(tree,gc) *nonlocalized_vars;
+ 
    tree subblocks;
    tree supercontext;
    tree abstract_origin;
Index: dwarf2out.c
===================================================================
*** dwarf2out.c	(revision 144497)
--- dwarf2out.c	(working copy)
*************** static void gen_inlined_enumeration_type
*** 5153,5163 ****
  static void gen_inlined_structure_type_die (tree, dw_die_ref);
  static void gen_inlined_union_type_die (tree, dw_die_ref);
  static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
! static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
  static void gen_unspecified_parameters_die (tree, dw_die_ref);
  static void gen_formal_types_die (tree, dw_die_ref);
  static void gen_subprogram_die (tree, dw_die_ref);
! static void gen_variable_die (tree, dw_die_ref);
  static void gen_const_die (tree, dw_die_ref);
  static void gen_label_die (tree, dw_die_ref);
  static void gen_lexical_block_die (tree, dw_die_ref, int);
--- 5153,5163 ----
  static void gen_inlined_structure_type_die (tree, dw_die_ref);
  static void gen_inlined_union_type_die (tree, dw_die_ref);
  static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
! static dw_die_ref gen_formal_parameter_die (tree, tree, dw_die_ref);
  static void gen_unspecified_parameters_die (tree, dw_die_ref);
  static void gen_formal_types_die (tree, dw_die_ref);
  static void gen_subprogram_die (tree, dw_die_ref);
! static void gen_variable_die (tree, tree, dw_die_ref);
  static void gen_const_die (tree, dw_die_ref);
  static void gen_label_die (tree, dw_die_ref);
  static void gen_lexical_block_die (tree, dw_die_ref, int);
*************** static void gen_block_die (tree, dw_die_
*** 5177,5183 ****
  static void decls_for_scope (tree, dw_die_ref, int);
  static int is_redundant_typedef (const_tree);
  static void gen_namespace_die (tree);
! static void gen_decl_die (tree, dw_die_ref);
  static dw_die_ref force_decl_die (tree);
  static dw_die_ref force_type_die (tree);
  static dw_die_ref setup_namespace_context (tree, dw_die_ref);
--- 5177,5183 ----
  static void decls_for_scope (tree, dw_die_ref, int);
  static int is_redundant_typedef (const_tree);
  static void gen_namespace_die (tree);
! static void gen_decl_die (tree, tree, dw_die_ref);
  static dw_die_ref force_decl_die (tree);
  static dw_die_ref force_type_die (tree);
  static dw_die_ref setup_namespace_context (tree, dw_die_ref);
*************** gen_enumeration_type_die (tree type, dw_
*** 13293,13308 ****
     argument type of some subprogram type.  */
  
  static dw_die_ref
! gen_formal_parameter_die (tree node, dw_die_ref context_die)
  {
    dw_die_ref parm_die
      = new_die (DW_TAG_formal_parameter, context_die, node);
-   tree origin;
  
!   switch (TREE_CODE_CLASS (TREE_CODE (node)))
      {
      case tcc_declaration:
!       origin = decl_ultimate_origin (node);
        if (origin != NULL)
  	add_abstract_origin_attribute (parm_die, origin);
        else
--- 13293,13309 ----
     argument type of some subprogram type.  */
  
  static dw_die_ref
! gen_formal_parameter_die (tree node, tree origin, dw_die_ref context_die)
  {
+   tree node_or_origin = node ? node : origin;
    dw_die_ref parm_die
      = new_die (DW_TAG_formal_parameter, context_die, node);
  
!   switch (TREE_CODE_CLASS (TREE_CODE (node_or_origin)))
      {
      case tcc_declaration:
!       if (!origin)
!         origin = decl_ultimate_origin (node);
        if (origin != NULL)
  	add_abstract_origin_attribute (parm_die, origin);
        else
*************** gen_formal_parameter_die (tree node, dw_
*** 13321,13335 ****
  	    add_AT_flag (parm_die, DW_AT_artificial, 1);
  	}
  
!       equate_decl_number_to_die (node, parm_die);
!       if (! DECL_ABSTRACT (node))
! 	add_location_or_const_value_attribute (parm_die, node, DW_AT_location);
  
        break;
  
      case tcc_type:
        /* We were called with some kind of a ..._TYPE node.  */
!       add_type_attribute (parm_die, node, 0, 0, context_die);
        break;
  
      default:
--- 13322,13338 ----
  	    add_AT_flag (parm_die, DW_AT_artificial, 1);
  	}
  
!       if (node)
!         equate_decl_number_to_die (node, parm_die);
!       if (! DECL_ABSTRACT (node_or_origin))
! 	add_location_or_const_value_attribute (parm_die, node_or_origin,
! 					       DW_AT_location);
  
        break;
  
      case tcc_type:
        /* We were called with some kind of a ..._TYPE node.  */
!       add_type_attribute (parm_die, node_or_origin, 0, 0, context_die);
        break;
  
      default:
*************** gen_formal_types_die (tree function_or_m
*** 13382,13388 ****
  	break;
  
        /* Output a (nameless) DIE to represent the formal parameter itself.  */
!       parm_die = gen_formal_parameter_die (formal_type, context_die);
        if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
  	   && link == first_parm_type)
  	  || (arg && DECL_ARTIFICIAL (arg)))
--- 13385,13391 ----
  	break;
  
        /* Output a (nameless) DIE to represent the formal parameter itself.  */
!       parm_die = gen_formal_parameter_die (formal_type, NULL, context_die);
        if ((TREE_CODE (function_or_method_type) == METHOD_TYPE
  	   && link == first_parm_type)
  	  || (arg && DECL_ARTIFICIAL (arg)))
*************** gen_type_die_for_member (tree type, tree
*** 13442,13448 ****
  	    }
  	}
        else
! 	gen_variable_die (member, type_die);
  
        pop_decl_scope ();
      }
--- 13445,13451 ----
  	    }
  	}
        else
! 	gen_variable_die (member, NULL_TREE, type_die);
  
        pop_decl_scope ();
      }
*************** gen_subprogram_die (tree decl, dw_die_re
*** 13787,13793 ****
  			    "__builtin_va_alist"))
  	      gen_unspecified_parameters_die (parm, subr_die);
  	    else
! 	      gen_decl_die (parm, subr_die);
  	  }
  
        /* Decide whether we need an unspecified_parameters DIE at the end.
--- 13790,13796 ----
  			    "__builtin_va_alist"))
  	      gen_unspecified_parameters_die (parm, subr_die);
  	    else
! 	      gen_decl_die (parm, NULL, subr_die);
  	  }
  
        /* Decide whether we need an unspecified_parameters DIE at the end.
*************** gen_subprogram_die (tree decl, dw_die_re
*** 13829,13835 ****
      {
        /* Emit a DW_TAG_variable DIE for a named return value.  */
        if (DECL_NAME (DECL_RESULT (decl)))
! 	gen_decl_die (DECL_RESULT (decl), subr_die);
  
        current_function_has_inlines = 0;
        decls_for_scope (outer_scope, subr_die, 0);
--- 13832,13838 ----
      {
        /* Emit a DW_TAG_variable DIE for a named return value.  */
        if (DECL_NAME (DECL_RESULT (decl)))
! 	gen_decl_die (DECL_RESULT (decl), NULL, subr_die);
  
        current_function_has_inlines = 0;
        decls_for_scope (outer_scope, subr_die, 0);
*************** common_block_die_table_eq (const void *x
*** 13871,13887 ****
    return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
  }
  
! /* Generate a DIE to represent a declared data object.  */
  
  static void
! gen_variable_die (tree decl, dw_die_ref context_die)
  {
    HOST_WIDE_INT off;
    tree com_decl;
    dw_die_ref var_die;
!   tree origin = decl_ultimate_origin (decl);
!   dw_die_ref old_die = lookup_decl_die (decl);
!   int declaration = (DECL_EXTERNAL (decl)
  		     /* If DECL is COMDAT and has not actually been
  			emitted, we cannot take its address; there
  			might end up being no definition anywhere in
--- 13874,13891 ----
    return d->decl_id == e->decl_id && d->die_parent == e->die_parent;
  }
  
! /* Generate a DIE to represent a declared data object.
!    Either DECL or ORIGIN must be non-null.  */
  
  static void
! gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
  {
    HOST_WIDE_INT off;
    tree com_decl;
+   tree decl_or_origin = decl ? decl : origin;
    dw_die_ref var_die;
!   dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
!   int declaration = (DECL_EXTERNAL (decl_or_origin)
  		     /* If DECL is COMDAT and has not actually been
  			emitted, we cannot take its address; there
  			might end up being no definition anywhere in
*************** gen_variable_die (tree decl, dw_die_ref 
*** 13899,13909 ****
  			Here, S<int>::i is not DECL_EXTERNAL, but no
  			definition is required, so the compiler will
  			not emit a definition.  */
! 		     || (TREE_CODE (decl) == VAR_DECL
! 			 && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
  		     || class_or_namespace_scope_p (context_die));
  
!   com_decl = fortran_common (decl, &off);
  
    /* Symbol in common gets emitted as a child of the common block, in the form
       of a data member.  */
--- 13903,13917 ----
  			Here, S<int>::i is not DECL_EXTERNAL, but no
  			definition is required, so the compiler will
  			not emit a definition.  */
! 		     || (TREE_CODE (decl_or_origin) == VAR_DECL
! 			 && DECL_COMDAT (decl_or_origin)
! 			 && !TREE_ASM_WRITTEN (decl_or_origin))
  		     || class_or_namespace_scope_p (context_die));
  
!   if (!origin)
!     origin = decl_ultimate_origin (decl);
! 
!   com_decl = fortran_common (decl_or_origin, &off);
  
    /* Symbol in common gets emitted as a child of the common block, in the form
       of a data member.  */
*************** gen_variable_die (tree decl, dw_die_ref 
*** 14071,14090 ****
    if (declaration)
      add_AT_flag (var_die, DW_AT_declaration, 1);
  
!   if (DECL_ABSTRACT (decl) || declaration)
      equate_decl_number_to_die (decl, var_die);
  
!   if (! declaration && ! DECL_ABSTRACT (decl))
      {
!       if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
!           && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
! 	defer_location (decl, var_die);
        else
!         add_location_or_const_value_attribute (var_die, decl, DW_AT_location);
!       add_pubname (decl, var_die);
      }
    else
!     tree_add_const_value_attribute (var_die, decl);
  }
  
  /* Generate a DIE to represent a named constant.  */
--- 14080,14101 ----
    if (declaration)
      add_AT_flag (var_die, DW_AT_declaration, 1);
  
!   if (decl && (DECL_ABSTRACT (decl) || declaration))
      equate_decl_number_to_die (decl, var_die);
  
!   if (! declaration && ! DECL_ABSTRACT (decl_or_origin))
      {
!       if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin)
!           && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
! 	defer_location (decl_or_origin, var_die);
        else
!         add_location_or_const_value_attribute (var_die,
! 					       decl_or_origin,
! 					       DW_AT_location);
!       add_pubname (decl_or_origin, var_die);
      }
    else
!     tree_add_const_value_attribute (var_die, decl_or_origin);
  }
  
  /* Generate a DIE to represent a named constant.  */
*************** gen_member_die (tree type, dw_die_ref co
*** 14466,14472 ****
        if (child)
  	splice_child_die (context_die, child);
        else
! 	gen_decl_die (member, context_die);
      }
  
    /* Now output info about the function members (if any).  */
--- 14477,14483 ----
        if (child)
  	splice_child_die (context_die, child);
        else
! 	gen_decl_die (member, NULL, context_die);
      }
  
    /* Now output info about the function members (if any).  */
*************** gen_member_die (tree type, dw_die_ref co
*** 14480,14486 ****
        if (child)
  	splice_child_die (context_die, child);
        else
! 	gen_decl_die (member, context_die);
      }
  }
  
--- 14491,14497 ----
        if (child)
  	splice_child_die (context_die, child);
        else
! 	gen_decl_die (member, NULL, context_die);
      }
  }
  
*************** gen_type_die_with_usage (tree type, dw_d
*** 14655,14661 ****
        gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
  
        TREE_ASM_WRITTEN (type) = 1;
!       gen_decl_die (TYPE_NAME (type), context_die);
        return;
      }
  
--- 14666,14672 ----
        gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
  
        TREE_ASM_WRITTEN (type) = 1;
!       gen_decl_die (TYPE_NAME (type), NULL, context_die);
        return;
      }
  
*************** static void
*** 14858,14864 ****
  gen_block_die (tree stmt, dw_die_ref context_die, int depth)
  {
    int must_output_die = 0;
-   tree decl;
    bool inlined_func;
  
    /* Ignore blocks that are NULL.  */
--- 14869,14874 ----
*************** gen_block_die (tree stmt, dw_die_ref con
*** 14893,14913 ****
        if (debug_info_level > DINFO_LEVEL_TERSE)
  	/* We are not in terse mode so *any* local declaration counts
  	   as being a "significant" one.  */
! 	must_output_die = (BLOCK_VARS (stmt) != NULL
  			   && (TREE_USED (stmt)
  			       || TREE_ASM_WRITTEN (stmt)
  			       || BLOCK_ABSTRACT (stmt)));
!       else
! 	/* We are in terse mode, so only local (nested) function
! 	   definitions count as "significant" local declarations.  */
! 	for (decl = BLOCK_VARS (stmt);
! 	     decl != NULL; decl = TREE_CHAIN (decl))
! 	  if (TREE_CODE (decl) == FUNCTION_DECL
! 	      && DECL_INITIAL (decl))
! 	    {
! 	      must_output_die = 1;
! 	      break;
! 	    }
      }
  
    /* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
--- 14903,14915 ----
        if (debug_info_level > DINFO_LEVEL_TERSE)
  	/* We are not in terse mode so *any* local declaration counts
  	   as being a "significant" one.  */
! 	must_output_die = ((BLOCK_VARS (stmt) != NULL
! 			    || BLOCK_NUM_NONLOCALIZED_VARS (stmt))
  			   && (TREE_USED (stmt)
  			       || TREE_ASM_WRITTEN (stmt)
  			       || BLOCK_ABSTRACT (stmt)));
!       else if (!dwarf2out_ignore_block (stmt))
! 	must_output_die = 1;
      }
  
    /* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
*************** gen_block_die (tree stmt, dw_die_ref con
*** 14928,14933 ****
--- 14930,14964 ----
      decls_for_scope (stmt, context_die, depth);
  }
  
+ /* Process variable DECL (or variable with origin ORIGIN) withing
+    block STMT and add it to CONTEXT_DIE.  */
+ static void
+ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
+ {
+   dw_die_ref die;
+   tree decl_or_origin = decl ? decl : origin;
+   tree ultimate_origin = origin ? decl_ultimate_origin (origin) : NULL;
+ 
+   if (ultimate_origin)
+     origin = ultimate_origin;
+ 
+   if (TREE_CODE (decl_or_origin) == FUNCTION_DECL)
+     die = lookup_decl_die (decl_or_origin);
+   else if (TREE_CODE (decl_or_origin) == TYPE_DECL
+            && TYPE_DECL_IS_STUB (decl_or_origin))
+     die = lookup_type_die (TREE_TYPE (decl_or_origin));
+   else
+     die = NULL;
+ 
+   if (die != NULL && die->die_parent == NULL)
+     add_child_die (context_die, die);
+   else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
+     dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME (decl_or_origin),
+ 					 stmt, context_die);
+   else
+     gen_decl_die (decl, origin, context_die);
+ }
+ 
  /* Generate all of the decls declared within a given scope and (recursively)
     all of its sub-blocks.  */
  
*************** static void
*** 14935,14972 ****
  decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
  {
    tree decl;
    tree subblocks;
  
    /* Ignore NULL blocks.  */
    if (stmt == NULL_TREE)
      return;
  
!   if (TREE_USED (stmt))
!     {
!       /* Output the DIEs to represent all of the data objects and typedefs
! 	 declared directly within this block but not within any nested
! 	 sub-blocks.  Also, nested function and tag DIEs have been
! 	 generated with a parent of NULL; fix that up now.  */
!       for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
! 	{
! 	  dw_die_ref die;
! 
! 	  if (TREE_CODE (decl) == FUNCTION_DECL)
! 	    die = lookup_decl_die (decl);
! 	  else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
! 	    die = lookup_type_die (TREE_TYPE (decl));
! 	  else
! 	    die = NULL;
! 
! 	  if (die != NULL && die->die_parent == NULL)
! 	    add_child_die (context_die, die);
! 	  else if (TREE_CODE (decl) == IMPORTED_DECL)
! 	    dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
! 						 stmt, context_die);
! 	  else
! 	    gen_decl_die (decl, context_die);
! 	}
!     }
  
    /* If we're at -g1, we're not interested in subblocks.  */
    if (debug_info_level <= DINFO_LEVEL_TERSE)
--- 14966,14987 ----
  decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
  {
    tree decl;
+   unsigned int i;
    tree subblocks;
  
    /* Ignore NULL blocks.  */
    if (stmt == NULL_TREE)
      return;
  
!   /* Output the DIEs to represent all of the data objects and typedefs
!      declared directly within this block but not within any nested
!      sub-blocks.  Also, nested function and tag DIEs have been
!      generated with a parent of NULL; fix that up now.  */
!   for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
!     process_scope_var (stmt, decl, NULL_TREE, context_die);
!   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
!     process_scope_var (stmt, NULL, BLOCK_NONLOCALIZED_VAR (stmt, i),
!     		       context_die);
  
    /* If we're at -g1, we're not interested in subblocks.  */
    if (debug_info_level <= DINFO_LEVEL_TERSE)
*************** force_decl_die (tree decl)
*** 15049,15055 ****
  	   gen_decl_die() call.  */
  	  saved_external_flag = DECL_EXTERNAL (decl);
  	  DECL_EXTERNAL (decl) = 1;
! 	  gen_decl_die (decl, context_die);
  	  DECL_EXTERNAL (decl) = saved_external_flag;
  	  break;
  
--- 15064,15070 ----
  	   gen_decl_die() call.  */
  	  saved_external_flag = DECL_EXTERNAL (decl);
  	  DECL_EXTERNAL (decl) = 1;
! 	  gen_decl_die (decl, NULL, context_die);
  	  DECL_EXTERNAL (decl) = saved_external_flag;
  	  break;
  
*************** declare_in_namespace (tree thing, dw_die
*** 15132,15138 ****
        if (is_fortran ())
  	return ns_context;
        if (DECL_P (thing))
! 	gen_decl_die (thing, ns_context);
        else
  	gen_type_die (thing, ns_context);
      }
--- 15147,15153 ----
        if (is_fortran ())
  	return ns_context;
        if (DECL_P (thing))
! 	gen_decl_die (thing, NULL, ns_context);
        else
  	gen_type_die (thing, ns_context);
      }
*************** gen_namespace_die (tree decl)
*** 15183,15196 ****
  /* Generate Dwarf debug information for a decl described by DECL.  */
  
  static void
! gen_decl_die (tree decl, dw_die_ref context_die)
  {
!   tree origin;
  
!   if (DECL_P (decl) && DECL_IGNORED_P (decl))
      return;
  
!   switch (TREE_CODE (decl))
      {
      case ERROR_MARK:
        break;
--- 15198,15212 ----
  /* Generate Dwarf debug information for a decl described by DECL.  */
  
  static void
! gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
  {
!   tree decl_or_origin = decl ? decl : origin;
!   tree class_origin = NULL;
  
!   if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin))
      return;
  
!   switch (TREE_CODE (decl_or_origin))
      {
      case ERROR_MARK:
        break;
*************** gen_decl_die (tree decl, dw_die_ref cont
*** 15257,15263 ****
  	    gen_type_die (DECL_CONTEXT (decl), context_die);
  
  	  /* And its containing type.  */
! 	  origin = decl_class_context (decl);
  	  if (origin != NULL_TREE)
  	    gen_type_die_for_member (origin, decl, context_die);
  
--- 15273,15280 ----
  	    gen_type_die (DECL_CONTEXT (decl), context_die);
  
  	  /* And its containing type.  */
! 	  if (!origin)
! 	    origin = decl_class_context (decl);
  	  if (origin != NULL_TREE)
  	    gen_type_die_for_member (origin, decl, context_die);
  
*************** gen_decl_die (tree decl, dw_die_ref cont
*** 15309,15336 ****
  
        /* Output any DIEs that are needed to specify the type of this data
  	 object.  */
!       if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl))
! 	gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
        else
! 	gen_type_die (TREE_TYPE (decl), context_die);
  
        /* And its containing type.  */
!       origin = decl_class_context (decl);
!       if (origin != NULL_TREE)
! 	gen_type_die_for_member (origin, decl, context_die);
  
        /* And its containing namespace.  */
!       context_die = declare_in_namespace (decl, context_die);
  
        /* Now output the DIE to represent the data object itself.  This gets
  	 complicated because of the possibility that the VAR_DECL really
  	 represents an inlined instance of a formal parameter for an inline
  	 function.  */
!       origin = decl_ultimate_origin (decl);
        if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
! 	gen_formal_parameter_die (decl, context_die);
        else
! 	gen_variable_die (decl, context_die);
        break;
  
      case FIELD_DECL:
--- 15326,15355 ----
  
        /* Output any DIEs that are needed to specify the type of this data
  	 object.  */
!       if (TREE_CODE (decl_or_origin) == RESULT_DECL
!           && DECL_BY_REFERENCE (decl_or_origin))
! 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
        else
! 	gen_type_die (TREE_TYPE (decl_or_origin), context_die);
  
        /* And its containing type.  */
!       class_origin = decl_class_context (decl_or_origin);
!       if (class_origin != NULL_TREE)
! 	gen_type_die_for_member (class_origin, decl_or_origin, context_die);
  
        /* And its containing namespace.  */
!       context_die = declare_in_namespace (decl_or_origin, context_die);
  
        /* Now output the DIE to represent the data object itself.  This gets
  	 complicated because of the possibility that the VAR_DECL really
  	 represents an inlined instance of a formal parameter for an inline
  	 function.  */
!       if (!origin)
!         origin = decl_ultimate_origin (decl);
        if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
! 	gen_formal_parameter_die (decl, origin, context_die);
        else
! 	gen_variable_die (decl, origin, context_die);
        break;
  
      case FIELD_DECL:
*************** gen_decl_die (tree decl, dw_die_ref cont
*** 15346,15356 ****
        break;
  
      case PARM_DECL:
!       if (DECL_BY_REFERENCE (decl))
! 	gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);
        else
! 	gen_type_die (TREE_TYPE (decl), context_die);
!       gen_formal_parameter_die (decl, context_die);
        break;
  
      case NAMESPACE_DECL:
--- 15365,15375 ----
        break;
  
      case PARM_DECL:
!       if (DECL_BY_REFERENCE (decl_or_origin))
! 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
        else
! 	gen_type_die (TREE_TYPE (decl_or_origin), context_die);
!       gen_formal_parameter_die (decl, origin, context_die);
        break;
  
      case NAMESPACE_DECL:
*************** dwarf2out_decl (tree decl)
*** 15641,15647 ****
        return;
      }
  
!   gen_decl_die (decl, context_die);
  }
  
  /* Output a marker (i.e. a label) for the beginning of the generated code for
--- 15660,15666 ----
        return;
      }
  
!   gen_decl_die (decl, NULL, context_die);
  }
  
  /* Output a marker (i.e. a label) for the beginning of the generated code for
*************** static bool
*** 15676,15686 ****
--- 15695,15713 ----
  dwarf2out_ignore_block (const_tree block)
  {
    tree decl;
+   unsigned int i;
  
    for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
      if (TREE_CODE (decl) == FUNCTION_DECL
  	|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
        return 0;
+   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (block); i++)
+     {
+       decl = BLOCK_NONLOCALIZED_VAR (block, i);
+       if (TREE_CODE (decl) == FUNCTION_DECL
+ 	  || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
+       return 0;
+     }
  
    return 1;
  }
Index: tree-ssa-live.c
===================================================================
*** tree-ssa-live.c	(revision 144497)
--- tree-ssa-live.c	(working copy)
*************** remove_unused_scope_block_p (tree scope)
*** 583,589 ****
     else if (debug_info_level == DINFO_LEVEL_NONE
  	    || debug_info_level == DINFO_LEVEL_TERSE)
       ;
!    else if (BLOCK_VARS (scope))
       unused = false;
     /* See if this block is important for representation of inlined function.
        Inlined functions are always represented by block with
--- 583,589 ----
     else if (debug_info_level == DINFO_LEVEL_NONE
  	    || debug_info_level == DINFO_LEVEL_TERSE)
       ;
!    else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope))
       unused = false;
     /* See if this block is important for representation of inlined function.
        Inlined functions are always represented by block with
*************** static void
*** 613,618 ****
--- 613,619 ----
  dump_scope_block (FILE *file, int indent, tree scope, int flags)
  {
    tree var, t;
+   unsigned int i;
  
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" , BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
*************** dump_scope_block (FILE *file, int indent
*** 648,653 ****
--- 649,661 ----
        print_generic_decl (file, var, flags);
        fprintf (file, "%s\n", used ? "" : " (unused)");
      }
+   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++)
+     {
+       fprintf (file, "%*s",indent, "");
+       print_generic_decl (file, BLOCK_NONLOCALIZED_VAR (scope, i),
+       			  flags);
+       fprintf (file, " (nonlocalized)\n");
+     }
    for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
      dump_scope_block (file, indent + 2, t, flags);
    fprintf (file, "\n%*s}\n",indent, "");
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 144497)
--- tree-inline.c	(working copy)
*************** eni_weights eni_time_weights;
*** 122,128 ****
  static tree declare_return_variable (copy_body_data *, tree, tree, tree *);
  static bool inlinable_function_p (tree);
  static void remap_block (tree *, copy_body_data *);
- static tree remap_decls (tree, copy_body_data *);
  static void copy_bind_expr (tree *, int *, copy_body_data *);
  static tree mark_local_for_remap_r (tree *, int *, void *);
  static void unsave_expr_1 (tree);
--- 122,127 ----
*************** remap_type (tree type, copy_body_data *i
*** 427,434 ****
    return tmp;
  }
  
  static tree
! remap_decls (tree decls, copy_body_data *id)
  {
    tree old_var;
    tree new_decls = NULL_TREE;
--- 426,469 ----
    return tmp;
  }
  
+ /* Decide if DECL can be put into BLOCK_NONLOCAL_VARs.  */
+   
+ static bool
+ can_be_nonlocal (tree decl, copy_body_data *id)
+ {
+   /* At the moment dwarf2out can handle only these types of nodes.  We
+      can support more later.  */
+   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL)
+     return false;
+ 
+   /* Local static vars must be non-local or we get multiple declaration
+      problems.  */
+   if (TREE_CODE (decl) == VAR_DECL
+       && !auto_var_in_fn_p (decl, id->src_fn))
+     return true;
+ 
+   /* We must use global type.  */
+   if (TREE_TYPE (decl) != remap_type (TREE_TYPE (decl), id))
+     return false;
+ 
+   /* Wihtout SSA we can't tell if variable is used.  */
+   if (!gimple_in_ssa_p (cfun))
+     return false;
+ 
+   /* Live variables must be copied so we can attach DECL_RTL.  */
+   if (var_ann (decl))
+     return false;
+ 
+ #ifdef ENABLE_CHECKING
+   /* Make us die in horrible death if we will somehow reference
+      this varible later.  */
+   insert_decl_map (id, decl, (tree)(size_t) 1);
+ #endif
+   return true;
+ }
+ 
  static tree
! remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
  {
    tree old_var;
    tree new_decls = NULL_TREE;
*************** remap_decls (tree decls, copy_body_data 
*** 437,452 ****
    for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
      {
        tree new_var;
  
!       /* We cannot chain the local static declarations into the local_decls
! 	 as we can't duplicate them or break one decl rule.  Go ahead
! 	 and link them into local_decls.  */
! 
!       if (!auto_var_in_fn_p (old_var, id->src_fn)
! 	  && !DECL_EXTERNAL (old_var))
  	{
! 	  cfun->local_decls = tree_cons (NULL_TREE, old_var,
! 						 cfun->local_decls);
  	  continue;
  	}
  
--- 472,487 ----
    for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
      {
        tree new_var;
+       tree origin_var = DECL_ORIGIN (old_var);
  
!       if (can_be_nonlocal (old_var, id))
  	{
! 	  if (TREE_CODE (old_var) == VAR_DECL
! 	      && (var_ann (old_var) || !gimple_in_ssa_p (cfun)))
! 	    cfun->local_decls = tree_cons (NULL_TREE, old_var,
! 						   cfun->local_decls);
! 	  if (debug_info_level > DINFO_LEVEL_TERSE)
! 	    VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
  	  continue;
  	}
  
*************** remap_decls (tree decls, copy_body_data 
*** 456,463 ****
        /* If we didn't remap this variable, we can't mess with its
  	 TREE_CHAIN.  If we remapped this variable to the return slot, it's
  	 already declared somewhere else, so don't declare it here.  */
!       if (!new_var || new_var == id->retvar)
  	;
        else
  	{
  	  gcc_assert (DECL_P (new_var));
--- 491,504 ----
        /* If we didn't remap this variable, we can't mess with its
  	 TREE_CHAIN.  If we remapped this variable to the return slot, it's
  	 already declared somewhere else, so don't declare it here.  */
!       
!       if (new_var == id->retvar)
  	;
+       else if (!new_var)
+         {
+ 	  if (debug_info_level > DINFO_LEVEL_TERSE)
+ 	    VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
+ 	}
        else
  	{
  	  gcc_assert (DECL_P (new_var));
*************** remap_block (tree *block, copy_body_data
*** 485,494 ****
    TREE_USED (new_block) = TREE_USED (old_block);
    BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
    BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
    *block = new_block;
  
    /* Remap its variables.  */
!   BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), id);
  
    fn = id->dst_fn;
  
--- 526,539 ----
    TREE_USED (new_block) = TREE_USED (old_block);
    BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
    BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
+   BLOCK_NONLOCALIZED_VARS (new_block)
+     = VEC_copy (tree, gc, BLOCK_NONLOCALIZED_VARS (old_block));
    *block = new_block;
  
    /* Remap its variables.  */
!   BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block),
!   					&BLOCK_NONLOCALIZED_VARS (new_block),
! 					id);
  
    fn = id->dst_fn;
  
*************** copy_bind_expr (tree *tp, int *walk_subt
*** 549,555 ****
    if (BIND_EXPR_VARS (*tp))
      /* This will remap a lot of the same decls again, but this should be
         harmless.  */
!     BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), id);
  }
  
  
--- 594,600 ----
    if (BIND_EXPR_VARS (*tp))
      /* This will remap a lot of the same decls again, but this should be
         harmless.  */
!     BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
  }
  
  
*************** copy_gimple_bind (gimple stmt, copy_body
*** 595,601 ****
       harmless.  */
    new_vars = gimple_bind_vars (stmt);
    if (new_vars)
!     new_vars = remap_decls (new_vars, id);
  
    new_bind = gimple_build_bind (new_vars, new_body, new_block);
  
--- 640,646 ----
       harmless.  */
    new_vars = gimple_bind_vars (stmt);
    if (new_vars)
!     new_vars = remap_decls (new_vars, NULL, id);
  
    new_bind = gimple_build_bind (new_vars, new_body, new_block);
  
*************** replace_locals_stmt (gimple_stmt_iterato
*** 3910,3916 ****
        /* This will remap a lot of the same decls again, but this should be
  	 harmless.  */
        if (gimple_bind_vars (stmt))
! 	gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), id));
      }
  
    /* Keep iterating.  */
--- 3956,3962 ----
        /* This will remap a lot of the same decls again, but this should be
  	 harmless.  */
        if (gimple_bind_vars (stmt))
! 	gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), NULL, id));
      }
  
    /* Keep iterating.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]