Last active
August 29, 2015 14:03
-
-
Save wjlafrance/c1f89e74ba436e26aa65 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func max1(numbers: [Int]) -> Int { | |
var maximumSoFar: Int = 0 | |
for i in numbers { | |
maximumSoFar = max(maximumSoFar, i) | |
} | |
return maximumSoFar | |
} | |
Compiled with -Ofast -emit-assembly: | |
Notice how it doesn't call max()! It optimized it to cmpq/cmovgeq! | |
__TF11maximumFast4max1FGSaSi_Si: | |
pushq %rbp | |
movq %rsp, %rbp | |
pushq %r15 | |
pushq %r14 | |
pushq %rbx | |
pushq %rax | |
movq %rdi, %r15 | |
callq _swift_retain | |
movq %rax, %r14 | |
xorl %ebx, %ebx | |
testq %r15, %r15 | |
je LBB1_3 | |
leaq 32(%r15), %rax | |
movq $-1, %rcx ; loop starts at -1, because i is incremented at the beginning. weird. | |
xorl %ebx, %ebx | |
jmp LBB1_2 | |
.align 4, 0x90 | |
LBB1_4: ; loop start | |
movq (%rax), %rdx ; rdx = *rax | |
addq $8, %rax ; move rax pointer forward by sizeof(Int64) | |
cmpq %rbx, %rdx ; if (rdx >= rbx) | |
cmovgeq %rdx, %rbx ; rbx = rdx | |
LBB1_2: | |
incq %rcx ; ++i | |
cmpq 16(%r15), %rcx ; condition = (i == lastIndex) | |
jne LBB1_4 ; if (!condition) goto LBB1_4 | |
LBB1_3: | |
movq %r14, %rdi | |
callq _swift_release | |
movq %r14, %rdi | |
callq _swift_release | |
movq %rbx, %rax | |
addq $8, %rsp | |
popq %rbx | |
popq %r14 | |
popq %r15 | |
popq %rbp | |
retq |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Actually, the notes on 34 and 35 are not entirely accurate but I'm not sure how to better express what's going on in pseudo-C.
On line 34
rbx
andrdx
are compared. Currentlyrbx
is holding the value ofmaximumSoFar
andrdx
is holding the nexti
from the array.On line 35, the magical
cmovge
instruction is used, or "conditionally move if greater than or equal". The result of thecmp
instruction is checked, and if it's greater than or equal, it performs the move.This is an example of how the compiler writes better assembler than I do, based on it knowing instructions I don't. If I were to go on the fool's errand of writing this myself, the assembler would look like this:
So, trust your compiler. It's smarter than you.