whole program optimization with .S files

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am testing the avr-gcc -combine -fwhole-program flags, and copied bits from the example makefile.wpo in winavr. But the example doesn't take .S asm files in account.

This is what the example makefile has:

%.elf: $(SRC)
	@echo
	@echo $(MSG_COMPILING_AND_LINKING) $@
	$(CC) -combine -fwhole-program $(ALL_CFLAGS) $(LDFLAGS) $^ --output $@

If I just add the asm files $(ASRC) as another dependency, the compiler errors out with "cc1: error: too many filenames given". Perhaps I could first build the .S files into a static library and then add another -l to LDFLAGS to get them into the program.

Any simpler ways to achieve this with whole program optimization on the .c files?

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, building the asm files into a static library hasn't worked either. A few of those asm functions jmp to C functions, and the linker complains that those C symbols are undefined references.

I thought maybe the whole program optimizer was just throwing out those functions since they are unused, but I added extra calls to them in "main.c", but that didn't help. Is the whole program optimizer re-factoring the code so much that the original symbols no longer exist after compilation?

If that is true, I'm thinking this isn't going to work with asm files that have dependencies on the C source. Anyone else make this work?

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

According to documentation -combine only works with C.
When given C and assembly, an early pass
will produce one file for all the C files
and individual files for the assembly files.
With -fwhole-program, the next pass is handed
multiple files and told it's only being given one.
It complains.
I expect libraries aren't allowed either.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

I expect libraries aren't allowed either.

In my case, I think you are correct. But if the libraries had no dependency on the C source, I don't see why it wouldn't work.

The avr-libc libraries work, afterall, and it seems to me that the linker shouldn't care how the object code was generated. The only difficulty seems to be that the whole program optimizer does something to the symbols in the C source, so that you can't have outside object code depend on it directly. At least that's my guess.

But I don't see why a normal static library full of independent object code wouldn't work.

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

schickb wrote:
skeeve wrote:

I expect libraries aren't allowed either.

In my case, I think you are correct. But if the libraries had no dependency on the C source, I don't see why it wouldn't work.

The compiler doesn't know that.
It's possible that there might be an
exception for functions declared const,
but the documentation doesn't say so.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
The compiler doesn't know that.
It's possible that there might be an
exception for functions declared const,
but the documentation doesn't say so.

I'm not getting a compiler error when I tried using a library to hold the asm, I am getting a linker error. Compiling with whole program optimization works fine.

What I am suggest would work (and clearly works for other static libraries like avr-libc itself) is this:

* Build asm files into a library
* Compile all of the C file with whole program optimization (which results in a giant object file I believe)
* Link the giant optimized object file with the library (and with other libraries like avr-libc).

What doesn't seem to work is the linking step, when the libraries contain references to symbols originating in C code (which is what I have).

As you mentioned, the compiling step doesn't work when you try to mix different source types (which was my OP).

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

schickb wrote:
What doesn't seem to work is the linking step, when the libraries contain references to symbols originating in C code (which is what I have).
With -whole-program, otherwise external
symbols are no longer made external.
That is in the documentation.
You might be able to get around this by making
your .S files into .c files with inline assembly.

edit:
On second thought, compile some of the .c files
separately and include the results in the library.
Compile the others with -whole-program and -fcombine.
The others should not contain any symbols referenced externally.
The link should work this time.

The important thing is not to invisibly
break promises made to the compiler.
Invoking an external function is visible.
An external function that refers to a
local symbol is invisible to the compiler.
I'm not sure about inline assembly.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
On second thought, compile some of the .c files
separately and include the results in the library.
Compile the others with -whole-program and -fcombine.
The others should not contain any symbols referenced externally.
The link should work this time

That's a good idea, unfortunately for me the references are from a bootloader jump table to functions that account for over 80% of the entire application size. So there is likely little to gain by compiling what remains with whole program optimization.

I may try your idea of inline asm in a naked C function. Or I may just give up on it for now :)

-Brad