disable return-value-optimization for one function

ぃ、小莉子 提交于 2019-12-13 15:33:19

问题


struct X {
  void * a;
  void * b;
};

X foo( void * u, void * v);
  • foo() is implemented in assembler (i386)
  • address of return value of type X is passed as hidden parameter to foo()

  • if test code is compiled with -O0 the code works as expected

  • if compiled with -O3 segmentation fault happens (return value was optimized out)
  • if compiled with -O3 -fno-elide-constructors the code works as expected again

how can the compiler be forced no to add RVO for foo() only (aka not forcing -fno-elide-constructors)?

Update1: the code must work for arbitrary compilers (at least gcc ,clang, msvc), example code:

void * vp = bar();
X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0);

Update2: the problem is, that the compiler optimizes out the instances of x

X x = foo( vp, 0);
x = foo( x.a, 0);
x = foo( x.a, 0)

or

X x1 = foo( vp, 0);
X x2 = foo( x1.a, 0);
X x3 = foo( x2.a, 0)

doesn't matter. for instance the segfault happens because

X x2 = foo( x1.a, 0);

x1 was optimized out and the implementation tries to access the first argument , which is a null pointer.


回答1:


You can set the optimization level for a single function in GCC, too:

X foo(void *u, void *v) __attribute__((optimize("no-elide-constructors");

The optimize attribute is used to specify that a function is to be compiled with different optimization options than specified on the command line. Arguments can either be numbers or strings. Numbers are assumed to be an optimization level. Strings that begin with O are assumed to be an optimization option, while other options are assumed to be used with a -f prefix. You can also use the ‘#pragma GCC optimize’ pragma to set the optimization options that affect more than one function. See Function Specific Option Pragmas, for details about the ‘#pragma GCC optimize’ pragma.

This can be used for instance to have frequently-executed functions compiled with more aggressive optimization options that produce faster and larger code, while other functions can be compiled with less aggressive options.

https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html

You can also try the #pragma variant:

#pragma GCC push_options
#pragma GCC optimize ("no-elide-constructors")

X foo(void *u, void *v);

#pragma GCC pop_options


来源:https://stackoverflow.com/questions/33475315/disable-return-value-optimization-for-one-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!