public TestForm() { InitializeComponent(); #region Graph graph = new CFGraph(PB_Graph, 40); string cCode = "int main() {\n\tint abc; switch(abc) { case 1:{i++;break;} case 2:{i++;break;} default:{asd--;break;} } \n\treturn 0; }\n"; //string cCode = "if (true) printf(\"k\"); else { printf(\"no\"); cout << \"awsm\"; }"; //string cCode = "while (true) { ok1(); ok2(); goto someLBL; DEADStatement; someLBL: stat1; stat2;}"; //string cCode = "while (true) {switch (c) { case 1: break; case 2: continue; } break;}"; CFGParserWrapper.SetCodeToParse(cCode); GraphManager.BuildGraph(graph, CFGParserWrapper.GetPairs()); #endregion #region Code int offsetV = 40; master = new ProgramTextMaster(PB_Code, CFGParserWrapper.GetParsedCode(), new ProgramTextBrushes(Brushes.Black, Brushes.DarkRed, Brushes.DarkGray)); master.CreateProgramText(offsetV); #endregion }
public SsaConstruction(CFGraph inputGraph) { variables = GetAllVariables(inputGraph); var phiGraph = InsertPhiFunctions(inputGraph); ssaForm = RenameVariables(phiGraph); }
/// <summary> /// Inserts phi functions for all variables in every block, /// which contains 2 predesessors /// </summary> /// <param name="inputGraph"></param> /// <returns></returns> private CFGraph InsertPhiFunctions(CFGraph inputGraph) { CFGraph ssaGraph = inputGraph; //HashSet<BaseBlock> blocksWithPhi = new HashSet<BaseBlock>(); foreach (var variable in variables) { foreach (var node in inputGraph.graph.Vertices) { if (node.ParentsNodes.Count >= 2) { IValue phiLabel = new IdentificatorValue("phi" + phiCounter); var newAssign = new LinearRepresentation(Operation.Assign, variable , phiLabel, null); node.Value.AppendFirst(newAssign); foreach (var parentNode in node.ParentsNodes) { var phiFunc = new LinearRepresentation(Operation.Phi, phiLabel as StringValue , variable, parentNode.Value.Enumerate().Last().Label); node.Value.InsertAfter(newAssign, phiFunc); } phiCounter++; } } } return(ssaGraph); }
static void Main(string[] args) { string inp = File.ReadAllText("a.txt"); var root = Parser.ParseString(inp); // Генерация и получение трёхзначного кода var linearCode = new LinearCodeVisitor(); root?.AcceptVisit(linearCode); var code = linearCode.code; // Get blocks and print it var blocks = LinearToBaseBlock.Build(code); foreach (var block in blocks) { Console.WriteLine(block.ToString()); } // Get graph and made DepthSpanningTree var cfg = new CFGraph(blocks); var dst = new DepthSpanningTree(cfg); string dst_viz = dst.ToString(); Console.WriteLine(dst_viz); Console.ReadLine(); }
private HashSet <IdentificatorValue> GetAllVariables(CFGraph inputGraph) { HashSet <IdentificatorValue> variables = new HashSet <IdentificatorValue>(); foreach (var block in inputGraph.Blocks) { foreach (var line in block.Enumerate()) { //if (LinearHelper.AsDefinition(line) != null && !Utilities.IsPhiIdentificator(line.LeftOperand.Value as IdentificatorValue)) // variables.Add(line.Destination as IdentificatorValue); if (LinearHelper.AsDefinition(line) != null && !Utilities.IsPhiIdentificator(line.LeftOperand.Value as IdentificatorValue)) { if (line.LeftOperand is IdentificatorValue) { variables.Add(line.LeftOperand as IdentificatorValue); } if (line.RightOperand is IdentificatorValue) { variables.Add(line.RightOperand as IdentificatorValue); } if (line.Destination is IdentificatorValue) { variables.Add(line.Destination as IdentificatorValue); } } } } return(variables); }
/// <summary> /// Renaming variables in order to make single assignment /// of every variable /// </summary> /// <param name="inputGraph"></param> /// <returns></returns> private CFGraph RenameVariables(CFGraph inputGraph) { CFGraph ssaGraph = inputGraph; SsaVarsRenaming renaming = new SsaVarsRenaming(ssaGraph); return(renaming.Launch()); }
public void Display(PictureBox pb) { CFGraph graphR = new CFGraph(pb, 1, 10, 19); TreeParameters tParams = new TreeParameters(graphR); NodeToDisplay(_root, tParams, 0, pb.Width, 0); tParams.graphRenderer.EndOfDraw(); }
public TreeParameters(int xStart, int yStart, CFGraph graphRenderer) { this.xStart = xStart; this.yStart = yStart; this.graphRenderer = graphRenderer; depthLvl = 0; widthLvl = 0; nodeName = null; parentNodeName = null; }
public AvailableExprAnalyzer(CFGraph _cfg) { cfg = _cfg; // Генерируем e_gen и e_kills genKills = new GenKillExprs(cfg); // Инициализируем для всех ББЛ пустые списки с входными выражениями foreach (var vertice in cfg.GetVertices()) { InBlocks.Add(vertice.Value, new List <Expression>()); } }
public void SsaConstructionTest() { var root = Parser.ParseString(Samples.SampleProgramText.ssaoptimizationSample2); var code = ProgramTreeToLinear.Build(root); var blocks = LinearToBaseBlock.Build(code); var cfg = new CFGraph(blocks); Console.WriteLine("###--------- Input CF Graph ---------###"); Console.WriteLine(cfg.ToString()); SsaConstruction ssa = new SsaConstruction(cfg); Console.WriteLine("###--------- Output SSA Graph ---------###"); Console.WriteLine(ssa.SsaForm.ToString()); }
public void CFGraphTest() { var root = Parser.ParseString(Samples.SampleProgramText.sample2); var linearCode = new LinearCodeVisitor(); root.AcceptVisit(linearCode); var code = linearCode.code; var blocks = LinearToBaseBlock.Build(code); var cfg = new CFGraph(blocks); Console.WriteLine(cfg.ToString()); }
public GenKillExprs(CFGraph cfg) { var blocks = cfg.Blocks; foreach (var block in blocks) { BlockDefs[block] = new List <StringValue>(); Gen[block] = new List <Expression>(); Remove[block] = new List <Expression>(); var countOfElems = block.Enumerate().Count(); foreach (var elem in block.Enumerate().Reverse()) { if (elem.IsBinOp()) { BlockDefs[block].Add(elem.Destination); if (elem.Operation != Operation.NoOperation) { var expr = new Expression(elem.Operation, elem.LeftOperand, elem.RightOperand); var hasThisExpr = AllExpressions.Any(iexpr => iexpr.Equals(expr)); if (!hasThisExpr) { AllExpressions.Add(expr); } if (!BlockDefs[block].Contains(elem.LeftOperand) && !BlockDefs[block].Contains(elem.RightOperand)) { Gen[block].Add(expr); } } } } } foreach (Expression e in AllExpressions) { foreach (BaseBlock block in blocks) { if (!Gen[block].Contains(e) && (BlockDefs[block].Contains(e.LeftOper) || BlockDefs[block].Contains(e.RightOper))) { Remove[block].Add(e); } } } }
public void DSTTest() { var root = Parser.ParseString(Samples.SampleProgramText.sample2); var linearCode = new LinearCodeVisitor(); root.AcceptVisit(linearCode); var code = linearCode.code; var blocks = LinearToBaseBlock.Build(code); var cfg = new CFGraph(blocks); var dst = new DepthSpanningTree(cfg); cfg.ShowCompact = true; Console.WriteLine(cfg.ToString()); Console.WriteLine(dst.ToString()); }
public SsaVarsRenaming(CFGraph cfg) { this.cfGraph = cfg; variableStacks = new Dictionary <IdentificatorValue, Stack <int> >(); counters = new Dictionary <IdentificatorValue, int>(); var allVariables = GetAllVariables(cfGraph); foreach (var v in allVariables) { var stack = new Stack <int>(); stack.Push(0); variableStacks.Add(v, stack); counters.Add(v, 0); } }
public RegionSequence(CFGraph cfg) { regions = new List <Region>(); // Get all nodes of cfg List <CFGNode> allNodes = cfg.GetVertices().ToList(); // All edges in cfg List <Edge <CFGNode> > edges = cfg.EdgeTypes.Select(e => e.Key).ToList(); // Each node in cfg is leaf region foreach (var node in cfg.GetVertices()) { var edgesFromNode = edges.FindAll(e => e.Target == node); regions.Add(new LeafRegion(node, edges, NextName())); } var nc = cfg.getNaturalCyclesForBackwardEdges(); // Nodes which are headers of natural cycles HashSet <CFGNode> cyclesHeaders = new HashSet <CFGNode>(nc.Select(c => c[0])); // Headers of cycles. These cycles are added to list of regions HashSet <CFGNode> addedCyclesHeaders = new HashSet <CFGNode>(); while (nc.Count > 0) { // List of cycles we can add into regions (there are no nonadded cycles inside) List <List <CFGNode> > cyclesToAdd = nc.FindAll(c => c.Skip(1).All(node => { // If node is header of cycle then it should be added in list of regions return(cyclesHeaders.Contains(node) ? addedCyclesHeaders.Contains(node) : true); })); foreach (var cycle in cyclesToAdd) { var nodes = new HashSet <CFGNode>(cycle); AddCycle(cycle, edges, nodes); addedCyclesHeaders.Add(cycle[0]); } nc.RemoveAll(c => addedCyclesHeaders.Contains(c[0])); } // cfg is natural cycle if there is cycle header equals first node of cfg bool cfgIsNaturalCycle = cyclesHeaders.Contains(allNodes[0]); // If cfg isn't natural cycle then add region contains all nodes and edges if (!cfgIsNaturalCycle) { regions.Add(new BodyRegion(allNodes[0], allNodes, edges, NextName())); } }
public void SsaCopyPropagationTest() { var root = Parser.ParseString(Samples.SampleProgramText.ssaoptimizationSample3); var code = ProgramTreeToLinear.Build(root); var blocks = LinearToBaseBlock.Build(code); var cfg = new CFGraph(blocks); Console.WriteLine("###--------- Input CF Graph ---------###"); Console.WriteLine(cfg.ToString()); SsaConstruction ssa = new SsaConstruction(cfg); CFGraph ssaGraph = ssa.SsaForm; Console.WriteLine("###--------- Constructed SSA Graph ---------###"); Console.WriteLine(ssaGraph.ToString()); SsaCopyPropagation ssaCopyPropagation = new SsaCopyPropagation(ssaGraph); ssaCopyPropagation.Launch(); Console.WriteLine("###--------- Output SSA Graph after copy propagation ---------###"); Console.WriteLine(ssaCopyPropagation.OptimizedSsaGraph); }
// Constructor from list of blocks public DominatorTree(CFGraph cfg) { var doms = new DominatorsIterAlg(cfg).Dom; var vertices = doms.Keys.Select(x => new DominatorTreeNode(x)).ToList(); graph.AddVertexRange(vertices); foreach (var node in vertices) { var dominatedBy = doms[node.CFGNode].ToList(); dominatedBy.Reverse(); var cfgClosestDominator = dominatedBy.Skip(1).FirstOrDefault(); if (cfgClosestDominator != null) { var domClosestDominator = vertices.FirstOrDefault(x => x.CFGNode == cfgClosestDominator); node.ParentNode = domClosestDominator; domClosestDominator.AddChild(node); graph.AddEdge(new Edge <DominatorTreeNode>(domClosestDominator, node)); } } }
public ReachingDefsIterAlg(CFGraph g) : base(g) { GenKill = new GenKillBuilder(g.Blocks); Run(); }
public ActiveVarsIterAlg(CFGraph g) : base(g) { DefUse = new DefUseBuilder(g.Blocks); ReverseRun(); }
public DominatorsIterAlg(CFGraph g) : base(g) { Run(); Dom = Out; }
public TreeParameters(CFGraph graphRenderer) { this.graphRenderer = graphRenderer; nodeName = null; }
protected IterativeCommonAlg(CFGraph g) { graph = g; }
static void Main(string[] args) { var text = File.ReadAllText("a.txt"); //text = "n = 0;" + // "if n {" + // "custom_label1:" + // "goto custom_label2;" + // "}" + // "else {" + // "custom_label2:" + // "goto custom_label1;" + // "}"; var root = Parser.ParseString(text); if (root == null) { Console.WriteLine("Error"); return; } // Генерация и получение трёхзначного кода var linearCode = new LinearCodeVisitor(); root.AcceptVisit(linearCode); var code = linearCode.code; // Get blocks and print it var blocks = LinearToBaseBlock.Build(code); foreach (var block in blocks) { Console.WriteLine(block.ToString()); } // Get graph and made DepthSpanningTree var cfg = new CFGraph(blocks); Console.WriteLine(cfg.ToString()); var exprsAnalizer = new AvailableExprAnalyzer(cfg); exprsAnalizer.analyze(); var dst = new DepthSpanningTree(cfg); string dst_viz = dst.ToString(); Console.WriteLine(dst_viz); Console.WriteLine(""); Console.WriteLine(cfg.EdgeTypes.ToString()); var f = cfg.allRetreatingEdgesAreBackwards(); var r = cfg.getNaturalCyclesForBackwardEdges(); var rs = new RegionSequence(cfg); Console.ReadLine(); }