3

I want to compile a C++ program to an intermediate code. Then, I want to compile the intermediate code for the current processor with all of its resources.

The first step is to compile the C++ program with optimizations (-O2), run the linker and do most of the compilation procedure. This step must be independent of operating system and architecture.

The second step is to compile the result of the first step, without the original source code, for the operating system and processor of the current computer, with optimizations and special instructions of the processor (-march=native). The second step should be fast and with minimal software requirements.

Can I do it? How to do it?

Edit:
I want to do it, because I want to distribute a platform independent program that can use all resources of the processor, without the original source code, instead of distributing a compilation for each platform and operating system. It would be good if the second step be fast and easy.

Processors of the same architecture may have different features. X86 processors may have SSE1, SSE2 or others, and they can be 32 or 64 bit. If I compile for a generic X86, it will lack of SSE optimizations. After many years, processors will have new features, and the program will need to be compiled for new processors.

Squall
  • 4,344
  • 7
  • 37
  • 46
  • 8
    Sounds like a job for clang/LLVM ? – Paul R May 09 '11 at 21:10
  • We need a little more input to give useful advice. Which processors and operating systems are we talking about? Why exactly do you want to delay the last compilation step? – Mackie Messer May 10 '11 at 09:31
  • If you want to ship platform independent program, have a look at the java virtual machine. If you want to support different versions of x86, compile binaries for each version. (Alternatively you could just provide different versions of the most time critical functions.) And shipping code today for tomorrows x86 extensions is impossible. You will have to update your code for that. If you care about your future program performance, forget about sse and make sure your code can make use of as many processor cores as possible. – Mackie Messer May 10 '11 at 16:49

3 Answers3

7

Just a suggestion - google clang and LLVM.

Violet Giraffe
  • 32,368
  • 48
  • 194
  • 335
  • 2
    Actually, they do quite a bit of optimization. – Jerry Coffin May 09 '11 at 22:27
  • @Jerry Most of that optimization is done by the JIT at run time. – Etienne de Martel May 10 '11 at 12:36
  • The immediate representation “LLVM” _can_ be JIT-compiled, but you don't have to. You can also use a normal backend and get native code. That said, both JIT-compiler and native backends will do some own optimization, but most of the expensive optimizations are done on the IR, independent of the backend (so they only have to be written _once_). LLVM is really a re-usable framework of frontends, backends and optimizations, all centered around a common IR. You can combine them in quite a lot of ways. – ollb May 10 '11 at 23:18
  • That said, LLVM should in theory be able to do something like this. It is even listed on the features page as “install-time/run-time/offline”-optimization (which are all a variation of optimization on the target system). However I'm not sure how much additional work is required to get something like that working. I know, that you can run frontend, backend and optimizations separately from the command line though (if LLVM is installed). – ollb May 10 '11 at 23:34
3

How much do you know about compilers? You seem to treat "-O2" as some magical flag.

For instance, register assignment is a typical optimization. You definitely need to now how many registers are available. No point in assigning foo to register 16, and then discover in phase 2 that you're targetting an x86.

And those architecture-dependent optimizations can be quite complex. Inlining depends critically on call cost, and that in turn depends on architecture.

MSalters
  • 173,980
  • 10
  • 155
  • 350
0

Once you get to "processor-specific" optimizations, things get really tricky. It's really tough for a platform-specific compiler to be truly "generic" in its generation of object or "intermediate" code at an appropriate "level": Unless it's something like "IL" (intermediate language) code (like the C#-IL code, or Java bytecode), it's really tough for a given compiler to know "where to stop" (since optimizations occur all over the place at different levels of the compilation when target platform knowledge exists).

Another thought: What about compiling to "preprocessed" source code, typically with a "*.i" extension, and then compile in a distributed manner on different architectures?

For example, most (all) the C and C++ compilers support something like:

cc /P MyFile.cpp
gcc -E MyFile.cpp

...each generates MyFile.i, which is the preprocessed file. Now that the file has included ALL the headers and other #defines, you can compile that *.i file to the target object file (or executable) after distributing it to other systems. (You might need to get clever if your preprocessor macros are specific to the target platform, but it should be quite straight-forward with your build system, which should generate the command line to do this pre-processing.)

This is the approach used by distcc to preprocess the file locally, so remote "build farms" need not have any headers or other packages installed. (You are guaranteed to get the same build product, no matter how the machines in the build farm are configured.)

Thus, it would similarly have the effect of centralizing the "configuration/pre-processing" for a single machine, but provide cross-compiling, platform-specific compiling, or build-farm support in a distributed manner.

FYI -- I really like the distcc concept, but the last update for that particular project was in 2008. So, I'd be interested in other similar tools/products if you find them. (In the mean time, I'm writing a similar tool.)

charley
  • 5,913
  • 1
  • 33
  • 58