-3

I have a piece of code with this structure:

__forceinline void problemFunction(bool condition, int & value)
{
    if (condition)
    {
        value = 0;
        return;
    }

    // ...
    // a lot of calculations
    // ...
}

void caller()
{
    bool condition;
    int value;

    // ...

    problemFunction(condition, value);
    someOtherStuff();
}

But after building Release configuration with optimization turned on in Disassembly I get something like this:

void caller()
{
    bool condition;
    int value;

    // ...

    if (condition)
        value = 0;
    else
        goto CalculateLabel;

ReturnProblemFunctionLabel:

    someOtherStuff();
    goto ReturnLabel;

CalculateLabel:
    // ...
    // a lot of calculations
    // ...
    goto ReturnProblemFunctionLabel;

ReturnLabel:

}

ProblemFunction was splitted into two parts. And the proble is that the second part is located after the someOtherStuff function call.

How can I locally suppress this kind of optimization?

I am using Visual Studio 2019 Version 16.4.2 on Windows 10.

  • 3
    Is there any reason why you want to do this? It's not wrong or anything. The behaviour is exactly the same. – Lukas-T Dec 24 '19 at 11:36
  • 1
    In C++20 you can mark the if statement with the likely/unlikely attribute ([see here](https://stackoverflow.com/questions/51797959/how-to-use-c20s-likely-unlikely-attribute-in-if-else-statement)). I don't know if Visual Studio 2019 has support for it right now. – IlCapitano Dec 24 '19 at 11:41
  • Please explain why this is a problem. – molbdnilo Dec 24 '19 at 12:17
  • You explicitly marked your function `__forceinline`, so the compiler did inline it. Once inlined, it isn't a separate function anymore. The compiler simply reordered operations within a single function. What problem are you trying to solve? – IInspectable Dec 24 '19 at 12:55
  • The compiler is allowed to rearrange code, provided that the resulting code does the same thing as the non-rearranged code. That looks like it's the case here. Can you write a valid C++ program that can tell the difference? If not, the change is okay. – Pete Becker Dec 24 '19 at 13:48

1 Answers1

0

In C++20 you can mark branches with the likely/unlikely attribute (see this question and cppreference), which can give the compiler a hint on how to better optimize the code. In your original post I'm assuming that the condition passed to problemFunction is usually false, which would mean an unnecessary jump in most cases.

As you can see on godbolt, if you mark your if statement with [[unlikely]] g++ will output your desired result, but msvc will not change the generated code. Note that this example is just a basic demo. Compiling your actual program may give different results.

Also note that jumps do not necessarily mean worse performance, because of branch prediction. You have to measure your execution time to make any meaningful conclusions.

IlCapitano
  • 1,994
  • 1
  • 7
  • 15