public static ControlFlowGraph LiveVariableDeleteDeadCode(ControlFlowGraph cfg) { var newInstructions = new List <Instruction>(); var activeVariable = new LiveVariableAnalysis(); var resActiveVariable = activeVariable.Execute(cfg); foreach (var x in cfg.GetCurrentBasicBlocks().Take(cfg.GetCurrentBasicBlocks().Count - 1).Skip(1)) { var instructionsTemp = x.GetInstructions(); if (resActiveVariable.ContainsKey(x)) { var InOutTemp = resActiveVariable[x]; foreach (var i in instructionsTemp) { if (!InOutTemp.Out.Contains(i.Result) && i.Operation == "assign" && i.Argument1 != i.Result) { if (i.Label != "") { newInstructions.Add(new Instruction(i.Label, "noop", "", "", "")); } } else { newInstructions.Add(i); } } } } return(new ControlFlowGraph(newInstructions)); }
public void DeleteDeadCode(ControlFlowGraph graph) { var usedVars = CreateUsedVarsSets(graph); var info = new ReachingDefinitions().Execute(graph); var usedDefinitions = new HashSet <Instruction>( info[graph.GetCurrentBasicBlocks().Last()].In, new InstructionComparer()); var possibleOperationTypes = new[] { "assign", "input", "PLUS" }; var wasChanged = true; while (wasChanged) { wasChanged = false; foreach (var block in graph.GetCurrentBasicBlocks()) { var deadDefinitions = info[block].In.Except(info[block].Out); foreach (var oldDef in deadDefinitions) { var variable = oldDef.Result; // find first assign in current block that rewrites variable var newDefIndex = block.GetInstructions() .Select((t, i) => new { Instruction = t, Index = i }) .First(t => possibleOperationTypes.Contains(t.Instruction.Operation) && t.Instruction.Result == variable) .Index; var blockWithOldDef = graph.GetCurrentBasicBlocks() .Single(z => z.GetInstructions().Any(t => t == oldDef)); var oldDefIndex = blockWithOldDef.GetInstructions() .Select((t, i) => new { Instruction = t, Index = i }) .Single(t => t.Instruction == oldDef) .Index; if (usedDefinitions.Contains(oldDef) || IsUsedInCurrentBlock(block, variable, newDefIndex) || IsUsedInOriginalBlock(blockWithOldDef, variable, oldDefIndex) || IsUsedInOtherBlocks(graph, blockWithOldDef, oldDef, usedVars, info)) { usedDefinitions.Add(oldDef); continue; } // remove useless definition blockWithOldDef.RemoveInstructionByIndex(oldDefIndex); if (!string.IsNullOrEmpty(oldDef.Label)) { blockWithOldDef.InsertInstruction(oldDefIndex, new Instruction(oldDef.Label, "noop", null, null, null)); } info = new ReachingDefinitions().Execute(graph); wasChanged = true; } } } }
/// <summary> /// Принимает Граф потока данных и по нему ищет все естественные циклы /// </summary> /// <param name="cfg">Граф потока управления</param> /// <returns> /// Вернет все натуральные циклы /// </returns> public static IReadOnlyList <IReadOnlyList <BasicBlock> > GetAllNaturalLoops(ControlFlowGraph cfg) { if (cfg.IsReducibleGraph()) { var natLoops = new List <List <BasicBlock> >(); var ForwardEdges = cfg.GetCurrentBasicBlocks(); foreach (var(From, To) in cfg.GetBackEdges()) { if (cfg.VertexOf(To) > 0) { var tmp = new List <BasicBlock>(); for (var i = cfg.VertexOf(To); i < cfg.VertexOf(From) + 1; i++) { if (!tmp.Contains(ForwardEdges[i])) { tmp.Add(ForwardEdges[i]); } } natLoops.Add(tmp); } } return(natLoops.Where(loop => IsNaturalLoop(loop, cfg)).ToList()); } else { Console.WriteLine("Граф не приводим"); return(new List <List <BasicBlock> >()); } }
public ReachingTransferFunc(ControlFlowGraph g) { var basicBlocks = g.GetCurrentBasicBlocks(); GetDefs(basicBlocks); GetGenKill(basicBlocks); }
private Dictionary <BasicBlock, HashSet <string> > CreateUsedVarsSets(ControlFlowGraph graph) { var result = new Dictionary <BasicBlock, HashSet <string> >(); foreach (var block in graph.GetCurrentBasicBlocks()) { result[block] = new HashSet <string>(); foreach (var instruction in block.GetInstructions()) { if (IsVariable(instruction.Argument1)) { result[block].Add(instruction.Argument1); } if (IsVariable(instruction.Argument2)) { result[block].Add(instruction.Argument2); } } } return(result); }
public override InOutData <Dictionary <string, LatticeValue> > Execute(ControlFlowGraph graph, bool useRenumbering = true) { var blocks = graph.GetCurrentBasicBlocks(); var variables = new HashSet <string>(); foreach (var block in blocks) { foreach (var instr in block.GetInstructions()) { if (checkStr(instr.Result) && !variables.Contains(instr.Result)) { variables.Add(instr.Result); } if (checkStr(instr.Argument1) && instr.Argument1 != "True" && instr.Argument1 != "False" && !int.TryParse(instr.Argument1, out var temp1) && !variables.Contains(instr.Argument1)) { variables.Add(instr.Argument1); } if (checkStr(instr.Argument2) && instr.Argument2 != "True" && instr.Argument2 != "False" && !int.TryParse(instr.Argument2, out var temp2) && !variables.Contains(instr.Argument2)) { variables.Add(instr.Argument2); } } } var temp = new Dictionary <string, LatticeValue>(); foreach (var elem in variables) { temp.Add(elem, new LatticeValue(LatticeTypeData.UNDEF)); } Init = temp; TransferFunction = Transfer; return(base.Execute(graph)); }
public INsOUTs ExecuteNonGeneric(ControlFlowGraph g) { var blocks = g.GetCurrentBasicBlocks(); var INs = new Dictionary <BasicBlock, Dictionary <string, LatticeValue> >(); var OUTs = new Dictionary <BasicBlock, Dictionary <string, LatticeValue> >(); var variables = new HashSet <string>(); foreach (var block in blocks) { foreach (var instr in block.GetInstructions()) { if (checkStr(instr.Result) && !variables.Contains(instr.Result)) { variables.Add(instr.Result); } if (checkStr(instr.Argument1) && instr.Argument1 != "True" && instr.Argument1 != "False" && !int.TryParse(instr.Argument1, out var temp1) && !variables.Contains(instr.Argument1)) { variables.Add(instr.Argument1); } if (checkStr(instr.Argument2) && instr.Argument2 != "True" && instr.Argument2 != "False" && !int.TryParse(instr.Argument2, out var temp2) && !variables.Contains(instr.Argument2)) { variables.Add(instr.Argument2); } } } var temp = new Dictionary <string, LatticeValue>(); foreach (var elem in variables) { temp.Add(elem, new LatticeValue(LatticeTypeData.UNDEF)); } foreach (var block in blocks) { INs.Add(block, temp.ToDictionary(entry => entry.Key, entry => entry.Value)); OUTs.Add(block, temp.ToDictionary(entry => entry.Key, entry => entry.Value)); } var Changed = true; while (Changed) { Changed = false; foreach (var block in blocks) { var parents = g.GetParentsBasicBlocks(g.VertexOf(block)).Select(x => x.block); INs[block] = parents.Select(x => OUTs[x]) .Aggregate(temp.ToDictionary(entry => entry.Key, entry => entry.Value), (x, y) => Collect(x, y)); var newOut = Transfer(block, INs[block]); if (OUTs[block].Where(entry => newOut[entry.Key] != entry.Value).Any()) { Changed = true; OUTs[block] = newOut; } } } return(new INsOUTs { IN = INs, OUT = OUTs }); }