Related articles |
---|
Looking for Dependency Analysis Tool for C grtmail@patmedia.net (2004-08-23) |
Re: Looking for Dependency Analysis Tool for C nmm1@cus.cam.ac.uk (2004-08-25) |
Re: Looking for Dependency Analysis Tool for C dnovillo@redhat.com (Diego Novillo) (2004-09-03) |
Re: Looking for Dependency Analysis Tool for C nmm1@cus.cam.ac.uk (2004-09-07) |
Re: Looking for Dependency Analysis Tool for C skaller@nospam.com.au (John Max Skaller) (2004-09-07) |
Re: Looking for Dependency Analysis Tool for C dnovillo@redhat.com (Diego Novillo) (2004-09-08) |
From: | Diego Novillo <dnovillo@redhat.com> |
Newsgroups: | comp.compilers |
Date: | 8 Sep 2004 12:11:42 -0400 |
Organization: | Red Hat Canada |
References: | 04-08-124 04-09-004 04-09-037 |
Keywords: | analysis |
Posted-Date: | 08 Sep 2004 12:11:42 EDT |
On Tue, 2004-09-07 at 23:32, Nick Maclaren wrote:
> #ifdef __STDC_IEC_559__
> #pragma STDC FENV_ACCESS ON
> ... Usual usage omitted ...
> double a = ..., b;
> b = a+a;
> #endif
>
> Now, how do you convert the 'b = a+a;' to single-assignment form?
> Depending on the value of a, it may assign to b or assign to b and
> the floating-point flags.
At the IL level that GCC operates in SSA form, floating-point flags
are not considered. This will be, b_2 = a_1 + a_1. But, I agree with
your conclusion, as you push your IL down into the abstraction ladder
you will find IL constructs that are hard or impossible to represent.
GCC certainly had that problem when an SSA representation over RTL was
initially implemented and later abandoned.
> And, under the conditions I have specified,
> those two assignations are atomic. 'b = a/a;' is marginally worse,
> in that it assigns to the flags only if a is zero or an infinity.
> There are similar issues with some library functions.
For operations that may throw an exception, GCC does split the
expression. b = a/a becomes,
tmp_1 = a_2 / a_2
# END OF BASIC BLOCK
b_3 = tmp_1
The basic block finished by the division expression will have the
standard fallthru edge and an exception edge to the EH handling block.
> typedef struct {int a; double b; int c;} COMPOSITE;
> COMPOSITE composite = {0,0.0,0};
> int *r;
> r = (int *)(((char *)&composite)+offsetof(COMPOSITE,c));
> composite.a = *r = 0.0;
>
> As the joke goes, what and with which and to whom? Such code really
> does exist (and I could name culprits), and no sane compiler is
> likely to get far working out the aliasing. Especially as it can be
> a LOT for obfuscated than that and even halting problem equivalent.
Right. That's why GCC has thresholds on aliasing and structures.
Currently, if a structure can't be scalarized GCC will glob structure
references into the base name.
In this case GCC will mark 'r' as pointing to 'composite'. Dereferences
of 'r' are considered references to 'composite'. The assignments to 'r'
and 'composite.a' are represented in GIMPLE SSA form as:
composite.1_3 = (char *)&composite;
T.2_4 = composite.1_3 + 12B;
r_5 = (int *)T.2_4;
# composite_10 = V_MAY_DEF <composite_9>;
*r_5 = 0;
# VUSE <composite_10>;
T.3_6 = *r_5;
# composite_7 = V_MAY_DEF <composite_10>;
composite.a = T.3_6;
The VUSE and V_MAY_DEF constructs are used to keep track of aliased
stores and loads.
There is new work underway to implement field-sensitive aliasing and
better handling of non-scalarizable structures. That won't probably
appear until 3.6 or so.
Diego.
Return to the
comp.compilers page.
Search the
comp.compilers archives again.