[PATCH] Fix PTA with lots of SFTs

Daniel Berlin dberlin@dberlin.org
Wed Nov 14 19:50:00 GMT 2007


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.



More information about the Gcc-patches mailing list