/// <summary> /// Computes the liveness for the given register /// </summary> /// <param name="backflowGraph">The backflow graph</param> /// <param name="register">The register</param> /// <param name="useSites">The use sites</param> /// <param name="aliveAt">The instructions which the register is alive</param> private static void ComputeLiveness(BackflowGraph backflowGraph, VirtualRegister register, IList<UsageSite> useSites, ISet<int> aliveAt) { foreach (var useSite in useSites) { ComputeLiveness( backflowGraph, useSite.Block, useSite.Offset, new HashSet<VirtualBasicBlock>(), register, aliveAt); } }
/// <summary> /// Computes the liveness for the given register /// </summary> /// <param name="backflowGraph">The backflow graph</param> /// <param name="basicBlock">The current block</param> /// <param name="startOffset">The offset in the current block</param> /// <param name="visited">The visited blocks</param> /// <param name="register">The current register</param> /// <param name="aliveAt">The instructions which the register is alive</param> private static void ComputeLiveness( BackflowGraph backflowGraph, VirtualBasicBlock basicBlock, int startOffset, ISet<VirtualBasicBlock> visited, VirtualRegister register, ISet<int> aliveAt) { if (visited.Contains(basicBlock)) { return; } visited.Add(basicBlock); bool terminated = false; for (int i = startOffset; i >= 0; i--) { var instruction = basicBlock.Instructions[i]; if (instruction.AssignRegister == register) { if (!instruction.UsesRegisters.Contains(register)) { aliveAt.Add(i + basicBlock.StartOffset); terminated = true; break; } } aliveAt.Add(i + basicBlock.StartOffset); } //If we have not terminated the search, search edges flowing backwards from the current block if (!terminated) { ISet<VirtualBasicBlock> edges; if (backflowGraph.Edges.TryGetValue(basicBlock, out edges)) { foreach (var backEdge in edges) { ComputeLiveness( backflowGraph, backEdge, backEdge.Instructions.Count - 1, visited, register, aliveAt); } } } }