This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PTA with lots of SFTs
- From: "Daniel Berlin" <dberlin at dberlin dot org>
- To: "Richard Guenther" <rguenther at suse dot de>
- Cc: gcc-patches at gcc dot gnu dot org, dnovillo at google dot com
- Date: Wed, 14 Nov 2007 12:18:48 -0500
- Subject: Re: [PATCH] Fix PTA with lots of SFTs
- References: <Pine.LNX.4.64.0711141714440.4153@zhemvz.fhfr.qr>
On 11/14/07, Richard Guenther <rguenther@suse.de> wrote:
>
> Currently we have a mismatch between when we create SFTs for a structure
> ("always")
> and when we create variable info structs for PTA (only if
> we have less than MAX_FIELDS_FOR_FIELD_SENSITIVE per struct). This causes
> wrong virtual operands if there's a mismatch. For example in
>
> struct X { int i; int j; };
> #define FOO struct X
> #define FOO10(x) FOO x ## 0; FOO x ## 1; FOO x ## 2; FOO x ## 3; FOO x ##
> 4; FOO x ## 5; FOO x ## 6; FOO x ## 7; FOO x ## 8; FOO x ## 9;
> struct Y {
> FOO10(x0)
> FOO10(x1)
> FOO10(x2)
> FOO10(x3)
> FOO10(x4)
> /*FOO10(x5) */
> struct X x50;
> } m;
>
> #define COO(n,f) case n: p = &m.f; break;
> #define COO10(n,f) COO(n ## 0, f ## 0) COO(n ## 1, f ## 1) COO(n ## 2, f
> ## 2) COO(n ## 3, f ## 3) COO(n ## 4, f ## 4) COO(n ## 5, f ## 5) COO(n ##
> 6, f ## 6) COO(n ## 7, f ## 7) COO(n ## 8, f ## 8) COO(n ## 9, f ## 9)
> int foo(int i)
> {
> struct X *p = 0;
> m.x00.i = 0;
> switch (i)
> {
> COO10(1, x0)
> COO10(2, x1)
> COO10(3, x2)
> COO10(4, x3)
> COO10(5, x4)
> /* COO10(6, x5) */
> case 60: p = &m.x50; break;
> }
> return p->j;
> }
>
> we currently generate
>
> # SFT.0_58 = VDEF <SFT.0_57(D)>
> m.x00.i = 0;
> ...
> # p_1 = PHI <0B(2), &m.x00(3), &m.x01(4), &m.x02(5), &m.x03(6),
> &m.x04(7), &m.x05(8), &m.x06(9), &m.x07(10), &m.x08(11), &m.x09(12),
> &m.x10(13), &m.x11(14), &m.x12(15), &m.x13(16), &m.x14(17), &m.x15(18),
> &m.x16(19), &m.x17(20), &m.x18(21), &m.x19(22), &m.x20(23), &m.x21(24),
> &m.x22(25), &m.x23(26), &m.x24(27), &m.x25(28), &m.x26(29), &m.x27(30),
> &m.x28(31), &m.x29(32), &m.x30(33), &m.x31(34), &m.x32(35), &m.x33(36),
> &m.x34(37), &m.x35(38), &m.x36(39), &m.x37(40), &m.x38(41), &m.x39(42),
> &m.x40(43), &m.x41(44), &m.x42(45), &m.x43(46), &m.x44(47), &m.x45(48),
> &m.x46(49), &m.x47(50), &m.x48(51), &m.x49(52), &m.x50(53)>
> <L51>:;
> # VUSE <SFT.1_59(D)>
> D.1652_55 = p_1->j;
>
> (that is, we only use SFT.1 here!)
>
> while if you comment out the last field and the last case then you get
> (viola, only 99 variable infos needed):
>
> # VUSE <SFT.1_58(D), SFT.3_59(D), SFT.5_60(D), SFT.7_61(D), SFT.9_62(D),
> SFT.11_63(D), SFT.13_64(D), SFT.15_65(D), SFT.17_66(D), SFT.19_67(D),
> SFT.21_68(D), SFT.23_69(D), SFT.25_70(D), SFT.27_71(D), SFT.29_72(D),
> SFT.31_73(D), SFT.33_74(D), SFT.35_75(D), SFT.37_76(D), SFT.39_77(D),
> SFT.41_78(D), SFT.43_79(D), SFT.45_80(D), SFT.47_81(D), SFT.49_82(D),
> SFT.51_83(D), SFT.53_84(D), SFT.55_85(D), SFT.57_86(D), SFT.59_87(D),
> SFT.61_88(D), SFT.63_89(D), SFT.65_90(D), SFT.67_91(D), SFT.69_92(D),
> SFT.71_93(D), SFT.73_94(D), SFT.75_95(D), SFT.77_96(D), SFT.79_97(D),
> SFT.81_98(D), SFT.83_99(D), SFT.85_100(D), SFT.87_101(D), SFT.89_102(D),
> SFT.91_103(D), SFT.93_104(D), SFT.95_105(D), SFT.97_106(D), SFT.99_107(D)>
> D.1650_54 = p_1->j;
>
> which is correct.
>
> The difference is ultimatively because points-to and operand scanning
> disagree about whether they did field-sensitive analysis.
>
When PTA doesn't do field sensitive analysis, it should have chosen to
say the entire variable is pointed-to, because that is all it creates
in the way of variable info.
This should end up translating into all the SFT's in set_uids_in_ptset.
That this is not happening is going to cause bugs elsewhere (in
particular, when we collapse C++ variables because of weird front end
issues), and your fix won't fix those.
Hmmm.
I see what is happening.
This is a bug in set_uids_in_ptset. It's not taking into account that
their may be more than one sft per var when
MAX_FIELDS_FOR_FIELD_SENSITIVE is hit. It assumes if the variable has
subvars, that we built separate vars for it (same problem you
mentioned, different place).
I think the right way to fix this is to take into account the size of
the varinfo here:
if (var_can_have_subvars (vi->decl)
&& get_subvars_for_var (vi->decl))
{
/* If VI->DECL is an aggregate for which we created
SFTs, add the SFT corresponding to VI->OFFSET. */
tree sft = get_subvar_at (vi->decl, vi->offset);
and make it into a loop so it gets all the subvars until it hits the
size of the variable.