LLVM-GCC generating too much code from inline assembly

Hi,

I recently switched to LLVM-GCC 4.2 on OS X, to go around a bug caused by gcc with optimized code. Unfortunately, I ran into another weird problem on LLVM-GCC. In my code, there’s a file with a bunch of inline assembly blocks, that worked fine with GCC 4.2. Now, when compiling with LLVM-GCC 4.2, weird things happen.

Here’s an example: (the blocks are larger than that, but a single line will do to show you what’s happening)
__asm {
mov ebx, iObject
}

When compiling in release, everything goes fine, and the produced assembly looks like this :

InlineAsm Start

.file “… my filename”

InlineAsm End

InlineAsm Start

.line 1454

InlineAsm End

InlineAsm Start

movl -20(%ebp), $ebx

InlineAsm End

The problem occurs in debug, and the code looks like this :

InlineAsm Start

.file “… my filename”

InlineAsm End

InlineAsm Start

.line 1454

InlineAsm End

InlineAsm Start

movl -20(%ebp), $ebx

InlineAsm End

movl %ebx, %eax
movl %eax, -52(%ebp)

Only the last two lines are added, but since I’m using the eax register for other things in the block, the code keeps writing over it, and end up crashing when I try to really use whatever I did put in eax.

From the looks of it, those lines must be here for a reason, but I’m wondering how to avoid generating them, as it’s causing some major problems in my code (at least in this specific file). Is there some way to disable that ?

Thanks,
Fred

You may find it helpful to reference http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html. In particular, the information regarding clobbers and constraints.

Generally speaking, it's best not to use inline assembly at all. What are you trying to do that you find it necessary?

Yeah, I used that document as a reference to rewrite all the assembly blocks that were failing, but since the code is pretty central to my software, I'd like to be able to revert to the old code (that GCC 4.2 was producing right) if I need to check for differences between the two, or just if other problems arise...

In my case, I absolutely need inline asm, since I'm writing functions that do what objc_msgSend does for Obj-C, but for C++. Methods are binded at the start and then I can have C++ setters/getters, and so on... It's a pretty hard thing to do without asm :wink: But right now I managed to get it done with small asm blocks, using constraints and clobbers on each of them.

And now that it's all working again, I'm finding performance took a big hit since I went to using LLVM-GCC in debug. Are there any other surprises like the one I found on asm blocks that are disseminated all around, making my app be 3x times slower in debug ?

Fred

Hi Fred,

And now that it's all working again, I'm finding performance took a
big hit since I went to using LLVM-GCC in debug. Are there any other
surprises like the one I found on asm blocks that are disseminated
all around, making my app be 3x times slower in debug ?

I'm not sure what you mean by "using LLVM-GCC in debug". If you mean that
you are compiling without optimization, then it is normal that your program
runs slowly.

Ciao,

Duncan.

Yeah, sorry, it's the habit of working with Visual Studio people in a cross-platform environment :wink:
I mean with no optimizations, but when I was saying I took a 3x performance hit, I mean between GCC 4.2 - no optims, and LLVM-GCC 4.2 - no optims. I expect it to be slower between LLVM GCC with or without optims, but not that much in that specific case...

Fred

This is something I fixed recently; I think it produces functionally correct code at -O0 now in TOT. You will still see interpolated copies, and stack loads and stores, but it should no longer clobber registers that are explicitly used for something else. You need to use -O to get good performance though.