I just ran into an interesting "bug" here.
The "bug" itself is not really a bug but a performance issue. The
details aren't important but in the course of investigation I came
across a general scheduling problem I don't know how to solve.
Let's say we have a routine for getting the clock tick of the CPU,
called "mysecond." This is a user-written function that may or may
not
call some inline asm. It is not an intrinsic, just an ordinary
function.
The situation I ran into is this:
extern volatile double mysecond(void);
int main() {
start = mysecond()
for(...) {
...
}
end = mysecond()
...
}
The optimizer turns this into:
start = mysecond()
for(...) {
...
}
... // cleanup
end = mysecond()
When LLVM isel/scheduling gets hold of it it becomes:
start = mysecond()
for(...) {
...
}
end = mysecond()
... // cleanup
This is not good because now we're not counting the cleanup time as part
of the loop.
AFAIK LLVM has no way to mark a function call as volatile, as in,
"don't
move this." I can sort of hack things around in the scheduler, adding
some fake edges but this isn't a good general solution because not all
calls have this code motion restriction.
Any ideas? Do we need an IR change to allow calls to be marked
volatile?
-Dave