noinline changes between 3.8 and 4.0?


I’m in the process of upgrading an LLVM client from using 3.8 to using 4.0 and am running into the following issue:

// compile with:
// clang++ -std=c++11 -Wno-c++14-extensions -S -emit-llvm
// ~/chrono.cpp -o chrono.ll
using namespace std;
using namespace std::chrono;

using tick = ratio<1, 300>;
using tick_duration = duration<long, tick>;

class ticking_clock {
using duration = tick_duration;
using rep = duration::rep;
using period = duration::period;
using time_point = time_point<ticking_clock, duration>;
static constexpr bool is_steady = true;

static time_point now() noexcept;

void f(long &elapsed_time) {
auto start = ticking_clock::now();
auto finish = ticking_clock::now();
auto dur = finish - start;
elapsed_time = dur.count();

The functions defined in the resultant IR are marked noinline in 4.0 but do not have that same attribute in 3.8. Running the unoptimized IR through opt -O2 <chrono.ll -S >chrono.opt.ll produces the expected 6 line function in 3.8 but does no inlining in 4.0 (respecting the attribute).

This appears to be a large change from where clang++ -O2 was roughly equal to clang++ -O0 | opt -O2 in 3.8 but is not in 4.0.

Is there a way to obtain that previous functionality in 4.0?



Try “-O2 -Xclang -disable-llvm-passes”.

Huh, that appears to do it - preventing noinline from showing up on defined functions. Thanks.

Out of curiosity, what does that do? And what changed to require this?

-O2 has multiple effects. The obvious effect is the set of optimization passes which run, but it also changes the behavior of the frontend. It affects the preprocessor (we set a define with the optimization level), and we change how IR is generated in a few cases. -disable-llvm-passes disables the optimization passes, but doesn’t affect the other behavior of -O2.