On 04/24/2015 10:18 AM, Jiong Wang wrote:
2015-04-21 Jiong Wang <jiong.w...@arm.com>
gcc/
* loop-invariant.c (find_defs): Enable DF_DU_CHAIN build.
(vfp_const_iv): New hash table.
(expensive_addr_check_p): New boolean.
(init_inv_motion_data): Initialize new variables.>
(free_inv_motion_data): Release hash table.
(create_new_invariant): Set cheap_address to false for iv in
vfp_const_iv table.
(find_invariant_insn): Skip dependencies check for iv in vfp_const_iv
table.
(use_for_single_du): New function.
(reshuffle_insn_with_vfp): Likewise.
(find_invariants_bb): Call reshuffle_insn_with_vfp.
gcc/testsuite/
* gcc.dg/pr62173.c: New testcase.
So ultimately isn't this just a specialized version of reassociation of
pointer arithmetic? And if so, don't we have all the usual problems
around introducing overflow?
ISTM if this is going to go forward (ie, we somehow convince ourselves
that this kind of reassociation is OK), then should it be made to apply
on pointers in general rather than restricting to stack, frame,
virtual-frame?
Jeff,
Thanks for the review.
This transformation is not reassociation of pointer arithmetic.
^^^
The idea of this patch is, given two instructions with variable value,
we may get new instruction sequences with fixed value by reassociating
their operands. And currently GCC only generate such instruction
sequences for local array accessing as far as I known.
Which is precisely reassociation of pointer arithmetic.
Given:
x = a + b
y = *(x + c)
You're generating:
x = a + c
y = *(x + b)
That's reassociation of pointer arithmetic.
For all kinds of reassociation we have to concern ourselves with adding
overflow where it didn't already occur. Assuming a 32 bit architecture
we could get overflow if A is 0x7fffffff, b is -4 and and c = 3
0x7fffffff + -4 = 0x7ffffffb
0x7ffffffb + 3 = 0x7ffffffe
If you make the transformation you're suggesting we get
0x7fffffff + 3 = 0x80000002 OVERFLOW
0x80000002 - 4 = 0x7ffffffe
Now if you always know pointers are unsigned, then the overflow is
defined and you'd be OK. But that's a property of the target and one
that's not well modeled within GCC (we have POINTER_EXTEND_UNSIGNED
which kind of tells us something in this space).
In addition to worrying about overflow, you have to worry about
segmented architectures with implicit segment selection -- especially if
the segment selection comes from the base register than the entire
effective address.
On such architectures a + b != b + a when used in a memory reference.
The HPPA and mn103 ports immediately come to mind. I'm sure there's at
least one more since I recall helping someone with these issues in the
past. Anyway
So given
x = a + b;
y = *(x + c)
Can only be transformed into
x = a + c
y = *(x + b)
If and only if a + b would choose the same segment as a + c. On the PA
that wouldn't be true for something like
a = 0x4000000
b = 0x10
c = -4
a + b is 0x40000010
a + c is 0x3ffffffc
Those select different segments. Even though the full address is the
same (0x4000000c).
Sadly we don't expose this aspect of target characteristics at all.
To proceed, you'd probably need ways to conditionalize these
transformations. ie, target hooks.
Jeff