Bug 1149 – Optimizer: obsolete array length loads, common subexpr. elimin. not working
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2007-04-15T12:05:36Z
Last change time
2019-08-26T09:21:08Z
Keywords
performance, pull
Assigned to
yebblies
Creator
Jascha Wetzel
Comments
Comment #0 by jascha — 2007-04-15T12:05:36Z
consider the following code:
void main()
{
uint[] arr;
arr.length = 4;
arr[0] = 1;
arr[1] = 1;
arr[2] = 1;
arr[3] = 1;
}
for the 4 assignments, "dmd -O -inline" generates
mov ECX,1
mov EDX,010h[ESP]
mov EAX,0Ch[ESP]
mov [EDX],ECX
mov EDX,010h[ESP]
mov EAX,0Ch[ESP]
mov 4[EDX],ECX
mov EDX,010h[ESP]
mov EAX,0Ch[ESP]
mov 8[EDX],ECX
mov EDX,010h[ESP]
mov EAX,0Ch[ESP]
mov 0Ch[EDX],ECX
instead of
mov ECX,1
mov EDX,010h[ESP]
mov [EDX],ECX
mov 4[EDX],ECX
mov 8[EDX],ECX
mov 0Ch[EDX],ECX
- the length of the array is always loaded, even if it's not used
- the array pointer is loaded multiple times into the same register
the common subexpression elimination appears to be working for the value in ECX, but not for the pointer in EDX.
(In reply to comment #3)
> With the test code, this is the X86 asm I was seeing before this patch (-O
> -release -inline):
>
[snip]
>
> So is this patch working?
Oops. I tried to disable it for floating point and ended up disabling it for all non-integers.
Comment #5 by bearophile_hugs — 2012-02-22T20:00:29Z
(In reply to comment #4)
> Oops. I tried to disable it for floating point and ended up disabling it for
> all non-integers.
I have tried it with this code:
void main() {
int[] arr;
arr.length = 4;
arr[0] = 1;
arr[1] = 1;
arr[2] = 1;
arr[3] = 1;
}
And I am seeing something similar to the uint[] case.
Comment #6 by yebblies — 2012-02-22T20:20:57Z
(In reply to comment #5)
> (In reply to comment #4)
>
> > Oops. I tried to disable it for floating point and ended up disabling it for
> > all non-integers.
>
> I have tried it with this code:
>
> void main() {
> int[] arr;
> arr.length = 4;
> arr[0] = 1;
> arr[1] = 1;
> arr[2] = 1;
> arr[3] = 1;
> }
>
>
> And I am seeing something similar to the uint[] case.
Yeah, the optimization in my patch is effectively disabled.
I changed it to integer-only because it was crashing in some floating point code - but the most significant word of an array isn't an integer, it's a pointer.
I've tracked to codegen down, it seems like 'fnstsw ax' destroys eax and it never gets restored. Without the optimization loading the pointer into eax never gets picked up as a cse and removed in the first place.
Comment #7 by github-bugzilla — 2012-02-23T00:05:21Z