Fix PR 33870

Diego Novillo dnovillo@google.com
Tue Nov 13 16:30:00 GMT 2007


Richard Guenther wrote:

> taking the address of result.x.pDirty causes the SFT to be marked as
> in substructure and the problem re-surfaces.

Yes.  Thanks for the test case.  The original patch did not take into 
account that the nesting level of the memory reference is also important.

There are two problems here:

1- Given an arbitrary memory expression M dereferencing a pointer P into 
a nested structure, the offset computed for M is the offset starting at 
P.  However, the offsets computed for the original SFTs are offsets from 
the top of the pointed-to memory object O.  So, when we recognize this 
situation, we must adjust the offsets.  This was the situation 
recognized and fixed by the original patch.

The bug was in the detection of whether P is "pointing to the middle of 
an object".  This is where the nesting level comes in to play.  Suppose 
that M was the expression p_3->b[3] and the original pointed-to object 
was v.x.y:

		struct {
			...
			struct {
				...
				struct {
					...
					int b[4];
				} y;
			} x;
		} v;

		p_3 = &v.x.y;

If alias analysis created SFTs for this structure, the array 'b' will 
have 4 SFTs associated with it.  Say SFT.12, SFT.13, SFT.14 and SFT.15. 
  However, only SFT.12 will be added to the alias set of p_3's name tag.

So, when we see the expression 'p_3->b[3]', we compute an offset of 96, 
but we need SFT.14 which will probably have an offset much higher than 
that.  So, we adjust 96 by the offset of SFT.12 and get to SFT.14.

In the original patch, we recognized this situation by asking whether 
the SFT.12 was inside a nested structure.  However, it may happen that 
the pointer was actually pointing to the base of the original object 
'v'.  In which case, we would have the expression 'p_3->x.y.b[3]', which 
also takes us to SFT.12.

But in this case, the offset we computed from 'p_3->x.y.b[3]' is 
*already* the right offset, so adding the offset of SFT.12 to it gives 
us the wrong offset.  So, what this patch does is determine the nesting 
level of each SFT and the nesting level of the memory expression.  We 
only need to adjust the offset of an SFT if the nesting level of the 
memory expression is lower than the nesting level of the SFT that we are 
analyzing.


2- The second problem we have with this scheme is that we rely on the 
presence of key SFTs to adjust offsets when we detect references to 
nested aggregates.  This is something we cannot easily undo because 
inside the operand scanner we cannot really start doing use-def chain 
chasing to determine the original pointed-to objects.  This work has 
already been done by alias analysis, so duplicating this in the operand 
scanner would be wasteful.

This means that this scheme cannot tolerate these key SFTs to be 
partitioned away.  If they are partitioned, then inside the operand 
scanner is essentially impossible to determine where in the structure is 
an arbitrary memory expression referring to.  This is shown in the new 
test gcc.dg/tree-ssa/alias-16.c.

One way to deal with this would be to use the pointed-to set for the 
base pointer instead of the alias set of the name tag.  This has the 
problem that we'd miss the compile-time benefits of partitioning, as we 
would be traversing the original sets instead of the partitioned 
(smaller) alias sets.  Also, we may want to get rid of the duplicate 
pointed-to/alias sets in the future (not sure if they're both worth 
keeping).

The other way of dealing with this is to recognize which SFTs are 
important to not partition and make sure they are never partitioned. 
During alias analysis, if a nested SFT is added to the alias set of a 
pointer, then it is marked as unpartitionable.  The partitioner, in 
turn, gives these SFTs a very high score and makes sure that they are 
never added to a partition.  The effects of this are/should be 
negligible as it only involves a single SFT and nested structures.

The new test alias-16.c tests for these edge cases.

Tested on x86_64 and ppc64.  Committed to trunk.


Diego.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: 20071113-33870-nesting-level.diff.txt
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20071113/45d69dce/attachment.txt>


More information about the Gcc-patches mailing list