Java Reference
In-Depth Information
FourN
4
× N
for i =
1 to N do
for j =
1 to N do
a
&( A [ i , j ])
b
&( B [ i ,
1])
c
&( C [1
, j ])
while b <
+ FourN do
a a + b × c
b b +
&( B [ i ,
1])
4
c c + FourN
Figure 14.5: Optimized matrix multiply.
ment, it is easy to generate redundant computations. For example, Markers 9
and 10 compute the address of A [ i , j ]. Only one such computation is necessary.
Conceivably, the code generator could be written to account for these
conditions as it generates code. Superficially, this may seem desirable, but
modern compiler design practices dictate otherwise:
Such concerns can greatly complicate the task of writing the code gen-
erator. Issues such as instruction selection and register allocation are
the primary concerns of the code generator. Generally, it is wiser to
craft a compiler by combining simple, single-purpose transformations
that are easily understood, programmed, and maintained. Each such
transformation is often called a pass of the compiler.
There are typically many portions of a compiler that can generate su-
perfluous code.
cient to write one compiler pass that is
dedicated to the removal of unnecessary computations than to duplicate
that functionality throughout the compiler.
It is more e
For example, dead code elimination and unreachable code elimination re-
move unnecessary computations. Most compilers include these passes, if only
to clean up after themselves.
Continuing with our example, consider code generation for Figure 14.3.
Let us assume that each array element occupies 4 bytes and that subscripts are
specified in the range of 1.. N . The code for indexing the array element A [ i , j ]
becomes
Addr ( A )
+
((( i
1)
× N +
( j
1)))
×
4
which takes
4
integer “
+
”and“
2
integer “
×
6
integer operations
 
Search WWH ::




Custom Search