0

How would one compute efficiently the minimal list of macro definitions combinations that will give the same code ? The list of macros is known before-hand.

The objective would be to compile less versions of the program (possibly a shader) and thus skip some compilation time by knowing what macro combinations are equivalent. eg. if a program built with MACRO_A and MACRO_B is the same as a program built only with MACRO_A.

For the sake of simplicity, those macro are either defined or not, and their value doesn't matter (meaning there is no #if SOMEMACRO).

For example with:

#ifdef A
  #ifdef B
    // some code
  #endif
  // some code
#elif defined(C)
 // some code
#else
  // some code
#endif

A trivial way to generate all the programs would be to compile with all the combinations made from A,B and C. It would mean creating 2^3=8 combinations. However, only the following combinations really are useful (! means the macro is not defined, ~that the macro doesn't matter and can be either defined or undefined ):

  • ( A, B, ~C) (same as A, B, C and A, B, !C)
  • ( A, !B, ~C)
  • (!A, ~B, C)
  • (!A, ~B, !C)

Which means compiling only programs with the following definitions is enough:

  • A B
  • A
  • C
  • No defines

With this list, I know that when asked for a program with the (A, !B, C) combination I can simply use the one built with only A defined.

What tools could be used ?

Notes:

  • Most preprocessors will only give the path for a given set of defines
  • Perhaps building the control flow graph of the preprocessor would help?
  • Some work has been done with clang here by J. Trull to add conditional nodes to the AST, but seems to be aimed at refactoring, not sure if it is the best way to do it
Lectem
  • 503
  • 6
  • 19
  • This is loosely related to (but not a duplicate of) [Is there a C pre-processor which eliminates `#ifdef` blocks based on values defined or undefined?](https://stackoverflow.com/questions/525283/) and the Coan (Coan2) tool mentioned there may be helpful. However, I'm not sure that it can address your full requirement. It may help, though. – Jonathan Leffler Apr 10 '17 at 16:28
  • Part of the process seems a logical optimisation, to find an efficient way of configuring each possible resulting code, but only once. I.e. find the combinations which are NOT needed anymore after having used a logically identical one already. For this part I want to mention the method based on Karnaugh Veitch diagrams: https://en.wikipedia.org/wiki/Karnaugh_map Determining which combination has which resulting code and identifying the combinations which result in identical code is the first step. – Yunnosch Apr 10 '17 at 16:40
  • @Jarod42 thanks I edited the post – Lectem Apr 10 '17 at 17:02
  • @JonathanLeffler Sadly those tools only eliminate dead code, which is useful when you want to fully remove use of a deprecated macro, but this is not the case here. Doing so seems (to me) way easier because it is closer to a normal preprocessor job – Lectem Apr 10 '17 at 17:03
  • @Yunnosch Indeed the logical optimisation is the second step, Karnaugh's maps could be a solution. I'm more interested in the 'identifying the combinations' which is the hardest part IMO though. – Lectem Apr 10 '17 at 17:03

0 Answers0