www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19078] New: dmd does not remove inlined functions

https://issues.dlang.org/show_bug.cgi?id=19078

          Issue ID: 19078
           Summary: dmd does not remove inlined functions
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: johnnymarler gmail.com

I've attempted to create a minimal example to demonstrate that dmd fails to
remove inlined functions from the final executable.  In order to keep the final
executable small enough analyze with a disassembler, I've omitted
druntime/phobos.  Because of this, the example is very platform specific.  It
was made to work on the linux x86_64 platform.

--- build.sh
dmd -c -conf= -O -release -inline -betterC main.d object.d
ld -o main main.o object.o

--- object.d
module object;

alias size_t = ulong;
alias ptrdiff_t = long;

alias string = immutable(char)[];

--- main.d
pragma(inline)
int removeme(int x)
{
    return x;
}

extern(C) int main(int argc, char*[] argv, char*[] envp)
{
    sys_write(1, "running...\n".ptr, 11);
    return removeme(0);
}

extern (C) ptrdiff_t sys_exit(int exitCode)
{
    asm
    {
        naked;
        mov EAX, 60;
    }
}
extern (C) ptrdiff_t sys_write(int fd, const(char)* buf, size_t n)
{
    asm
    {
        naked;
        mov EAX, 1;
        syscall;
        ret;
    }
}
extern (C) void _start()
{
    asm
    {
        naked;
        xor RBP,RBP;
        pop RDI;
        mov RSI,RSP;
        mov RDX,RDI;
        add RDX,1;
        shl RDX, 3;
        add RDX,RSP;
        add RSP,-8;
        and RSP, 0xFFFFFFFFFFFFFFF8;
        call main;
        mov RDI, RAX;  // syscall param 1 = RAX (return value of main)
        mov RAX, 60;   // SYS_exit
        syscall;
    }
}


After running `./build.sh`, it should create the `main` executable.  You can
run it with `./main` and verify it prints "running'.  However, if you
disassemble it then you'll find that it does not remove the "removeme" function
that should have been inlined.

 objdump -d main
main: file format elf64-x86-64 Disassembly of section .text: 00000000004000b0 <_D4main8removemeFiZi>: 4000b0: 50 push %rax 4000b1: 48 89 f8 mov %rdi,%rax 4000b4: 59 pop %rcx 4000b5: c3 retq ... 00000000004000b8 <main>: 4000b8: 55 push %rbp 4000b9: 48 8b ec mov %rsp,%rbp 4000bc: ba 0b 00 00 00 mov $0xb,%edx 4000c1: be 10 01 40 00 mov $0x400110,%esi 4000c6: bf 01 00 00 00 mov $0x1,%edi 4000cb: e8 0c 00 00 00 callq 4000dc <sys_write> 4000d0: 31 c0 xor %eax,%eax 4000d2: 5d pop %rbp 4000d3: c3 retq 00000000004000d4 <sys_exit>: 4000d4: b8 3c 00 00 00 mov $0x3c,%eax 4000d9: 00 00 add %al,(%rax) ... 00000000004000dc <sys_write>: 4000dc: b8 01 00 00 00 mov $0x1,%eax 4000e1: 0f 05 syscall 4000e3: c3 retq 00000000004000e4 <_start>: 4000e4: 31 ed xor %ebp,%ebp 4000e6: 5f pop %rdi 4000e7: 48 89 e6 mov %rsp,%rsi 4000ea: 48 89 fa mov %rdi,%rdx 4000ed: 48 83 c2 01 add $0x1,%rdx 4000f1: 48 c1 e2 03 shl $0x3,%rdx 4000f5: 48 01 e2 add %rsp,%rdx 4000f8: 48 83 c4 f8 add $0xfffffffffffffff8,%rsp 4000fc: 48 83 e4 f8 and $0xfffffffffffffff8,%rsp 400100: e8 b3 ff ff ff callq 4000b8 <main> 400105: 48 89 c7 mov %rax,%rdi 400108: b8 3c 00 00 00 mov $0x3c,%eax 40010d: 0f 05 syscall --
Jul 11 2018