.NH 2 Implementation .PP UD first builds a number of tables: .IP locals: 9 contains information about the local variables of the current procedure (offset,size,whether a register message was found for it and, if so, the score field of that message) .IP defs: a table of all explicit definitions appearing in the current procedure. .IP copies: a table of all copies appearing in the current procedure. .LP Every variable (local as well as global), definition and copy is identified by a unique number, which is the index in the table. All tables are constructed by traversing the EM code. A fourth table, "vardefs" is used, indexed by a 'variable number', which contains for every variable the set of explicit definitions of it. Also, for each basic block b, the set CHGVARS containing all variables changed by it is computed. .PP The GEN sets are obtained in one scan over the EM text, by analyzing every EM instruction. The KILL set of a basic block b is computed by looking at the set of variables changed by b (i.e. CHGVARS[b]). For every such variable v, all explicit definitions to v (i.e. vardefs[v]) that are not in GEN[b] are added to KILL[b]. Also, the implicit defininition of v is added to KILL[b]. Next, the data flow equations for use-definition information are solved, using a straight forward, iterative algorithm. All sets are represented as bitvectors, so the operations on sets (union, difference) can be implemented efficiently. .PP The C_GEN and C_KILL sets are computed simultaneously in one scan over the EM text. For every copy A := B appearing in basic block b we do the following: .IP 1. for every basic block n /= b that changes B, see if the definition A := B reaches the beginning of n (i.e. check if the index number of A := B in the "defs" table is an element of IN[n]); if so, add the copy to C_KILL[n] .IP 2. if B is redefined later on in b, add the copy to C_KILL[b], else add it to C_GEN[b] .LP C_IN and C_OUT are computed from C_GEN and C_KILL via the second set of data flow equations. .PP Finally, in one last scan all opportunities for optimization are detected. For every use u of a variable A, we check if there is a unique explicit definition d reaching u. .sp If the definition is a copy A := B and B has the same value at d as at u, then the use of A at u may be changed into B. The latter condition can be verified as follows: .IP - if u and d are in the same basic block, see if there is any assignment to B in between d and u .IP - if u and d are in different basic blocks, the condition is satisfied if there is no assignment to B in the block of u prior to u and d is in C_IN[b]. .LP Before the transformation is actually done, UD first makes sure the alteration is really desirable, as described before. The information needed for this purpose (access costs of local and global variables) is read from a machine descriptor file. .sp If the only definition reaching u has the form "A := constant", the use of A at u is replaced by the constant.