Search This Blog

Saturday, November 22, 2008

Porting to “Intel C Compiler”

In this post, I will explain how to easy it is to compile/port C programs and makefiles designed for GCC(GNU compiler collection) can be used with ICC(intel c compiler)

The necessity for using ICC happened to me because gcc was generating much bigger object files. Ace is using ACPI-CA(http://acpica.org/) as it is ACPI driver. After compilation the ACPI library is around 7M in debug version and around 500K in non-debug version. But from http://acpica.org/download/changes.txt it seems Microsoft C compiler produce smaller code.
    Non-Debug Version:  81.2K Code, 17.0K Data,  98.2K Total
    Debug Version:     155.8K Code, 49.1K Data, 204.9K Total

So I decided to try “Intel Compiler” as replacement for GCC. Things were easy, since icc has options which is similar to gcc.

You can get the details of portability options from icc documentation -http://www.intel.com/software/products/compilers/docs/clin/main_cls/index.htm.

I just changed my make.conf file to check the compiler in use and use appropriate options. I removed -fno-leading-underscore and –Wall. I removed –Wall because it was giving lot of warnings, we have to fix our code sometime soon. I removed -fno-leading-underscore because there is no equivalent option in icc, however icc does not adds underscores to symbols anyway. 

I added –O1 option because the kernel was panicked during boot with invalid opcode exception, I believe it was because of some MMX register usage by icc. So I settled with –O1 now.

ifeq ($(CC),gcc)
    DEBUG_FLAGS= -gdwarf-2 -g3
    CFLAGS+= -Wall -Wno-multichar $(DEFINES) -nostartfiles -ffreestanding -funsigned-char -fno-leading-underscore -c -fno-stack-protector $(DEBUG_FLAGS) $(CUSTOM_FLAG)
else
    DEBUG_FLAGS= -gdwarf-2 -g
    CFLAGS+= -O1 -Wno-multichar $(DEFINES) -nostartfiles -ffreestanding -funsigned-char -c -fno-stack-protector $(DEBUG_FLAGS) $(CUSTOM_FLAG)
endif

I also made some static variables in kernel/i386/gdb_stub.c to non-static because icc appends .0 to static variables but it forgets the same name when referenced in a inline assembly code in the same file. After removing the static attribute it is working fine.

gcc compiler took the following time to compile Ace source code.
real    0m51.125s
user    0m36.975s
sys     0m11.185s

icc compiler took the following time to compile Ace source code.
real    1m44.366s
user    0m59.107s
sys     0m20.946s

Gcc produced double the size of kernel.sys produced by icc. (I used GNU linker(ld) and ar).

gcc output size:
[samuel@linux Ace3]$ ls -lh /home/samuel/Projects/Ace3/obj/
-rw-rw-r-- 1 samuel samuel 372K 2008-11-22 18:17 acpi.a
-rw-rw-r-- 1 samuel samuel 545K 2008-11-22 18:17 arch.a
-rwxrwxr-x 1 samuel samuel 1.3M 2008-11-22 18:17 kernel.sys
-rw-rw-r-- 1 samuel samuel  62K 2008-11-22 18:17 libds.a
-rw-rw-r-- 1 samuel samuel  40K 2008-11-22 18:17 libheap.a
-rw-rw-r-- 1 samuel samuel  39K 2008-11-22 18:17 libstring.a
-rw-rw-r-- 1 samuel samuel 9.5K 2008-11-22 18:17 libsync.a
-rw-rw-r-- 1 samuel samuel  91K 2008-11-22 18:17 pic.a
-rw-rw-r-- 1 samuel samuel  23K 2008-11-22 18:17 pit.a
-rw-rw-r-- 1 samuel samuel  21K 2008-11-22 18:17 rtc.a

icc output:
[samuel@linux Ace3]$ ls -lh /home/samuel/Projects/Ace3/obj/
-rw-rw-r-- 1 samuel samuel 352K 2008-11-22 16:25 acpi.a
-rw-rw-r-- 1 samuel samuel 230K 2008-11-22 16:24 arch.a
-rwxrwxr-x 1 samuel samuel 528K 2008-11-22 16:25 kernel.sys
-rw-rw-r-- 1 samuel samuel  38K 2008-11-22 16:23 libds.a
-rw-rw-r-- 1 samuel samuel  22K 2008-11-22 16:23 libheap.a
-rw-rw-r-- 1 samuel samuel  21K 2008-11-22 16:23 libstring.a
-rw-rw-r-- 1 samuel samuel  11K 2008-11-22 16:23 libsync.a
-rw-rw-r-- 1 samuel samuel  19K 2008-11-22 16:24 pic.a
-rw-rw-r-- 1 samuel samuel 8.4K 2008-11-22 16:24 pit.a
-rw-rw-r-- 1 samuel samuel  13K 2008-11-22 16:24 rtc.a

So it is easy to use icc instead of gcc. However since I am using Windows and icc is free only for Linux for non commerical purposes. I stick to gcc to compile Ace in Windows. 

0 comments: