public static void DominanceCalculation2() { var basicBlocks = BlockTests.Scenario4; SimpleFastDominance dominance = new SimpleFastDominance(basicBlocks, basicBlocks[0]); IDominanceAnalysis provider = dominance as IDominanceAnalysis; Assert.Same(provider.GetImmediateDominator(basicBlocks[0]), null); Assert.Same(provider.GetImmediateDominator(basicBlocks[1]), basicBlocks[0]); Assert.Same(provider.GetImmediateDominator(basicBlocks[2]), basicBlocks[1]); Assert.Same(provider.GetImmediateDominator(basicBlocks[3]), basicBlocks[0]); Assert.Same(provider.GetImmediateDominator(basicBlocks[4]), basicBlocks[0]); Assert.Same(provider.GetImmediateDominator(basicBlocks[5]), basicBlocks[4]); Assert.Same(provider.GetImmediateDominator(basicBlocks[6]), basicBlocks[4]); Assert.Same(provider.GetImmediateDominator(basicBlocks[7]), basicBlocks[4]); Assert.Same(provider.GetImmediateDominator(basicBlocks[8]), basicBlocks[0]); Assert.Same(provider.GetImmediateDominator(basicBlocks[9]), basicBlocks[8]); Assert.Same(provider.GetImmediateDominator(basicBlocks[10]), basicBlocks[8]); Assert.Same(provider.GetImmediateDominator(basicBlocks[11]), basicBlocks[0]); Assert.Same(provider.GetImmediateDominator(basicBlocks[12]), basicBlocks[0]); Assert.Equal(provider.GetDominators(basicBlocks[0]), new[] { basicBlocks[0] }); //Assert.Equal(provider.GetDominators(basicBlocks[1]), new[] { basicBlocks[0], basicBlocks[1] }); //Assert.Equal(provider.GetDominators(basicBlocks[2]), new[] { basicBlocks[0], basicBlocks[1], basicBlocks[2] }); //Assert.Equal(provider.GetDominators(basicBlocks[3]), new[] { basicBlocks[0], basicBlocks[3] }); //Assert.Equal(provider.GetDominators(basicBlocks[4]), new[] { basicBlocks[0], basicBlocks[4] }); //Assert.Equal(provider.GetDominators(basicBlocks[5]), new[] { basicBlocks[0], basicBlocks[4], basicBlocks[5] }); //Assert.Equal(provider.GetDominators(basicBlocks[6]), new[] { basicBlocks[0], basicBlocks[4], basicBlocks[6] }); //Assert.Equal(provider.GetDominators(basicBlocks[7]), new[] { basicBlocks[0], basicBlocks[4], basicBlocks[7] }); //Assert.Equal(provider.GetDominators(basicBlocks[8]), new[] { basicBlocks[0], basicBlocks[8] }); //Assert.Equal(provider.GetDominators(basicBlocks[9]), new[] { basicBlocks[0], basicBlocks[8], basicBlocks[9] }); //Assert.Equal(provider.GetDominators(basicBlocks[10]), new[] { basicBlocks[0], basicBlocks[8], basicBlocks[10] }); //Assert.Equal(provider.GetDominators(basicBlocks[11]), new[] { basicBlocks[0], basicBlocks[11] }); //Assert.Equal(provider.GetDominators(basicBlocks[12]), new[] { basicBlocks[0], basicBlocks[12] }); //Assert.Equal(provider.GetDominanceFrontier(basicBlocks[4]), new[] { basicBlocks[3], basicBlocks[4], basicBlocks[11], basicBlocks[12] }); Dump(basicBlocks, dominance); }
internal static void Dump(BasicBlocks basicBlocks, IDominanceAnalysis analysis) { foreach (var b in basicBlocks) { Console.WriteLine(b.ToString() + " -> " + analysis.GetImmediateDominator(b)); } Console.WriteLine(); foreach (var b in basicBlocks) { Console.Write(b.ToString() + " -> "); foreach (var d in analysis.GetDominators(b)) { Console.Write(d.ToString() + " "); } Console.WriteLine(); } return; }
/// <summary> /// Renames the variables. /// </summary> /// <param name="block">The block.</param> /// <param name="dominance">The dominance provider.</param> private void RenameVariables(BasicBlock block, IDominanceAnalysis dominance) { for (var node = block.First; !node.IsBlockEndInstruction; node = node.Next) { if (node.Instruction != IRInstruction.Phi) { for (var i = 0; i < node.OperandCount; ++i) { var op = node.GetOperand(i); if (op == null || !op.IsVirtualRegister) continue; Debug.Assert(variables.ContainsKey(op), op.ToString() + " is not in dictionary [block = " + block + "]"); var version = variables[op].Peek(); node.SetOperand(i, GetSSAOperand(op, version)); } } if (!node.IsEmpty && node.Result != null && node.Result.IsVirtualRegister) { var op = node.Result; var index = counts[op]; node.Result = GetSSAOperand(op, index); variables[op].Push(index); counts[op] = index + 1; } } foreach (var s in block.NextBlocks) { // index does not change between this stage and PhiPlacementStage since the block list order does not change var index = WhichPredecessor(s, block); for (var context = new Context(s); !context.IsBlockEndInstruction; context.GotoNext()) { if (context.Instruction != IRInstruction.Phi) continue; Debug.Assert(context.OperandCount == context.Block.PreviousBlocks.Count); var op = context.GetOperand(index); if (variables[op].Count > 0) { var version = variables[op].Peek(); context.SetOperand(index, GetSSAOperand(context.GetOperand(index), version)); } } } foreach (var s in dominance.GetChildren(block)) { RenameVariables(s, dominance); } for (var context = new Context(block); !context.IsBlockEndInstruction; context.GotoNext()) { if (!context.IsEmpty && context.Result != null && context.Result.IsVirtualRegister) { var op = context.Result.SSAParent; var index = variables[op].Pop(); } } }
internal static void Dump(BasicBlocks basicBlocks, IDominanceAnalysis analysis) { foreach (var b in basicBlocks) { Console.WriteLine(b.ToString() + " -> " + analysis.GetImmediateDominator(b)); } Console.WriteLine(); foreach (var b in basicBlocks) { Console.Write(b.ToString() + " -> "); foreach (var d in analysis.GetDominators(b)) Console.Write(d.ToString() + " "); Console.WriteLine(); } return; }
/// <summary> /// Renames the variables. /// </summary> /// <param name="block">The block.</param> /// <param name="dominance">The dominance provider.</param> private void RenameVariables(BasicBlock block, IDominanceAnalysis dominance) { for (var node = block.First; !node.IsBlockEndInstruction; node = node.Next) { if (node.Instruction != IRInstruction.Phi) { for (var i = 0; i < node.OperandCount; ++i) { var op = node.GetOperand(i); if (op == null || !op.IsVirtualRegister) { continue; } Debug.Assert(variables.ContainsKey(op), op.ToString() + " is not in dictionary [block = " + block + "]"); var version = variables[op].Peek(); node.SetOperand(i, GetSSAOperand(op, version)); } } if (!node.IsEmpty && node.Result != null && node.Result.IsVirtualRegister) { var op = node.Result; var index = counts[op]; node.Result = GetSSAOperand(op, index); variables[op].Push(index); counts[op] = index + 1; } } foreach (var s in block.NextBlocks) { // index does not change between this stage and PhiPlacementStage since the block list order does not change var index = WhichPredecessor(s, block); for (var context = new Context(s); !context.IsBlockEndInstruction; context.GotoNext()) { if (context.Instruction != IRInstruction.Phi) { continue; } Debug.Assert(context.OperandCount == context.Block.PreviousBlocks.Count); var op = context.GetOperand(index); if (variables[op].Count > 0) { var version = variables[op].Peek(); context.SetOperand(index, GetSSAOperand(context.GetOperand(index), version)); } } } foreach (var s in dominance.GetChildren(block)) { RenameVariables(s, dominance); } for (var context = new Context(block); !context.IsBlockEndInstruction; context.GotoNext()) { if (!context.IsEmpty && context.Result != null && context.Result.IsVirtualRegister) { var op = context.Result.SSAParent; var index = variables[op].Pop(); } } }