C ++: возможная ошибка в оптимизации gcc - PullRequest
0 голосов
/ 21 января 2019

У меня есть gcc версия 8.2.1.

В следующем коде я ожидаю, что компилятор не будет генерировать код между двумя mfence инструкциями в методе CheckAndPrint().

Действительно, это хорошо, если я вызываю метод PrintGood<false>(), а код не генерируется. Но если я прокомментирую PrintBad<false>() или даже просто return, компилятор генерирует код для if -выражения if (t.j > 0).

Во всех трех случаях не должно быть причин для создания какого-либо кода, особенно для дорогостоящего ветвления.

Код ниже скомпилирован как:

g++ -std=c++11 -Ofast optimization_problem.cc -o optimization_problem

Пытался напрямую связаться с gcc bugzilla, но у него были проблемы с созданием там учетной записи.

Есть ли веская причина, по которой компилятору удалось оптимизировать код в одном случае, а не в двух других?

#include <iostream>
#include <string>

struct Data {
  int i;
  int j;
};

template <typename Dummy>
class Test {
 public:
  template <typename T>
  void CheckAndPrint(const T &t);

 protected:
  template <bool print, typename T>
  inline void PrintGood(const std::string &prefix, const T &t);

  template <bool print, typename T>
  inline void PrintBad(const std::string &prefix, const std::string  &postfix, const T &t);
};

template <typename Dummy>
template <typename T>
inline void Test<Dummy>::CheckAndPrint(const T &t) {
  asm volatile ("mfence" ::: "memory");
  if (t.j > 0) {
    //return;
    //PrintBad<false>("<", ">", t);
    PrintGood<false>("<", t);
  }
  asm volatile ("mfence" ::: "memory");
}

template <typename Dummy>
template <bool print, typename T>
inline void Test<Dummy>::PrintGood(const std::string &prefix, const T &t) {
  if (print)
    std::cout << prefix << t.i << t.j << std::endl;
}

template <typename Dummy>
template <bool print, typename T>
inline void Test<Dummy>::PrintBad(const std::string &prefix, const std::string &postfix, const T &t) {
  if (print)
    std::cout << prefix << t.i << t.j << postfix << std::endl;
}

int main() {
  Data data;
  std::cin >> data.i;
  std::cin >> data.j;

  Test<int> t;
  t.CheckAndPrint(data);

  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...