4 ms·
Look at it in smaller transformations. Compiler optimizations are kinda like algebra - many small structured steps result in hard, large changes. for(a = Acq
by tetha 9y ago
Look at it in smaller transformations. Compiler optimizations are kinda like algebra - many small structured steps result in hard, large changes.
for(a = AcquireLock(), c = 0; c < 100; c++) {
synchronized(this) {
f();
}
}
ReleaseLock(a);
Per definition of the for-loop, that's the same as:
a = AcquireLock();
c = 0;
while (c < 100) {
synchronized(this) { f(); }
c++;
}
ReleaseLock(a);
From there, you can deduce: 'c < 100' and 'c++' don't depend on a and have no side effects besides c. Furthermore, there is no guarantee about two consecutive synchronized blocks actually releasing the lock. Thus, you can safely lift the synchronized block from the loop. However, as AcquireLock and ReleaseLock are function calls with unknown behavior, you can't coarsen the lock further in your example.
Interestingly enough, if you'd talk about 'f(c = 0, g(); c < 100; c++)', the optimizations above might be impossible because you don't know if the call to g modifies c. Unless you can inline g, so you can re-arrange instructions again.