ну и в итоге: простейший, совершенно дубовый dead store eliminator — который убирает только простейшее, даже толком data flow analysis не делает, — смог превратить вот это:
Код:
=== Aggregated assembly output: BEGIN
===
0xb721d913 [prologue]
0xb721d913 55 push ebp
0xb721d914 8b ec mov ebp,esp
0xb721d916 [frag entry]
0xb721d916 [zero stack]
0xb721d916 6a 00 push 0
0xb721d918 6a 00 push 0
parami1 = parami 0 ecx (in reg? -1)
------------------------------ # line 8: Core:Hashes:U32:Hash [MY_THISCALL_NO_SAVE]
------------------------------ # line 10: local variable: a
allocp1 = allocp 4 (in reg? -1)
------------------------------ # line 10: cache param `a` to make addressable
sti.s allocp1[0] = parami1 (in reg? -1)
0xb721d91a 89 4d fc mov [ebp-4],ecx
ldi1 = ldi.s allocp1[0] (in reg? -1)
0xb721d91d 8b 5d fc mov ebx,[ebp-4]
immi1 = immi 0x7ed55d16 (in reg? -1)
addi1 = addi ldi1, immi1/*0x7ed55d16*/ (in reg? -1)
0xb721d920 8d 9b 16 5d d5 7e lea ebx,[ebx+2127912214]
ldi2 = ldi.s allocp1[0] (in reg? -1)
0xb721d926 8b 75 fc mov esi,[ebp-4]
immi2 = immi 12 (in reg? -1)
roli1 = roli ldi2, immi2/*12*/ (in reg? -1)
0xb721d929 c1 c6 0c rol esi,12
addi2 = addi addi1, roli1 (in reg? -1)
0xb721d92c 8d 1c 33 lea ebx,[ebx+esi*1]
sti.s allocp1[0] = addi2 (in reg? -1)
0xb721d92f 89 5d fc mov [ebp-4],ebx
ldi3 = ldi.s allocp1[0] (in reg? -1)
0xb721d932 8b 5d fc mov ebx,[ebp-4]
immi3 = immi 0xc761c23c (in reg? -1)
xori1 = xori ldi3, immi3/*0xc761c23c*/ (in reg? -1)
0xb721d935 81 f3 3c c2 61 c7 xor ebx,-949894596
ldi4 = ldi.s allocp1[0] (in reg? -1)
0xb721d93b 8b 75 fc mov esi,[ebp-4]
immi4 = immi 19 (in reg? -1)
roli2 = roli ldi4, immi4/*19*/ (in reg? -1)
0xb721d93e c1 c6 13 rol esi,19
xori2 = xori xori1, roli2 (in reg? -1)
0xb721d941 33 de xor ebx,esi
sti.s allocp1[0] = xori2 (in reg? -1)
0xb721d943 89 5d fc mov [ebp-4],ebx
ldi5 = ldi.s allocp1[0] (in reg? -1)
0xb721d946 8b 5d fc mov ebx,[ebp-4]
immi5 = immi 0x165667b1 (in reg? -1)
addi3 = addi ldi5, immi5/*0x165667b1*/ (in reg? -1)
0xb721d949 8d 9b b1 67 56 16 lea ebx,[ebx+374761393]
ldi6 = ldi.s allocp1[0] (in reg? -1)
0xb721d94f 8b 75 fc mov esi,[ebp-4]
immi6 = immi 5 (in reg? -1)
roli3 = roli ldi6, immi6/*5*/ (in reg? -1)
0xb721d952 c1 c6 05 rol esi,5
addi4 = addi addi3, roli3 (in reg? -1)
0xb721d955 8d 1c 33 lea ebx,[ebx+esi*1]
sti.s allocp1[0] = addi4 (in reg? -1)
0xb721d958 89 5d fc mov [ebp-4],ebx
ldi7 = ldi.s allocp1[0] (in reg? -1)
0xb721d95b 8b 5d fc mov ebx,[ebp-4]
immi7 = immi 0xd3a2646c (in reg? -1)
addi5 = addi ldi7, immi7/*0xd3a2646c*/ (in reg? -1)
0xb721d95e 8d 9b 6c 64 a2 d3 lea ebx,[ebx-744332180]
ldi8 = ldi.s allocp1[0] (in reg? -1)
0xb721d964 8b 75 fc mov esi,[ebp-4]
immi8 = immi 9 (in reg? -1)
roli4 = roli ldi8, immi8/*9*/ (in reg? -1)
0xb721d967 c1 c6 09 rol esi,9
xori3 = xori addi5, roli4 (in reg? -1)
0xb721d96a 33 de xor ebx,esi
sti.s allocp1[0] = xori3 (in reg? -1)
0xb721d96c 89 5d fc mov [ebp-4],ebx
ldi9 = ldi.s allocp1[0] (in reg? -1)
0xb721d96f 8b 5d fc mov ebx,[ebp-4]
immi9 = immi 0xfd7046c5 (in reg? -1)
addi6 = addi ldi9, immi9/*0xfd7046c5*/ (in reg? -1)
0xb721d972 8d 9b c5 46 70 fd lea ebx,[ebx-42973499]
ldi10 = ldi.s allocp1[0] (in reg? -1)
0xb721d978 8b 75 fc mov esi,[ebp-4]
immi10 = immi 3 (in reg? -1)
roli5 = roli ldi10, immi10/*3*/ (in reg? -1)
0xb721d97b c1 c6 03 rol esi,3
addi7 = addi addi6, roli5 (in reg? -1)
0xb721d97e 8d 1c 33 lea ebx,[ebx+esi*1]
sti.s allocp1[0] = addi7 (in reg? -1)
0xb721d981 89 5d fc mov [ebp-4],ebx
ldi11 = ldi.s allocp1[0] (in reg? -1)
0xb721d984 8b 45 fc mov eax,[ebp-4]
immi11 = immi 0xb55a4f09 (in reg? -1)
xori4 = xori ldi11, immi11/*0xb55a4f09*/ (in reg? -1)
0xb721d987 35 09 4f 5a b5 xor eax,-1252372727
ldi12 = ldi.s allocp1[0] (in reg? -1)
0xb721d98c 8b 5d fc mov ebx,[ebp-4]
immi12 = immi 16 (in reg? -1)
roli6 = roli ldi12, immi12/*16*/ (in reg? -1)
0xb721d98f c1 c3 10 rol ebx,16
xori5 = xori xori4, roli6 (in reg? -1)
0xb721d992 33 c3 xor eax,ebx
reti xori5 (in reg? -1)
0xb721d994 8b e5 mov esp,ebp
0xb721d996 5d pop ebp
0xb721d997 c3 ret
unreachable (in reg? -1)
unreachable (in reg? -1)
0xb721d998 90 90 90 90 align
===
=== Aggregated assembly output: END
в это:
Код:
=== Aggregated assembly output: BEGIN
===
0xb72e3abf [prologue]
0xb72e3abf [prologue, no extra stack]
0xb72e3abf 55 push ebp
0xb72e3ac0 8b ec mov ebp,esp
0xb72e3ac2 [frag entry]
parami1 = parami 0 ecx (in reg? -1)
0xb72e3ac2 8b f1 mov esi,ecx
------------------------------ # line 8: Core:Hashes:U32:Hash [MY_THISCALL_NO_SAVE]
------------------------------ # line 10: local variable: a
------------------------------ # removed dead store
------------------------------ # a
------------------------------ # sti/ldi optimisation
immi1 = immi 0x7ed55d16 (in reg? -1)
addi1 = addi parami1, immi1/*0x7ed55d16*/ (in reg? -1)
0xb72e3ac4 8d 9e 16 5d d5 7e lea ebx,[esi+2127912214]
------------------------------ # sti/ldi optimisation
immi2 = immi 12 (in reg? -1)
roli1 = roli parami1, immi2/*12*/ (in reg? -1)
0xb72e3aca c1 c6 0c rol esi,12
addi2 = addi addi1, roli1 (in reg? -1)
0xb72e3acd 8d 1c 33 lea ebx,[ebx+esi*1]
------------------------------ # removed dead store
------------------------------ # a
------------------------------ # sti/ldi optimisation
immi3 = immi 0xc761c23c (in reg? -1)
xori1 = xori addi2, immi3/*0xc761c23c*/ (in reg? -1)
0xb72e3ad0 8b f3 mov esi,ebx
0xb72e3ad2 81 f6 3c c2 61 c7 xor esi,-949894596
------------------------------ # sti/ldi optimisation
immi4 = immi 19 (in reg? -1)
roli2 = roli addi2, immi4/*19*/ (in reg? -1)
0xb72e3ad8 c1 c3 13 rol ebx,19
xori2 = xori xori1, roli2 (in reg? -1)
0xb72e3adb 33 f3 xor esi,ebx
------------------------------ # removed dead store
------------------------------ # a
------------------------------ # sti/ldi optimisation
immi5 = immi 0x165667b1 (in reg? -1)
addi3 = addi xori2, immi5/*0x165667b1*/ (in reg? -1)
0xb72e3add 8d 9e b1 67 56 16 lea ebx,[esi+374761393]
------------------------------ # sti/ldi optimisation
immi6 = immi 5 (in reg? -1)
roli3 = roli xori2, immi6/*5*/ (in reg? -1)
0xb72e3ae3 c1 c6 05 rol esi,5
addi4 = addi addi3, roli3 (in reg? -1)
0xb72e3ae6 8d 1c 33 lea ebx,[ebx+esi*1]
------------------------------ # removed dead store
------------------------------ # a
------------------------------ # sti/ldi optimisation
immi7 = immi 0xd3a2646c (in reg? -1)
addi5 = addi addi4, immi7/*0xd3a2646c*/ (in reg? -1)
0xb72e3ae9 8d b3 6c 64 a2 d3 lea esi,[ebx-744332180]
------------------------------ # sti/ldi optimisation
immi8 = immi 9 (in reg? -1)
roli4 = roli addi4, immi8/*9*/ (in reg? -1)
0xb72e3aef c1 c3 09 rol ebx,9
xori3 = xori addi5, roli4 (in reg? -1)
0xb72e3af2 33 f3 xor esi,ebx
------------------------------ # removed dead store
------------------------------ # a
------------------------------ # sti/ldi optimisation
immi9 = immi 0xfd7046c5 (in reg? -1)
addi6 = addi xori3, immi9/*0xfd7046c5*/ (in reg? -1)
0xb72e3af4 8d 9e c5 46 70 fd lea ebx,[esi-42973499]
------------------------------ # sti/ldi optimisation
immi10 = immi 3 (in reg? -1)
roli5 = roli xori3, immi10/*3*/ (in reg? -1)
0xb72e3afa c1 c6 03 rol esi,3
addi7 = addi addi6, roli5 (in reg? -1)
0xb72e3afd 8d 1c 33 lea ebx,[ebx+esi*1]
------------------------------ # removed dead store
------------------------------ # a
------------------------------ # sti/ldi optimisation
immi11 = immi 0xb55a4f09 (in reg? -1)
xori4 = xori addi7, immi11/*0xb55a4f09*/ (in reg? -1)
0xb72e3b00 8b c3 mov eax,ebx
0xb72e3b02 35 09 4f 5a b5 xor eax,-1252372727
------------------------------ # sti/ldi optimisation
immi12 = immi 16 (in reg? -1)
roli6 = roli addi7, immi12/*16*/ (in reg? -1)
0xb72e3b07 c1 c3 10 rol ebx,16
xori5 = xori xori4, roli6 (in reg? -1)
0xb72e3b0a 33 c3 xor eax,ebx
reti xori5 (in reg? -1)
0xb72e3b0c 8b e5 mov esp,ebp
0xb72e3b0e 5d pop ebp
0xb72e3b0f c3 ret
unreachable (in reg? -1)
unreachable (in reg? -1)
0xb72e3b10 90 90 90 90 align
===
=== Aggregated assembly output: END
а, оригинал, да:
Код:
PROCEDURE Hash* [no_overflow_checks] (a: INTEGER): INTEGER;
BEGIN
a := (a + 07ED55D16H) + ROL(a, 12);
a := (((a AS SET) / (0C761C23CH AS SET)) / (ROR(a, 19) AS SET) AS INTEGER);
a := (a + 0165667B1H) + ROL(a, 5);
a := ((a + 0D3A2646CH AS SET) / (ROL(a, 9) AS SET) AS INTEGER);
a := (a + 0FD7046C5H) + ROL(a, 3);
RETURN (((a AS SET) / (0B55A4F09H AS SET)) / (ROR(a, 16) AS SET) AS INTEGER);
END Hash;
как видим — вообще все временные сохранения в переменную вайпнулись. вместе с самой переменной. только ECX Nanojit отчего-то не захотел использовать напрямую, а перетащил в scratch register.
p.s.: кстати, я по спекам O/Ur после `FOR` переменную цикла зануляю. иба нефиг. а dead store eliminator ходит по пятам и зануления вайпает, лол.
и если чо — мы всё ещё можем делать крипто. потому что `ERASE()` никогда не вайпается, даже если локалы чистим.