protected override ThreeAddressCode ProcessTAC(ThreeAddressCode tacContainer) { var optimization = new CommonSubexprOptimization(); optimization.Optimize(tacContainer); return(tacContainer); }
private void OptimizationInBlock(TacExpr expr, ThreeAddressCode block, string tmpName) { var taCode = block.TACodeLines.First; while (taCode != null) { var node = taCode.Value; if (node is TacAssignmentNode assign) { TacExpr nodeExpr = new TacExpr(assign.FirstOperand, assign.Operation, assign.SecondOperand); string id = assign.LeftPartIdentifier; if (id == expr.FirstOperand || id == expr.SecondOperand) { block.TACodeLines.AddAfter(block.TACodeLines.Find(node), expr.CreateAssignNode(tmpName)); } if (nodeExpr.Equals(expr) && id != tmpName) { assign.FirstOperand = tmpName; assign.Operation = null; assign.SecondOperand = null; } } taCode = taCode.Next; } }
public bool Optimize(ThreeAddressCode tac) { var isApplied = false; var targetLabels = FindAllTargetLabels(tac); var currentNode = tac.TACodeLines.First; var linesToDelete = new List <TacNode>(); while (currentNode != null) { var line = currentNode.Value; if (line is TacIfGotoNode ifGotoNode && Equals(ifGotoNode.Condition, "True")) { if (CheckLabels(targetLabels, currentNode.Next, ifGotoNode.TargetLabel, linesToDelete)) { tac[line.Label] = new TacGotoNode { Label = ifGotoNode.Label, TargetLabel = ifGotoNode.TargetLabel }; tac.RemoveNodes(linesToDelete); linesToDelete.Clear(); isApplied = true; } } currentNode = currentNode.Next; } return(isApplied); }
protected override ThreeAddressCode ProcessTAC(ThreeAddressCode tacContainer) { var elimintaion = new EliminateTranToTranOpt(); elimintaion.Optimize(tacContainer); return(tacContainer); }
public void Optimize_NoParamsWithDefinedType() { TmpNameManager.Instance.Drop(); var tacContainer = new ThreeAddressCode(); Utils.AddAssignmentNode(tacContainer, null, "a", "x", "+", "y"); Utils.AddAssignmentNode(tacContainer, null, "b", "x", "+", "y"); Utils.AddAssignmentNode(tacContainer, null, "a", "17"); Utils.AddAssignmentNode(tacContainer, null, "b", "18"); Utils.AddAssignmentNode(tacContainer, null, "c", "x", "+", "y"); var expectedResult = new ThreeAddressCodeVisitor(); Utils.AddAssignmentNode(expectedResult, null, "a", "x", "+", "y"); Utils.AddAssignmentNode(expectedResult, null, "b", "a"); Utils.AddAssignmentNode(expectedResult, null, "t1", "a"); Utils.AddAssignmentNode(expectedResult, null, "a", "17"); Utils.AddAssignmentNode(expectedResult, null, "b", "18"); Utils.AddAssignmentNode(expectedResult, null, "c", "t1"); var optimization = new LocalValueNumberingOptimization(); var isOptimized = optimization.Optimize(tacContainer); Assert.IsTrue(isOptimized); Assert.AreEqual(tacContainer.ToString(), expectedResult.ToString()); }
public TACGenerationVisitor() { tempVariableCounter = 0; tempLabelCounter = 0; Instructions = new List <TACInstruction>(); TAC = new ThreeAddressCode(Instructions); }
public Dictionary <string, bool> InitializeVariables(ThreeAddressCode block, HashSet <TacNode> outData) { Dictionary <string, bool> result = new Dictionary <string, bool>(); foreach (var line in block) { if (line.GetType() == typeof(TacAssignmentNode)) { string leftIdent = ((TacAssignmentNode)line).LeftPartIdentifier; if (IsVariable(leftIdent) && !result.ContainsKey(leftIdent)) { result.Add(leftIdent, false); } else if (IsTempVariable(leftIdent) && !result.ContainsKey(leftIdent)) { result.Add(leftIdent, false); } } } foreach (var item in outData) { if (result.ContainsKey(item.ToString())) { result[item.ToString()] = true; } } return(result); }
private void Build(ThreeAddressCode block) { if (block == null) { return; } _visitedBlocks.Add(block); var outEdges = _cfg.OutEdges(block); foreach (var edge in outEdges) { var targetBlock = edge.Target; if (_visitedBlocks.Contains(targetBlock)) { continue; } if (!ContainsVertex(block)) { Graph.AddVertex(block); } if (!ContainsVertex(targetBlock)) { Graph.AddVertex(targetBlock); } Graph.AddEdge(new Edge <ThreeAddressCode>(block, targetBlock)); Build(targetBlock); } }
public void Rebuild_SingleBasicBlock() { var tacContainer0 = Utils.GetNestedLoopWithCounterInTAC(); var tacContainer1 = new ThreeAddressCode(); Utils.AddAssignmentNode(tacContainer1, null, "a", "1"); Utils.AddAssignmentNode(tacContainer1, null, "b", "10"); Utils.AddAssignmentNode(tacContainer1, null, "c", "a", "+", "b"); var cfg = new ControlFlowGraph(tacContainer0); cfg.Rebuild(tacContainer1); Assert.IsTrue(cfg.IsEdgesEmpty); Assert.IsFalse(cfg.IsVerticesEmpty); Assert.AreEqual(cfg.EdgeCount, 0); Assert.AreEqual(cfg.VertexCount, 1); Assert.AreEqual(cfg.Edges.Count(), 0); Assert.AreEqual(cfg.Vertices.Count(), 1); Assert.IsNotNull(cfg.SourceBasicBlocks); Assert.AreEqual(cfg.EntryBlock.ToString(), tacContainer1.ToString()); Assert.AreEqual(cfg.ExitBlock.ToString(), tacContainer1.ToString()); }
public bool Optimize(ThreeAddressCode tac) { bool isUsed = false; var node = tac.TACodeLines.First; while (true) { var next = node.Next; if (next == null) { break; } var val = node.Value; var label = val.Label; if (val is TacEmptyNode && val.Label == null) { isUsed = true; if (next != null) { next.Value.Label = label; } tac.TACodeLines.Remove(node); } node = next; } return(isUsed); }
public HashSet <TacNode> Calculate(HashSet <TacNode> _in, ThreeAddressCode bblock) { basicBlock = bblock; var func = _in; foreach (var line in GetBasicBlock()) { var gen = new HashSet <TacNode>(); gen.UnionWith(GetLineGen(line)); var kill = new HashSet <TacNode>(); kill.UnionWith(GetLineKill(line)); var exceptKill = new HashSet <TacNode>(); exceptKill.UnionWith(func); exceptKill.ExceptWith(kill); gen.UnionWith(exceptKill); func = new HashSet <TacNode>(); func.UnionWith(gen); } return(func); }
public static BoundBlockExpression Lower(Symbol method, BoundStatement boundStatement) { var tac = new ThreeAddressCode(method); tac.RewriteStatement(boundStatement); return(tac.GetBlock(boundStatement.Syntax)); }
public void Optimize_OneCopyPropagation() { /* * a = b * c = b - a ---> c = b - b * a = 1 * e = d * a ---> e = d * a */ var tacContainer = new ThreeAddressCode(); Utils.AddAssignmentNode(tacContainer, "L1", "a", "b"); Utils.AddAssignmentNode(tacContainer, null, "c", "b", "-", "a"); Utils.AddAssignmentNode(tacContainer, null, "a", "1"); Utils.AddAssignmentNode(tacContainer, null, "e", "d", "*", "a"); var expectedResult = new ThreeAddressCode(); Utils.AddAssignmentNode(expectedResult, "L1", "a", "b"); Utils.AddAssignmentNode(expectedResult, null, "c", "b", "-", "b"); Utils.AddAssignmentNode(expectedResult, null, "a", "1"); Utils.AddAssignmentNode(expectedResult, null, "e", "d", "*", "a"); var optimization = new CopyPropagationOptimization(); var isOptimized = optimization.Optimize(tacContainer); Assert.IsTrue(isOptimized); Assert.AreEqual(tacContainer.ToString(), expectedResult.ToString()); }
/// <summary> /// Creates and pushes empty node to the end of the tac container /// </summary> public static void AddEmptyNode(ThreeAddressCode tacContainer, string label = null) { tacContainer.PushNode(new TacEmptyNode() { Label = label }); }
public TACOptimizer(ThreeAddressCode tac, List <BasicBlock> blocks, ControlFlowGraph cfg) { TAC = tac; Instructions = tac.Instructions; Blocks = blocks; Cfg = cfg; }
public void Optimize_SimpleBlock() { TmpNameManager.Instance.Drop(); /* * * x = a; To be removed * x = b; * y = x + 1; */ var tacContainer = new ThreeAddressCode(); Utils.AddAssignmentNode(tacContainer, null, "x", "a"); Utils.AddAssignmentNode(tacContainer, null, "x", "b"); Utils.AddAssignmentNode(tacContainer, null, "y", "x", "+", "1"); Utils.AddAssignmentNode(tacContainer, null, "e", "d", "*", "a"); var expectedResult = new ThreeAddressCode(); Utils.AddAssignmentNode(expectedResult, null, "x", "b"); Utils.AddAssignmentNode(expectedResult, null, "y", "x", "+", "1"); Utils.AddAssignmentNode(expectedResult, null, "e", "d", "*", "a"); var optimization = new DeadCodeOptimization(); var isOptimized = optimization.Optimize(tacContainer); Assert.IsTrue(isOptimized); Assert.AreEqual(tacContainer.ToString(), expectedResult.ToString()); isOptimized = optimization.Optimize(tacContainer); Assert.IsFalse(isOptimized); }
public bool Optimize(ThreeAddressCode tac) { bool isUsed = false; var node = tac.TACodeLines.First; while (node != null) { var next = node.Next; var val = node.Value; var label = val.Label; if (next != null) { var nextVal = next.Value; if (val is TacIfGotoNode && nextVal is TacGotoNode) { isUsed = true; var ifVal = val as TacIfGotoNode; ifVal.Condition = "!(" + ifVal.Condition + ")"; var oldTarget = ifVal.TargetLabel; ifVal.TargetLabel = (nextVal as TacGotoNode).TargetLabel; var remove = next; next = next.Next; next.Value.Label = null; tac.TACodeLines.Remove(remove); } } node = next; } return(isUsed); }
public bool Optimize(ThreeAddressCode tac) { var initialTac = tac.ToString(); var node = tac.Last; while (node != null) { if (node.Value is TacAssignmentNode assignment) { if (assignment.SecondOperand == null && Utility.Utility.IsNum(assignment.FirstOperand)) { var key = new VarNodePair(assignment.LeftPartIdentifier, node); if (_detector.Definitions.ContainsKey(key)) { foreach (var usage in _detector.Definitions[key]) { ChangeByConst(usage.Value, assignment); } _detector.Definitions.Remove(key); } } } node = node.Previous; } return(!initialTac.Equals(tac.ToString())); }
protected override ThreeAddressCode ProcessTAC(ThreeAddressCode tacContainer) { var optimization = new UnreachableCodeOpt(); optimization.Optimize(tacContainer); return(tacContainer); }
public static BoundBlockExpression Lower(Symbol method, BoundStatement statement) { var debug = false; if (debug) { Console.WriteLine("==== Original Code ==="); statement.WriteTo(Console.Out); } var boundStatement = LoopLowerer.Lower(method, statement); if (debug) { Console.WriteLine("==== Lowered Code ==="); boundStatement.WriteTo(Console.Out); } var noIndexExpr = IndexExpressions.Lower(method, boundStatement); if (debug) { Console.WriteLine("==== Index Expressions ==="); noIndexExpr.WriteTo(Console.Out); } var tac = ThreeAddressCode.Lower(method, noIndexExpr); if (debug) { Console.WriteLine("==== Three Address Code ==="); tac.WriteTo(Console.Out); } var unitLessStatements = RemoveUnitAssignments.Lower(tac); if (debug) { Console.WriteLine("==== Remove Unit Assignments ==="); unitLessStatements.WriteTo(Console.Out); } var inlinedTemporaries = InlineTemporaries.Lower(method, unitLessStatements); if (debug) { Console.WriteLine("==== Inlined Temporaries ==="); inlinedTemporaries.WriteTo(Console.Out); } var deadCodeRemoval = DeadCodeRemoval.RemoveDeadCode(inlinedTemporaries); if (debug) { Console.WriteLine("==== Dead Code Removal ==="); deadCodeRemoval.WriteTo(Console.Out); } return(deadCodeRemoval); }
public void AnalyzeVariables(ThreeAddressCode block) { InitializeVariables(block); string tempRes = ""; for (int i = block.TACodeLines.Count - 1; i >= 0; --i) { if (block.TACodeLines.ElementAt(i).GetType() == typeof(TacAssignmentNode)) { string leftIdent = ((TacAssignmentNode)block.TACodeLines.ElementAt(i)).LeftPartIdentifier; if (IsVariable(leftIdent) || IsTempVariable(leftIdent)) { this.variables[leftIdent] = false; } string firstOp = ((TacAssignmentNode)block.TACodeLines.ElementAt(i)).FirstOperand; if (IsVariable(firstOp) || IsTempVariable(firstOp)) { this.variables[firstOp] = true; } string secondOp = ((TacAssignmentNode)block.TACodeLines.ElementAt(i)).SecondOperand; if (IsVariable(secondOp) || IsTempVariable(secondOp)) { this.variables[secondOp] = true; } } } }
/// <summary> /// Returns the code containing nested loop with counter converted to TAC /// </summary> public static ThreeAddressCode GetNestedLoopWithCounterInTAC() { /* * a = 1; * for (i = 1 to 10) * for (j = 1 to 10) * a = a + 1; */ var tacContainer = new ThreeAddressCode(); // basic block #0 AddAssignmentNode(tacContainer, null, "a", "1"); AddAssignmentNode(tacContainer, null, "i", "1"); // basic block #1 AddAssignmentNode(tacContainer, "L1", "j", "1"); // basic block #2 AddAssignmentNode(tacContainer, "L2", "t1", "a", "+", "1"); AddAssignmentNode(tacContainer, null, "a", "t1"); AddAssignmentNode(tacContainer, null, "j", "j", "+", "1"); AddAssignmentNode(tacContainer, null, "t2", "j", "<", "10"); AddIfGotoNode(tacContainer, null, "L2", "t2"); // basic block #3 AddAssignmentNode(tacContainer, null, "i", "i", "+", "1"); AddAssignmentNode(tacContainer, null, "t3", "i", "<", "10"); AddIfGotoNode(tacContainer, null, "L1", "t3"); return(tacContainer); }
public AstMethodDefinition Decompile(MethodDefinition source) { ILtoTACTransformer tacTransformer = new ILtoTACTransformer(); ThreeAddressCode tac = tacTransformer.Decompile(source); TACtoASTTransformer astTransformer = new TACtoASTTransformer(); return(astTransformer.Decompile(tac)); }
private ControlFlowGraph(ThreeAddressCode tac, BasicBlocks basicBlocks, IEnumerable <ThreeAddressCode> vertices, IEnumerable <Edge <ThreeAddressCode> > edges) { SourceCode = tac; SourceBasicBlocks = basicBlocks; Graph.AddVertexRange(vertices); Graph.AddEdgeRange(edges); }
/// <summary> /// Creates and pushes goto node to the end of the tac container /// </summary> public static void AddGotoNode(ThreeAddressCode tacContainer, string label, string targetLabel) { tacContainer.PushNode(new TacGotoNode { Label = label, TargetLabel = targetLabel }); }
public bool Optimize(ThreeAddressCode tac) { var isOptimized = false; var directAssignments = new Dictionary <string, string>(); var blocks = new BasicBlocks(); blocks.SplitTACode(tac); foreach (var block in blocks) { var currentNode = block.First; while (currentNode != null) { if (currentNode.Value is TacAssignmentNode assignmentNode) { if (assignmentNode.Operation == null) { if (directAssignments.ContainsKey(assignmentNode.LeftPartIdentifier)) { directAssignments.Remove(assignmentNode.LeftPartIdentifier); } if (!int.TryParse(assignmentNode.FirstOperand, out int firstOpValue)) { var id = assignmentNode.LeftPartIdentifier; var firstOp = assignmentNode.FirstOperand; directAssignments.Add(id, firstOp); } } if (directAssignments.ContainsKey(assignmentNode.FirstOperand)) { assignmentNode.FirstOperand = directAssignments[assignmentNode.FirstOperand]; isOptimized = true; } if (assignmentNode.SecondOperand != null && directAssignments.ContainsKey(assignmentNode.SecondOperand)) { assignmentNode.SecondOperand = directAssignments[assignmentNode.SecondOperand]; isOptimized = true; } if (directAssignments.ContainsKey(assignmentNode.LeftPartIdentifier) && assignmentNode.SecondOperand != null && assignmentNode.FirstOperand != null) { directAssignments.Remove(assignmentNode.LeftPartIdentifier); } } currentNode = currentNode.Next; } } return(isOptimized); }
public override void Run() { var res = DeleteDeadCode(Instructions); if (res.Item1) { Instructions = res.Item2; TAC = new ThreeAddressCode(Instructions); } }
/// <summary> /// Creates and pushes if-goto node to the end of the tac container /// </summary> public static void AddIfGotoNode(ThreeAddressCode tacContainer, string label, string targetLabel, string condition) { tacContainer.PushNode(new TacIfGotoNode { Label = label, Condition = condition, TargetLabel = targetLabel }); }
public void Constructor_EmptyOrNullSourceCode() { var tacContainer0 = new ThreeAddressCode(); ThreeAddressCode tacContainer1 = null; var cfg0 = new ControlFlowGraph(tacContainer0); var cfg1 = new ControlFlowGraph(tacContainer1); CheckGraphForEmptiness(cfg0); CheckGraphForEmptiness(cfg1); }
public ControlFlowGraph(ThreeAddressCode tac) { SourceCode = tac; if (SourceCode == null || SourceCode.TACodeLines.Count == 0) { return; } Build(); }