LADSoft / OrangeC

OrangeC Compiler And Tool Chain
http://ladsoft.tripod.com/orange_c_compiler.html
Other
291 stars 39 forks source link

Research whether anything can be done about EXE size. #391

Open LADSoft opened 5 years ago

LADSoft commented 5 years ago

the OCC compiled binaries are significantly larger than binaries compiled by other compilers. This may be because the linker doesn't do a good job of filtering unused virtual sections. Research it to find out.

GitMensch commented 5 years ago

Do you compare sources that linked with a static C/C++ lib in both cases (or an import library in both cases)? Can you drop some "current numbers"? And yes: having the linker filter out anything that is unused is definitely a good thing.

chuggafan commented 5 years ago

Yhea, one of the things the linker seems to be doing is pulling in gaurenteed unrelated things, such as on the latest master the lines:


#include <stdlib.h>
extern "C" {
[[gnu::dllexport]] int memcmp(const void *vl, const void *vr, size_t n)
{
    const unsigned char *l=(unsigned char*)vl, *r=(unsigned char*)vr;
    for (; n && *l == *r; n--, l++, r++);
    return n ? *l-*r : 0;
}
}

compiled as a dll will produce a dll with the imports:

    KERNEL32.DLL
                418240 Import Address Table
                418544 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                    0 CloseHandle
                    0 DeleteCriticalSection
                    0 EnterCriticalSection
                    0 ExitProcess
                    0 FlushFileBuffers
                    0 FreeLibrary
                    0 GetCommandLineA
                    0 GetConsoleMode
                    0 GetEnvironmentStringsA
                    0 GetFileType
                    0 GetLastError
                    0 GetModuleFileNameA
                    0 GetModuleHandleA
                    0 GetProcAddress
                    0 GetStdHandle
                    0 GetTickCount
                    0 InitializeCriticalSection
                    0 LeaveCriticalSection
                    0 LoadLibraryA
                    0 LocalAlloc
                    0 LocalFree
                    0 LocalLock
                    0 LocalUnlock
                    0 RaiseException
                    0 RtlUnwind
                    0 SetConsoleMode
                    0 SetFileAttributesA
                    0 SetFilePointer
                    0 Sleep
                    0 TlsAlloc
                    0 TlsFree
                    0 TlsGetValue
                    0 TlsSetValue
                    0 VirtualAlloc
                    0 VirtualFree
                    0 WriteFile

    USER32.DLL
                4182D4 Import Address Table
                4185D8 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                    0 MessageBoxA

And when I compile it to assembly (occ /S /Wd) it tries importing _time _srand and _rand . This shows that we have a lot we could do to optimize binaries (other than bettering the optimizer for size). Mostly stripping a ton of irrelevant stuff (why is MessageBoxA imported?) So that's hard proof that we have a lot of irrelevant things being pulled in (and because of the linker getting statically linked into the dll for some reason)

LADSoft commented 5 years ago

the files compiled by OCIDE are roughly twice the size of the ones compiled by MSVC. When written in the C++ language. On windows, both using static libraries.

For example, the compiler comes out to about 2.5MB when compiled by MSVC, and 4.5MB when compiled by OCC.

LADSoft commented 4 years ago

ok i did some research and it seems like there is stuff in the libcxx library that shouldn't be visible to the linker; this probably will mean implementing a couple more attributes in the compiler and adjusting the libcxx 8 __config file to use them. Because it involves library rework and we are about to switch out libraries in the next milestone, I'll move this there to get it down along with the scheduled library rework.

GitMensch commented 4 years ago

Just a note as people regularly stumble over a change in the linker on GNU/Linux: There should be an option like --no-as-needed that forces libraries specified on the command line to be fully included. This does allow a later dynamic lookup and use of functions in the resulting binary, even when they where not statically called (and therefore not "seen" by the linker) in the original source.

LADSoft commented 4 years ago

@gitmensch ok i can do that :)

LADSoft commented 4 years ago

I think fixing the visibility problem may speed up the compiler as well (when compiled with itself). That because I believe it is calling things like the constructor/destructor for compile-time structures like integral_constant at runtime...such constructors/destructors are empty so they are just time and space wasters... well we'll see where this goes :)

LADSoft commented 1 year ago

the recent changes to optimize the compiler output made about a 10% difference to this as well.