That's because of the awful iostream crap.
This version inlines both calls:
$ cat /tmp/c.cpp
#include <stdio.h>
inline void hello()
{
printf("Hello World\n");
}
int main()
{
hello();
hello();
}
0000000000400500 <main>:
400500: 48 83 ec 08 sub $0x8,%rsp
400504: bf a0 06 40 00 mov $0x4006a0,%edi
400509: e8 d2 ff ff ff callq 4004e0 <puts@plt>
40050e: bf a0 06 40 00 mov $0x4006a0,%edi
400513: e8 c8 ff ff ff callq 4004e0 <puts@plt>
400518: 31 c0 xor %eax,%eax
40051a: 48 83 c4 08 add $0x8,%rsp
40051e: c3 retq
40051f: 90 nop
As opposed to the iostream version, which it doesn't make sense to inline.
0000000000400990 <hello()>:
400990: 53 push %rbx
400991: ba 0b 00 00 00 mov $0xb,%edx
400996: be 90 0a 40 00 mov $0x400a90,%esi
40099b: bf 80 10 60 00 mov $0x601080,%edi
4009a0: e8 7b fe ff ff callq 400820 <std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)@plt>
4009a5: 48 8b 05 d4 06 20 00 mov 0x2006d4(%rip),%rax # 601080 <std::cout@@GLIBCXX_3.4>
4009ac: 48 8b 40 e8 mov -0x18(%rax),%rax
4009b0: 48 8b 98 70 11 60 00 mov 0x601170(%rax),%rbx
4009b7: 48 85 db test %rbx,%rbx
4009ba: 74 3c je 4009f8 <hello()+0x68>
4009bc: 80 7b 38 00 cmpb $0x0,0x38(%rbx)
4009c0: 74 1e je 4009e0 <hello()+0x50>
4009c2: 0f b6 43 43 movzbl 0x43(%rbx),%eax
4009c6: bf 80 10 60 00 mov $0x601080,%edi
4009cb: 0f be f0 movsbl %al,%esi
4009ce: e8 6d fe ff ff callq 400840 <std::ostream::put(char)@plt>
4009d3: 5b pop %rbx
4009d4: 48 89 c7 mov %rax,%rdi
4009d7: e9 54 fe ff ff jmpq 400830 <std::ostream::flush()@plt>
4009dc: 0f 1f 40 00 nopl 0x0(%rax)
4009e0: 48 89 df mov %rbx,%rdi
4009e3: e8 e8 fd ff ff callq 4007d0 <std::ctype<char>::_M_widen_init() const@plt>
4009e8: 48 8b 03 mov (%rbx),%rax
4009eb: be 0a 00 00 00 mov $0xa,%esi
4009f0: 48 89 df mov %rbx,%rdi
4009f3: ff 50 30 callq *0x30(%rax)
4009f6: eb ce jmp 4009c6 <hello()+0x36>
4009f8: e8 b3 fd ff ff callq 4007b0 <std::__throw_bad_cast()@plt>
4009fd: 0f 1f 00 nopl (%rax)