Search code examples
coptimizationpragma

C optimization with pragmas, does it recurse? Or does it simply use look at the order of the pragmas in the file?


Lets say we have project wide optimisation disabled (eg -O0) for my project and I did the following. Edit: I am using tricore-gcc (should be the same as normal GCC). There is no documentation I can find specific to tricore-gcc regarding pragmas.

static void Method1(U8 *data) __attribute__((-fno-inline));
static void Method2(U8 *data) __attribute__((-fno-inline));
//Example 1 (expect method1/method2 to both be optimised at -0s level
#pragma GCC optimize ("-Os")
static void Method1(U8 *data);
{
    ...do stuff
    Method2(data);
}
#pragma GCC optimize ("-O0")

#pragma GCC optimize ("-Os")
static void Method2(U8 *data)
{
    ...do stuff
}
#pragma GCC optimize ("-O0")
//Example 2 Expect method 1 to not be optimised 
//expect method2 to be optimised at -0s level
#pragma GCC optimize ("-O0")
static void Method1(U8 *data)
{
    ...do stuff
    Method2(data);
}
#pragma GCC optimize ("-O0")

#pragma GCC optimize ("-Os")
static void Method2(U8 *data);
{
    ...do stuff
}
#pragma GCC optimize ("-O0")

//Example 3 - Expect method method 1 to not be optimised? 
expect method 2 to be optimised

//No pragma, assume defaults to -O0 as that is the project default
static void Method1(U8 *data)
{
    Method2(data);
}

#pragma GCC optimize ("-Os")
static void Method2(U8 *data);
{
    ...do stuff
}
#pragma GCC optimize ("-O0")

//Example 4 - expect method 1 to be optimised, however will method 2 be optimised?
//as it was called from method1?
#pragma GCC optimize ("-Os")
static void Method1(U8 *data)
{
    ...do stuff
    Method2(data);
}
#pragma GCC optimize ("-O0")

//No pragma, assume defaults to -O0 as that is the project default
//OR does it simply default to the last pragma it saw, eg the -O0 above?
static void Method2(U8 *data);
{
    ...do stuff
}
//Example 6 - expect method 1 to be optimised, however will method 2 be optimised?
//as it was called from method1?
#pragma GCC optimize ("-Os")
static void Method1(U8 *data)
{
    ...do stuff
    Method2(data);
}

//Ommitted #pragma GCC optimize ("-O0"), I assuming that method2
//will be optimised?
static void Method2(U8 *data);
{
    ...do stuff
}

Example 3 and 4 are the two examples I am not sure what will happen or what to expect as there is no pragma, does the pragma recurse into the called function? Or does the compiler simply look for whether it lies within inside a pragma to determine if it should be optimised?

Example 5 I believe I understand what will happen

Final question. Do I need to put pragmas on the function definitions at the top of the file? Or are they simply ignored and the function itself is all that matters?

Eg these lines here, would putting pragmas here confuse things, do nothing or they should go here and not on the function at all? Or do both for brevity?

static void Method1(U8 *data) __attribute__((-fno-inline));
static void Method2(U8 *data) __attribute__((-fno-inline));

edit: Update - The localised optimisation works exactly as nielsen described. Might seem like a strange thing to do but for my use case it is exactly what I want.


Solution

  • The pragma effect is implementation-defined, so it cannot be assumed to be the same across different compilers. The question is focused on GCC and the GCC Documentation says the following:

    #pragma GCC optimize (string, …)

    This pragma allows you to set global optimization options for functions defined later in the source file. [...] Each function that is defined after this point is treated as if it had been declared with one optimize(string) attribute for each string argument. [...]

    Thus, this pragma has effect from the point where it appears in the file until the end of the file.

    In order to optimize a single function without affecting subsequent function definitions, either the attribute notation can be used:

    __attribute__((optimize(3)))
    void func()
    {
       ...
    }
    
    

    or the pragma can be scoped by saving and restoring settings:

    #pragma GCC push_options
    #pragma GCC optimize ("-O3")
    void func()
    {
       ...
    }
    #pragma GCC pop_options
    

    The optimization options in effect for a function definition only affects the function itself, it will not propagate to called functions. They will be optimized with the options in effect at the point where they are defined.