Java Reference
In-Depth Information
As a result, code schedulers often seek to move loads as early as possible
in an instruction sequence. There are several complicating factors, however.
To what predecessor block should we move an instruction? Ideally, to a pre-
decessor that is control equivalent ; that is, a predecessor that will be executed
if, and only if, the current block is executed. An example of this is moving an
instruction that follows an if statement to a position that precedes the if (and
thereby past both arms of the if ). An alternative is to move an instruction to
ablockthat dominates it (that is, to a block that is a necessary predecessor).
Now, however, the moved instruction may become a speculative instruc-
tion —it may be executed unnecessarily on some execution paths. Thus, if an
instruction is moved from a then part to a position above the if, the instruction
will be executed even when the else part is selected. Speculative instructions
may waste computational resources by executing useless instructions. What
is worse, if a speculative instruction faults (for example, a load through a null
or illegal pointer), a false runtime error may be reported.
Even if we can move an instruction freely upward, how far should we
move it? If we move the instruction too far forward it will “tie up” a register
for an extended period, making register allocation harder and less e
ective.
Some architectures, like the DEC alpha, provide a prefetch instruction .This
instruction allows data to be loaded into the primary cache in advance, reduc-
ing the chance that a register load will miss. Again, placement of preloads is
a tricky scheduling issue. We want to preload early enough to hide the delays
incurred in loading the cache. But, if we preload too early, we may displace
other useful cache data, causing cache misses when these data are used.
ff
,PowerPC)include
asophisticated dynamic scheduling facility. These designs, sometimes called
out of order architectures or OOO , delay instructions that are not ready to exe-
cute, and dynamically choose successor instructions that are ready to execute.
These designs are far less sensitive to compiler-generated code schedules. In
fact, dynamically scheduled architectures are particularly e
Manymodern computer architectures (Intel Pentium R
ective in execut-
ing old programs (“dusty decks”) that were created before code scheduling
was even invented.
ff
Even with dynamically scheduled architectures, compiler-generated code
scheduling is still an important issue. Loads, especially loads that frequently
miss in the primary cache, must bemoved early enough to hide the long delays
a cache miss implies. Even the best current architectures cannot look dozens or
hundreds of instructions ahead for a load that might miss in the cache. Rather,
compilers must identify those instructions that might incur the greatest delays
and move them earlier in the instruction sequence.
 
Search WWH ::




Custom Search