1

Is it possible to make contents of constant array be visible across multiple other source files so that compiler can optimize access to the array.
I have an array const int myTable[10]; and in multiple source files I want contents of this table to be visible to other source files so that access can be optimized. For example the following code:

if (myTable[1] == 1)
{
    foo();
}
else if (myTable[2] == 5)
{
    bar();
}
else
{
    baz();
}

could have branch entirely optimized-out if source file is aware of contents of myTable.

I am aware of couple solutions but none are satisfactory:

  1. use LTO (on GCC) - on embedded device without support for LTO
  2. define myTable in header file and then include it in source files - I want only single definition of this table because it is large

EDIT:
Additional constraints to make the question clearer:

  1. Array must be a global variable - must be visible to MULTIPLE files
  2. Index to table is not an integer but an enumeral and is not always a compile-time constant
4
  • Is the table only 10 entries? How are the values for the table determined? Could you use a set of defined values: #define myTable_1 10, #define myTable_2 5 etc. And then your code would test these constants. Commented Nov 13 at 10:10
  • @JonathanLeffler Table is up to 200 entries large. Table is 'manually' populated by programmer. Index to table is in not an integer but an enumeral and it may not be a compile-time constant. Commented Nov 13 at 10:18
  • 1
    XY problem. What do you want to optimize? Commented Nov 13 at 10:26
  • You need tell us why the table cannot be static in a translation unit that also provides all the functions that access it to make the problem not appear arbitrarily self-imposed. Commented Nov 13 at 16:19

4 Answers 4

2

Declaring variables with external linkage usually prevents optimizations rather than the other way around. So the correct way to optimize out branches is probably rather to make the array local and static.

Trying out this code on gcc x86 -O3:

#include <stddef.h>

void foo (void);
void bar (void);
void baz (void);

void do_stuff_with_my_table (void)
{
    static const int my_table[10] = { [1] = 1, [2] = 5 };

    if (my_table[1] == 1)
    {
        foo();
    }
    else if (my_table[2] == 5)
    {
        bar();
    }
    else
    {
        baz();
    }
}

Results in 100% branch free code (and the whole table getting optimized out even):

do_stuff_with_my_table:
        jmp     foo

Whereas making my_table file scope extern results in 2 branches:

do_stuff_with_my_table:
        cmp     DWORD PTR my_table[rip+4], 1
        je      .L5
        cmp     DWORD PTR my_table[rip+8], 5
        je      .L6
        jmp     baz
.L6:
        jmp     bar
.L5:
        jmp     foo
1

Table is 'manually' populated by programmer.

Then you do not need the table.

create a header file with definitions

#define TABLE(x) VAL ## x

#define VAL1 2
#define VAL2 5

Then you can include it and your compiler will know what to optimize out

https://godbolt.org/z/vod5EWzGT

You can automatically generate this header file if you already have this array with values - just write a short C program.

Index to table is in not an integer but an enumeral and it may not be a compile-time constant.

If it is not a constant expression then you are out of luck. No optimizations are possible. Even C23 constexpr will not help

https://godbolt.org/z/fWTax3PTW

0

With the given restrictions, one option is to gather the functions where such optimizations are applicable in the same compilation unit as the table and use those functions in other compilation units instead of referring directly to the table.

E.g.:

const int myTable[10] = ...;

void doFooBar(void)
{
    if (myTable[1] == 1)
    {
        foo();
    }
    else if (myTable[2] == 5)
    {
        bar();
    }
    else
    {
        baz();
    }
}
-1

you can use the single definition as you have. If you like to access on other file to it, just add a

extern int table[100];  // sample 
2
  • 1
    The question is "Is it possible to make contents of constant array be visible across multiple other source files so that compiler can optimize access to the array?" extern table[100]; does not make the contents of the array visible to the compiler. That's why the poster doesn't want to use it. Commented Nov 13 at 11:10
  • Also this isn't valid C since 25 years back.
    – Lundin
    Commented Nov 14 at 7:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.