CSE, loops, and array accesses
Edward Nevill
edward.nevill at gmail.com
Thu Oct 1 13:00:59 UTC 2015
On Thu, 2015-10-01 at 11:27 +0100, Andrew Haley wrote:
> I'm looking at a failure to CSE the array base offset in this loop:
>
> for (int i = 0; i < array.length; i++) {
> res += array[i];
> }
>
> ;; B2: # B2 B3 <- B1 B2 Loop: B2-B2 inner Freq: 100.958
>
> 0x000003ff9d1a1a30: add xscratch1, x10, #0x10
> 0x000003ff9d1a1a34: ldr w13, [xscratch1,w11,sxtw #2]
> 0x000003ff9d1a1a38: add w11, w11, #0x1 ;*iinc
> ; - tests.ScalarReduce::test1 at 20 (line 22)
>
> 0x000003ff9d1a1a3c: add w0, w0, w13 ;*iadd
> ; - tests.ScalarReduce::test1 at 18 (line 23)
>
> 0x000003ff9d1a1a40: cmp w11, #0x64
> 0x000003ff9d1a1a44: b.lt 0x000003ff9d1a1a30 ;*if_icmpge
> ; - tests.ScalarReduce::test1 at 9 (line 22)
The reason it does not do the loop invariant lifting is because of the following transformation in AddPNode::Ideal in addnode.cpp
// Else move the constant to the right. ((A+con)+B) into ((A+B)+con)
address = phase->transform(new (phase->C) AddPNode(in(Base),addp->in(Address),in(Offset)));
offset = addp->in(Offset);
So, once it has transformed ((A+con)+B) into ((A+B)+con) all bets are off, we can never CSE/Loop invariant lift.
Try the following patch, it should generate the code you want.
All the best,
Ed.
--- CUT HERE ---
diff -r fa430fa4f577 src/share/vm/opto/addnode.cpp
--- a/src/share/vm/opto/addnode.cpp Wed Sep 23 12:39:30 2015 -0400
+++ b/src/share/vm/opto/addnode.cpp Thu Oct 01 12:59:19 2015 +0000
@@ -592,20 +592,16 @@
// The Add of the flattened expression
address = addp->in(Address);
offset = phase->MakeConX(t2->get_con() + t12->get_con());
- } else {
- // Else move the constant to the right. ((A+con)+B) into ((A+B)+con)
- address = phase->transform(new AddPNode(in(Base),addp->in(Address),in(Offset)));
- offset = addp->in(Offset);
+ PhaseIterGVN *igvn = phase->is_IterGVN();
+ if( igvn ) {
+ set_req_X(Address,address,igvn);
+ set_req_X(Offset,offset,igvn);
+ } else {
+ set_req(Address,address);
+ set_req(Offset,offset);
+ }
+ return this;
}
- PhaseIterGVN *igvn = phase->is_IterGVN();
- if( igvn ) {
- set_req_X(Address,address,igvn);
- set_req_X(Offset,offset,igvn);
- } else {
- set_req(Address,address);
- set_req(Offset,offset);
- }
- return this;
}
}
--- CUT HERE ---
More information about the hotspot-compiler-dev
mailing list