Cloning of functions
Description
Same as basic block cloning, but on function level. Increases the amount of the code and thus - the strength of the transformations applied later.
Original Code
#include <stdio.h>
unsigned fib(unsigned N) {
return N > 1 ? fib(N-2) + fib(N-1) : N;
}
int main(int argc, char **argv) {
printf("fib(0) = %u\n", fib(0));
printf("fib(1) = %u\n", fib(1));
printf("fib(2) = %u\n", fib(2));
printf("fib(4) = %u\n", fib(4));
printf("fib(8) = %u\n", fib(8));
printf("fib(16) = %u\n", fib(16));
return 0;
}
Compiled Code
public _Z3fibj
.align 16
_Z3fibj proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB1_3
.LBB1_1: ; %bb2
mov EAX, ESI
.LBB1_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB1_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj
add EAX, EDI
jmp .LBB1_2
_Z3fibj endp
public main
.align 16
main proc near
push ESI
sub ESP, 8
mov DWORD PTR [ESP + 4], 0
mov DWORD PTR [ESP], OFFSET .L_2E_str
call printf
mov DWORD PTR [ESP + 4], 1
mov DWORD PTR [ESP], OFFSET .L_2E_str1
call printf
mov DWORD PTR [ESP], 0
call _Z3fibj
mov ESI, EAX
mov DWORD PTR [ESP], 1
call _Z3fibj
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str2
call printf
mov DWORD PTR [ESP], 2
call _Z3fibj
mov ESI, EAX
mov DWORD PTR [ESP], 3
call _Z3fibj
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str3
call printf
mov DWORD PTR [ESP], 6
call _Z3fibj
mov ESI, EAX
mov DWORD PTR [ESP], 7
call _Z3fibj
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str4
call printf
mov DWORD PTR [ESP], 14
call _Z3fibj
mov ESI, EAX
mov DWORD PTR [ESP], 15
call _Z3fibj
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str5
call printf
xor EAX, EAX
add ESP, 8
pop ESI
ret
main endp
.L_2E_str:; .str
db 'fib(0) = %u',10,0
.L_2E_str1:; .str1
db 'fib(1) = %u',10,0
.L_2E_str2:; .str2
db 'fib(2) = %u',10,0
.L_2E_str3:; .str3
db 'fib(4) = %u',10,0
.L_2E_str4:; .str4
db 'fib(8) = %u',10,0
.L_2E_str5:; .str5
db 'fib(16) = %u',10,0
end
Transformed Code
.file "fclone.bc"
.686
.MMX
.XMM
.model flat
EXTERN printf:near
.text
public _Z3fibj
.align 16
_Z3fibj proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB1_3
.LBB1_1: ; %bb2
mov EAX, ESI
.LBB1_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB1_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj_2E_fclone_2E_4
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj_2E_fclone_2E_3
add EAX, EDI
jmp .LBB1_2
_Z3fibj endp
public main
.align 16
main proc near
push ESI
sub ESP, 8
mov DWORD PTR [ESP + 4], 0
mov DWORD PTR [ESP], OFFSET .L_2E_str
call printf
mov DWORD PTR [ESP + 4], 1
mov DWORD PTR [ESP], OFFSET .L_2E_str1
call printf
mov DWORD PTR [ESP], 0
call _Z3fibj_2E_fclone_2E_5
mov ESI, EAX
mov DWORD PTR [ESP], 1
call _Z3fibj
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str2
call printf
mov DWORD PTR [ESP], 2
call _Z3fibj_2E_fclone_2E_1
mov ESI, EAX
mov DWORD PTR [ESP], 3
call _Z3fibj_2E_fclone_2E_2
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str3
call printf
mov DWORD PTR [ESP], 6
call _Z3fibj_2E_fclone_2E_1
mov ESI, EAX
mov DWORD PTR [ESP], 7
call _Z3fibj_2E_fclone_2E_2
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str4
call printf
mov DWORD PTR [ESP], 14
call _Z3fibj_2E_fclone_2E_3
mov ESI, EAX
mov DWORD PTR [ESP], 15
call _Z3fibj_2E_fclone_2E_4
add EAX, ESI
mov DWORD PTR [ESP + 4], EAX
mov DWORD PTR [ESP], OFFSET .L_2E_str5
call printf
xor EAX, EAX
add ESP, 8
pop ESI
ret
main endp
public _Z3fibj_2E_fclone_2E_1
.align 16
_Z3fibj_2E_fclone_2E_1 proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB3_3
.LBB3_1: ; %bb2
mov EAX, ESI
.LBB3_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB3_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj
add EAX, EDI
jmp .LBB3_2
_Z3fibj_2E_fclone_2E_1 endp
public _Z3fibj_2E_fclone_2E_2
.align 16
_Z3fibj_2E_fclone_2E_2 proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB4_3
.LBB4_1: ; %bb2
mov EAX, ESI
.LBB4_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB4_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj
add EAX, EDI
jmp .LBB4_2
_Z3fibj_2E_fclone_2E_2 endp
public _Z3fibj_2E_fclone_2E_3
.align 16
_Z3fibj_2E_fclone_2E_3 proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB5_3
.LBB5_1: ; %bb2
mov EAX, ESI
.LBB5_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB5_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj
add EAX, EDI
jmp .LBB5_2
_Z3fibj_2E_fclone_2E_3 endp
public _Z3fibj_2E_fclone_2E_4
.align 16
_Z3fibj_2E_fclone_2E_4 proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB6_3
.LBB6_1: ; %bb2
mov EAX, ESI
.LBB6_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB6_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj
add EAX, EDI
jmp .LBB6_2
_Z3fibj_2E_fclone_2E_4 endp
public _Z3fibj_2E_fclone_2E_5
.align 16
_Z3fibj_2E_fclone_2E_5 proc near
push EDI
push ESI
sub ESP, 4
mov ESI, DWORD PTR [ESP + 16]
cmp ESI, 2
jae .LBB7_3
.LBB7_1: ; %bb2
mov EAX, ESI
.LBB7_2: ; %bb2
add ESP, 4
pop ESI
pop EDI
ret
.LBB7_3: ; %bb
lea EAX, DWORD PTR [ESI - 2]
mov DWORD PTR [ESP], EAX
call _Z3fibj
mov EDI, EAX
dec ESI
mov DWORD PTR [ESP], ESI
call _Z3fibj
add EAX, EDI
jmp .LBB7_2
_Z3fibj_2E_fclone_2E_5 endp
.L_2E_str:; .str
db 'fib(0) = %u',10,0
.L_2E_str1:; .str1
db 'fib(1) = %u',10,0
.L_2E_str2:; .str2
db 'fib(2) = %u',10,0
.L_2E_str3:; .str3
db 'fib(4) = %u',10,0
.L_2E_str4:; .str4
db 'fib(8) = %u',10,0
.L_2E_str5:; .str5
db 'fib(16) = %u',10,0
.weak mseed_2E_1253621324
.section .note.GNU-stack,""
end