------- Comment #3 from dnovillo at gcc dot gnu dot org 2006-09-28 18:32 -------
Excerpts from IRC session with jakub discussing this: 13:28 <dnovillo> 1 grow (); 13:28 <dnovillo> 2 node = pool; 13:28 <dnovillo> 3 D.1928 = node->next; 13:28 <dnovillo> 4 pool = D.1928; 13:28 <dnovillo> 5 foo = (struct Foo *) node; 13:28 <dnovillo> 6 foo->a = 0; 13:28 <dnovillo> 7 foo->b = -1; 13:28 <dnovillo> 8 node = (struct Node *) foo; <- redundant. node == foo already. 13:28 <dnovillo> 9 node->next = D.1928; <- redundant. node->next == D.1928 already 13:28 <dnovillo> 10 pool = node; <- redundant. node == pool already. 13:28 <dnovillo> 11 return foo->a; 13:33 <jakub> line 9 is not redundant, because node->next occupies the same memory as foo->a and foo->b 13:34 <jakub> I think we have 2 options with this optimization 13:35 <jakub> 1) for each memcpy etc. operand, look through all handled components and if it is an actual VAR_DECL, we can surely optimize it, with the native alias set 13:36 <jakub> but if it is a pointer, we can't be sure 13:37 <jakub> now, either we figure out some way how to express that operation in an alias friendly way if it is a pointer, or we just bail and don't optimize 13:37 <dnovillo> but, my point was that i don't see where the RTL optimizers may be screwing up. what's the exact operation that they remove that they shouldn't have? 13:37 <dnovillo> it all looks removable to me. 13:39 <jakub> RTL optimizers remove the node->next = D.1928 line 13:40 <jakub> which means 1) pool->next is in the end 0 rather than old pool->next 13:40 <jakub> and 2) 0 is returned rather than (int) pool->next 13:40 <dnovillo> but D.1928 and node->next have the same value according to the tree dump. or am i misreading something? 14:03 <jakub> foo == node, so foo->a and node->next occupy the same memory 14:03 <dnovillo> oh, crap. 14:03 <jakub> and eventhough those 2 have aliasing incompatible types, the use of memcpy makes it ok 14:03 <dnovillo> i had missed that. 14:04 <jakub> guess I'll now write just a quick patch to only do it for VAR_DECLs and components thereof 14:05 <jakub> so that the bug is fixed and we can then keep discussing how even pointers can be safely optimized 14:05 <dnovillo> so, going back to not apply this on pointers then? 14:05 <dnovillo> yeah, for now that would be the safe approach. 14:10 <jakub> /* If var is a VAR_DECL or a component thereof, 14:10 <jakub> we can use its alias set, otherwise we'd need to make 14:10 <jakub> sure we go through alias set 0. */ 14:10 <jakub> inner = srcvar; 14:10 <jakub> while (handled_component_p (inner)) 14:10 <jakub> inner = TREE_OPERAND (inner, 0); 14:10 <jakub> if (TREE_CODE (inner) != VAR_DECL) 14:10 <jakub> return 0; 14:11 <jakub> or should I use SSA_VAR_P (inner) instead? 14:12 <jakub> I guess at least PARM_DECL or RESULT_DECL would be ok, not sure about SSA names 14:22 <dnovillo> the reason we don't screw up in the trees is the presence of points-to information, most likely. i got tricked because i wasn't following who was pointing to who. 14:22 <dnovillo> the store foo->a changes node->next. 14:23 <dnovillo> bah. 14:23 <dnovillo> RTL misses that because the stores have different alias sets. 14:23 <dnovillo> the transformation we do on trees is invalid for RTL because we don't keep points-to info in RTL, only type info. 14:23 <dnovillo> the Real Fix would tag the stores so that gimple->RTL changes the alias sets. 14:24 <dnovillo> something along the lines of what you suggest may work. 14:26 <jakub> yeah, now to find a way to force the alias set... -- dnovillo at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|4.2.0 |--- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29272