nitc :: APropdef :: compute_phi
# Compute the first phase of SSA algorithm: placing phi-functions
fun compute_phi(ssa: SSA)
do
var root_block = basic_block.as(not null)
# Compute the iterated dominance frontier of the graph of basic blocks
root_block.compute_df
# Places where a phi-function is added per variable
var phi_blocks = new HashMap[Variable, Array[BasicBlock]]
# For each variables in the propdef
for v in variables do
var phi_variables = new Array[BasicBlock]
var read_blocks = new Array[BasicBlock]
read_blocks.add_all(v.read_blocks)
read_blocks.add_all(v.assignment_blocks)
# While we have not treated each part accessing `v`
while not read_blocks.is_empty do
# Remove a block from the array
var block = read_blocks.shift
# For each block in the dominance frontier of `block`
for df in block.dominance_frontier do
# If we have not yet put a phi-function at the beginning of this block
if not phi_variables.has(df) then
phi_variables.add(df)
# Create a new phi-function and set its dependences
var phi = new PhiFunction("phi", df)
phi.add_dependences(df, v)
phi.block = df
phi.original_variable = phi
phi.declared_type = v.declared_type
# Indicate this phi-function is assigned in this block
phi.assignment_blocks.add(block)
ssa.phi_functions.add(phi)
# Add a phi-function at the beginning of df for variable v
df.phi_functions.add(phi)
if not v.read_blocks.has(df) or not v.assignment_blocks.has(df) then read_blocks.add(df)
end
end
end
# Add `phi-variables` to the global map
phi_blocks[v] = phi_variables
end
end
src/ssa.nit:238,2--290,4