Как компилятор встроил функцию с ответвлениями и множественными операторами возврата? - PullRequest
0 голосов
/ 04 мая 2019

Если встроенная функция заканчивается единственным возвратом в конце, тривиально просто заменить код вызывающей стороны на тело функции, концептуально.

inline int foo(int i) {
    return i - 1;
}

// prior to inline
int result = foo(k);
// => after inline
int result = k - 1;

Что если есть ответвления и множественные возвраты? Как компилятор генерирует правильный код? Простая замена явно не достаточно.

inline int foo(int i) {
    if (i > 0)
        return i - 1;

    return i + 1;
}

// prior to inline
int result = foo(k);
// => after inline
int result;
if (k > 0)
    result = k - 1;

result = k + 1;

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Компилятору разрешено выполнять все виды преобразований кода во время компиляции.Например, компилятор может преобразовать функцию foo в

int foo(int i)
{
  int rv;
  if (i > 0)
  {
    rv = i - 1;
    goto end;
  }

  rv = i + 1;
end:
  return rv;
}

. Затем этот код можно вставить в вызывающую программу.Во время вставки компилятор вводит переменные для обработки параметров и возвращаемого значения встроенной функции.Результат выглядит примерно так, как показано ниже:

int foo_rv;
int foo_param_i = k;
{
  int i = foo_param_i;
  if (i > 0)
  {
    rv = i - 1;
    goto end:
  }

  rv = i + 1;
end:
  foo_rv = rv
}


int result = foo_rv;

Этот код затем может быть дополнительно оптимизирован компилятором, в результате чего код ниже

{
  if (k > 0)
  {
    result = k - 1;
    goto end:
  }

  result = k + 1;
end:
}
1 голос
/ 04 мая 2019

вы можете увидеть вывод встроенного временного компилятора.Поэкспериментируйте и вы увидите, как это делается https://godbolt.org/z/0MkWLs

...