Volatile Functions

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