Esempio n. 1
0
 private static void PropagateExpressions(CFGNode node, IDictionary <IVariable, IExpression> equalities)
 {
     foreach (var instruction in node.Instructions)
     {
         PropagateExpressions(instruction, equalities);
     }
 }
Esempio n. 2
0
            public AlternativeDependencyAnalyzer(CFGNode cfgNode, PointsToGraph ptg, AlternativeDependencyAnalysis depAnalysis)
            {
                this.cfgNode = cfgNode;
                this.ptg     = ptg;

                this.depAnalysis = depAnalysis;
            }
Esempio n. 3
0
        private void BFS_FinishVertex(CFGNode vertex)
        {
            IEnumerable <CFGEdge> edges = null;

            if (GraphControl.Graph.TryGetOutEdges(vertex, out edges))
            {
                if (edges.Count() > 0)
                {
                    foreach (var edge in edges)
                    {
                        currentSubtreeRoot.CollapsedSubtreeEdges.Add(edge);
                    }
                }
            }

            if (!currentSubtreeRoot.Equals(vertex))
            {
                if (vertex.IsSelected)
                {
                    vertex.Deselect();
                }
                vertex.IsCollapsed = true;
                currentSubtreeRoot.CollapsedSubtreeNodes.Add(vertex);
            }
        }
Esempio n. 4
0
        public override bool Match(CFGNode target)
        {
            IsMatched = false;
            MatchedNodes = new Tenpow.Collections.Generic.Set<CFGNode>();
            MatchedExpression = null;
            // TODO: Match a condition binaryExpression

            if (target.BasicBlock.Statements.Count < 1)
            {
                return false;
            }
            IAssignStatement assignStatement = target.BasicBlock.Statements[0] as IAssignStatement;
            if (assignStatement != null)
            {
                MatchedExpression = new AssignExpression(assignStatement.Target, assignStatement.Expression);
            }
            else
            {
                IExpressionStatement expressionStatement = target.BasicBlock.Statements[0] as IExpressionStatement;
                if (expressionStatement == null)
                {
                    return false;
                }
                MatchedExpression = expressionStatement.Expression;
            }
            MatchedNodes.Add(target);

            OnMatched(new CFGPatternMatch(MatchedNodes));
            IsMatched = true;
            return true;
        }
Esempio n. 5
0
 private void DecorateVertexBackground(CFGNode v)
 {
     if (GraphControl.GetVertexControl(v) != null)
     {
         GraphControl.GetVertexControl(v).Background = new SolidColorBrush(Converters.SevizColorToWpfColor(v.Color));
     }
 }
Esempio n. 6
0
 private void PropagateExpressions(CFGNode node)
 {
     foreach (var instruction in node.Instructions)
     {
         this.PropagateExpressions(instruction);
     }
 }
Esempio n. 7
0
        protected override VariableRangeDomain Flow(CFGNode node, VariableRangeDomain input)
        {
            var visitor = new RangeAnalysisVisitor(this, input);

            visitor.Visit(node);
            return(visitor.State);
        }
Esempio n. 8
0
        protected override HashSet <LabelValue> TransferFunc(CFGNode node)
        {
            var res = DefUse.UseLabels(node.Value);

            res.UnionWith(Out[node].Except(DefUse.DefLabels(node.Value)));
            return(res);
        }
        private IEnumerable <ProcedureCompilation> CompileDeclaration(IDeclaration declaration)
        {
            switch (declaration)
            {
            case NamespaceDeclaration decl:
                foreach (var compilation in decl.Declarations.SelectMany(CompileDeclaration))
                {
                    yield return(compilation);
                }
                break;

            case Procedure procedure:
                var(transformed, parameters) = Transformer.TransformProcedureStatement(procedure.EntryPoint, procedure.Parameters);

                var cfg = CFGNode.ConstructCFG(transformed);
                LivenessAnalysis.PerformAnalysis(cfg);
                var allocation = RegisterAllocation.Generate(cfg, parameters
                                                             .Select((x, i) => (x, i)).Where(x => x.i != 1).ToDictionary(
                                                                 x => x.x,
                                                                 x => ProcedureCompilation.ParameterLocation(x.i)));

                yield return(new ProcedureCompilation(procedure, parameters, transformed, ConstantTable, FalseConstant, TrueConstant, allocation));

                break;

            case ProcedureImport import:
                Externs.Add(import.Name);
                Imports.Add(import.ImportedName);
                break;
            }
        }
Esempio n. 10
0
        protected override HashSet <LabelValue> TransferFunc(CFGNode node)
        {
            var res = GenKill.GenLabels(node.Value);

            res.UnionWith(In[node].Except(GenKill.KillLabels(node.Value)));
            return(res);
        }
Esempio n. 11
0
        private void Propagate(CFGNode node, PathEdges pathEdge, LinkedList <CFGNode> workList)
        {
            PathEdges nodePaths;

            m_PathEdges.TryGetValue(node, out nodePaths);

            if (pathEdge != null)
            {
                List <PathEdgesPartition> newPaths = pathEdge.PathEdgesByLength;

                int index = 0;

                bool updated = false;
                while (index < newPaths.Count)
                {
                    if (nodePaths.AddPathEdge(newPaths[index], m_BddManager))
                    {
                        updated = true;
                        newPaths[index].PathEdges.UnfreeBdd();
                    }

                    index++;
                }

                if (updated)
                {
                    workList.AddLast(node);
                }
            }
        }
Esempio n. 12
0
        protected override IDictionary <IVariable, IExpression> Flow(CFGNode node, IDictionary <IVariable, IExpression> input)
        {
            IDictionary <IVariable, IExpression> result;

            if (input == null)
            {
                result = new Dictionary <IVariable, IExpression>();
            }
            else
            {
                result = new Dictionary <IVariable, IExpression>(input);
            }

            foreach (var instruction in node.Instructions)
            {
                var equality = this.Flow(instruction, result);

                foreach (var variable in instruction.ModifiedVariables)
                {
                    this.RemoveEqualitiesWithVariable(result, variable);
                }

                if (equality.HasValue)
                {
                    result.Add(equality.Value);
                }
            }

            return(result);
        }
Esempio n. 13
0
        protected override IteratorState Flow(CFGNode node, IteratorState input)
        {
            var oldInput = input.Clone();
            var visitor  = new MoveNextVisitorForItStateAnalysis(this, this.equalities, oldInput);

            visitor.Visit(node);
            return(visitor.State);
        }
Esempio n. 14
0
        public bool isDominate(CFGNode from, CFGNode to)
        {
            visited.Clear();
            var domNodeFrom = graph.Vertices.First(dtn => dtn.CFGNode.Equals(from));
            var domNodeTo   = graph.Vertices.First(dtn => dtn.CFGNode.Equals(to));

            return(isWayExists(domNodeFrom, domNodeTo));
        }
Esempio n. 15
0
 protected override SimplePointsToGraph InitialValue(CFGNode node)
 {
     if (this.cfg.Entry.Id == node.Id && this.initPTG != null)
     {
         return(this.initPTG);
     }
     return(this.initialGraph); // .Clone();
 }
Esempio n. 16
0
        protected override ConstantPropagationDomain Flow(CFGNode node, ConstantPropagationDomain input)
        {
            var nState  = input.Clone();
            var visitor = new ConstantPropagationTransferVisitor(nState, this);

            visitor.Visit(node);
            UpdateResults(visitor);
            return(visitor.State.Clone());
        }
Esempio n. 17
0
        /// <summary>
        /// Performs transfer function on a block represent by node.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        protected override ScopeEscapeDomain Flow(CFGNode node, ScopeEscapeDomain input)
        {
            var nState  = input.Clone();
            var visitor = new EscapeTransferVisitor(nState, this);

            visitor.Visit(node);
            UpdateResults(visitor);
            return(visitor.State.Clone());
        }
        protected override Subset <DefinitionInstruction> Flow(CFGNode node, Subset <DefinitionInstruction> input)
        {
            var output = input.Clone();
            var kill   = KILL[node.Id];
            var gen    = GEN[node.Id];

            output.Except(kill);
            output.Union(gen);
            return(output);
        }
Esempio n. 19
0
 protected override ScopeEscapeDomain InitialValue(CFGNode node)
 {
     if (unsupported)
     {
         return(ScopeEscapeDomain.Top(varsToTrack, fieldsToTrack.Select(f => f.Item1).ToList()));
     }
     else
     {
         return(ScopeEscapeDomain.Bottom(varsToTrack, fieldsToTrack.Select(f => f.Item1).ToList()));
     }
 }
Esempio n. 20
0
        protected override PointsToGraph Flow(CFGNode node, PointsToGraph input)
        {
            var ptg = input.Clone();

            foreach (var instruction in node.Instructions)
            {
                this.Flow(ptg, instruction);
            }

            return(ptg);
        }
Esempio n. 21
0
        private void ProcessBasicBlock(MethodBody body, CFGNode node, InstructionConverter translator)
        {
            if (node.Instructions.Count == 0)
            {
                return;
            }

            IInstruction firstInstruction = node.Instructions.First();

            //ProcessExceptionHandling(body, firstInstruction);

            translator.Visit(node);
        }
Esempio n. 22
0
        private void AddCycle(List <CFGNode> cycle, List <Edge <CFGNode> > edges, HashSet <CFGNode> nodes)
        {
            CFGNode                header          = cycle[0];
            List <CFGNode>         bodyNodes       = cycle.ToList();
            List <Edge <CFGNode> > allEdgesInCycle = edges.Where(e => { return(nodes.Contains(e.Source)); }).ToList();
            // Edges only for nodes into cycle
            List <Edge <CFGNode> > bodyEdgesInCycle = allEdgesInCycle.Where(e => { return(e.Target != header); }).ToList();
            BodyRegion             br = new BodyRegion(header, bodyNodes, bodyEdgesInCycle, NextName());
            LoopRegion             lr = new LoopRegion(header, bodyNodes, allEdgesInCycle, br, NextName());

            regions.Add(br);
            regions.Add(lr);
        }
Esempio n. 23
0
 protected override ConstantPropagationDomain InitialValue(CFGNode node)
 {
     if (unsupported)
     {
         return(ConstantPropagationDomain.Top(variables, fields.Select(f => f.Item1)));
     }
     else
     {
         var iv = ConstantPropagationDomain.Bottom(variables, fields.Select(f => f.Item1));
         //iv.SetFieldNonConstant();
         return(iv);
     }
 }
Esempio n. 24
0
        protected override VariableRangeDomain InitialValue(CFGNode node)
        {
            var res = new VariableRangeDomain();

            if (this.cfg.Entry.Id == node.Id)
            {
                if (this.initRange != null)
                {
                    return(this.initRange);
                }
            }
            return(res);
        }
        protected override IDictionary <IVariable, IVariable> Flow(CFGNode node, IDictionary <IVariable, IVariable> output)
        {
            var input = new Dictionary <IVariable, IVariable>(output);
            var kill  = KILL[node.Id];
            var gen   = GEN[node.Id];

            foreach (var variable in kill)
            {
                this.RemoveCopiesWithVariable(input, variable);
            }

            input.SetRange(gen);
            return(input);
        }
        public override bool Match(CFGNode node)
        {
            IsMatched = false;
            Patterns = new List<CostRestrictedStatementPattern>();
            MatchedNodes = new Tenpow.Collections.Generic.Set<CFGNode>();
            if (!PassesFilter(node))
            {
                return false;
            }
            int cost = 0;
            while (true)
            {
                CostRestrictedStatementPattern pattern = new CostRestrictedStatementPattern(CompileInfo);
                pattern.WorkingSet = WorkingSet;
                pattern.Matched += PatternMatched;
                pattern.MaxCost = MaxCost - cost;
                if (pattern.Match(node))
                {
                    cost += pattern.Cost;
                    Patterns.Add(pattern);

                    int topologicalOrder = -1;
                    // TODO: verify that last matched nodes are in topological order
                    foreach (CFGNode n in LastMatchedNodes)
                    {
                        if (CompileInfo.TopologicalOrder[n] > topologicalOrder)
                        {
                            topologicalOrder = CompileInfo.TopologicalOrder[n];
                        }
                    }
                    if (CompileInfo.TopologicalSort.Count == topologicalOrder + 1 || topologicalOrder == -1)
                    {
                        break;
                    }
                    node = CompileInfo.TopologicalSort[topologicalOrder + 1];
                    if (!PassesFilter(node))
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            OnMatched(new CFGPatternMatch(MatchedNodes));
            IsMatched = true;
            return true;
        }
Esempio n. 27
0
        private static string Serialize(CFGNode node)
        {
            string result;

            switch (node.Kind)
            {
            case CFGNodeKind.Entry: result = "entry"; break;

            case CFGNodeKind.Exit: result = "exit"; break;

            default: result = string.Join("\\l", node.Instructions) + "\\l"; break;
            }

            return(result);
        }
Esempio n. 28
0
        private Subset <IVariable> GetDerivedVariables(CFGNode successor, int successorIndex)
        {
            var result          = variables.ToEmptySubset();
            var phiInstructions = successor.Instructions.OfType <PhiInstruction>();

            foreach (var phi in phiInstructions)
            {
                var argument      = phi.Arguments[successorIndex];
                var argumentIndex = variablesIndex[argument];

                result.Add(argumentIndex);
            }

            return(result);
        }
Esempio n. 29
0
        protected override SimplePointsToGraph Flow(CFGNode node, SimplePointsToGraph input)
        {
            var ptg = input.Clone();

            var ptaVisitor = new PTAVisitor(ptg, this);

            ptaVisitor.Visit(node);

            //foreach (var instruction in node.Instructions)
            //{
            //    this.Flow(ptg, instruction as Instruction);
            //}

            return(ptaVisitor.State);
        }
Esempio n. 30
0
        private void MapNodesToSourceLinesBookmarks(CFGNode node)
        {
            var dte     = _parent.GetVsService(typeof(SDTE)) as EnvDTE.DTE;
            var fileUrl = node.SourceCodeMappingString.Split(':') [0] + ":" + node.SourceCodeMappingString.Split(':') [1];
            var line    = node.SourceCodeMappingString.Split(':') [2];
            var window  = dte.ItemOperations.OpenFile(fileUrl);

            if (window != null)
            {
                window.Activate();
                var selection = window.Selection as TextSelection;
                selection.GotoLine(int.Parse(line), true);
                var objectEditPoint = selection.ActivePoint.CreateEditPoint();
                objectEditPoint.SetBookmark();
            }
        }
Esempio n. 31
0
        private static CFGNode FindCommonAncestor(CFGNode a, CFGNode b)
        {
            while (a.ForwardIndex != b.ForwardIndex)
            {
                while (a.ForwardIndex > b.ForwardIndex)
                {
                    a = a.ImmediateDominator;
                }

                while (b.ForwardIndex > a.ForwardIndex)
                {
                    b = b.ImmediateDominator;
                }
            }

            return(a);
        }
Esempio n. 32
0
 public override bool Match(CFGNode target)
 {
     AnyExpressionPattern pattern = new AnyExpressionPattern(CompileInfo);
     pattern.Matched += new PatternMatchEventHandler<CFGPatternMatch>(pattern_Matched);
     if (!pattern.Match(target))
     {
         return false;
     }
     MatchedExpression = (IExpression)pattern.GenerateCode();
     if (MatchedExpression.Type.Equals(CoreTypes.Boolean))
     {
         return false;
     }
     OnMatched(new CFGPatternMatch(MatchedNodes));
     IsMatched = true;
     ExpressionPattern = pattern;
     return true;
 }
Esempio n. 33
0
        private static string Serialize(CFGNode node)
        {
            string result;

            switch (node.Kind)
            {
            case CFGNodeKind.Entry: result = "entry"; break;

            case CFGNodeKind.Exit: result = "exit"; break;

            default:
                result = string.Join(Environment.NewLine, node.Instructions);
                result = string.Format("Node ID: {0}{1}{2}", node.Id, Environment.NewLine, result);
                break;
            }

            return(result);
        }
Esempio n. 34
0
 public LoopTreeVertex AddVertex(CFGNode loopHeader)
 {
     LoopTreeVertex vertex = (LoopTreeVertex)AddVertex();
     vertex.Header = loopHeader;
     return vertex;
 }
Esempio n. 35
0
 private int CompareCFGNodesByTopologicalOrder(CFGNode a, CFGNode b)
 {
     return CompileInfo.TopologicalOrder[a].CompareTo(CompileInfo.TopologicalOrder[b]);
 }
Esempio n. 36
0
        public override bool Match(CFGNode target)
        {
            IsMatched = false;
            Condition.WorkingSet = WorkingSet;
            Condition.Matched += MatchedHandler;
            MatchedNodes = new Set<CFGNode>();
            if (!Condition.Match(target))
            {
                Condition.Matched -= MatchedHandler;
                return false;
            }
            Condition.Matched -= MatchedHandler;
            int topologicalOrder = -1;
            foreach (CFGNode node in MatchedNodes)
            {
                if (CompileInfo.TopologicalOrder[node] > topologicalOrder)
                {
                    topologicalOrder = CompileInfo.TopologicalOrder[node];
                }
            }
            if (CompileInfo.TopologicalSort.Count == topologicalOrder)
            {
                return false;
            }
            target = CompileInfo.TopologicalSort[topologicalOrder];

            if (target.Graph.OutDegree(target) != 2)
            {
                return false;
            }
            QuickGraph.Collections.EdgeCollection edges = target.Graph.OutEdges(target);
            CFGEdge edge1 = (CFGEdge)edges[0];
            CFGEdge edge2 = (CFGEdge)edges[1];
            if (CompileInfo.TopologicalOrder[edge1.Target] <= CompileInfo.TopologicalOrder[edge1.Source] ||
                CompileInfo.TopologicalOrder[edge2.Target] <= CompileInfo.TopologicalOrder[edge2.Source]
                )
            {
                return false;
            }
            CFGNode thenNode, elseNode;
            if (edge1.BranchCondition.Type == BranchConditionType.True)
            {
                thenNode = edge1.Target;
                if (edge2.BranchCondition.Type != BranchConditionType.False)
                {
                    return false;
                }
                elseNode = edge2.Target;
            }
            else if (edge2.BranchCondition.Type == BranchConditionType.True)
            {
                thenNode = edge2.Target;
                if (edge1.BranchCondition.Type != BranchConditionType.False)
                {
                    return false;
                }
                elseNode = edge1.Target;
            }
            else
            {
                return false;
            }
            if (!PassesFilter(thenNode) | !PassesFilter(elseNode))
            {
                return false;
            }

            Set<CFGNode> tcThen = Filter(CompileInfo.ForwardOnlyTransitiveClosure[thenNode]);
            Set<CFGNode> tcElse = Filter(CompileInfo.ForwardOnlyTransitiveClosure[elseNode]);
            Set<CFGNode> thenAndElseOnly = tcThen ^ tcElse;
            Set<CFGNode> sansThenAndElse = tcThen & tcElse;

            Set<CFGNode> thenSet = tcThen - sansThenAndElse;
            Set<CFGNode> elseSet = tcElse - sansThenAndElse;

            if (sansThenAndElse.Count != 0)
            {
                // next node after conditionstatement must dominate everything after it
                List<CFGNode> sansThenAndElseList = new List<CFGNode>(sansThenAndElse); // TODO: this algorithm could be better
                sansThenAndElseList.Sort(this.CompareCFGNodesByTopologicalOrder);
                if (sansThenAndElseList.Count > 1 && CompileInfo.TopologicalOrder[sansThenAndElseList[0]] >= CompileInfo.TopologicalOrder[sansThenAndElseList[1]])
                {
                    return false;
                }
            }

            // then node must dominate all nodes in thenSet
            foreach (CFGNode node in thenSet)
            {
                if (!CompileInfo.Dominators[node].Contains(thenNode))
                {
                    return false;
                }
            }
            thenSet.Add(thenNode);

            // same with else node and else set
            foreach (CFGNode node in elseSet)
            {
                if (!CompileInfo.Dominators[node].Contains(elseNode))
                {
                    return false;
                }
            }
            elseSet.Add(elseNode);

            this.Then.WorkingSet = thenSet;
            this.Else.WorkingSet = elseSet;

            this.Then.Matched += MatchedHandler;
            this.Else.Matched += MatchedHandler;

            if (this.Condition.Match(target) && this.Then.Match(thenNode) && this.Else.Match(elseNode))
            {
                this.Then.Matched -= MatchedHandler;
                this.Else.Matched -= MatchedHandler;
                this.Condition.Matched -= MatchedHandler;

                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;
                return true;
            }
            else
            {
                this.Then.Matched -= MatchedHandler;
                this.Else.Matched -= MatchedHandler;
                this.Condition.Matched -= MatchedHandler;
                return false;
            }
        }
        private CFGNode ProcessCFGNode(
            CFGNode calleeNode, CFGNode callerNode,
            CFGNode callerSuccessorNode,
            IExpression thisReplacement,
            IExpression returnValueTarget,
            MethodCompileInfo calleeMethodCompileInfo,
            MethodCompileInfo callerMethodCompileInfo,
            Dictionary<string, VariableDefinition> renamedLocalsMap,
            Dictionary<string, VariableReference> variableReplacements,
            Dictionary<string, IExpression> argumentReplacements,
            Dictionary<CFGNode, CFGNode> processedNodes,
            CFGNodeSet newNodes
            )
        {
            CFGNode inlinedNode;
            if (processedNodes.TryGetValue(calleeNode, out inlinedNode))
            {
                // we've already seen this node
                // don't inline it again otherwise we'll end up in an infinite recursion
                return inlinedNode;
            }

            CFG cfg = callerNode.Graph;
            inlinedNode = cfg.AddNode();
            inlinedNode.FlowControl = calleeNode.FlowControl;
            inlinedNode.BasicBlock = CodeUtility.CloneCode<BasicBlock>(calleeNode.BasicBlock);
            processedNodes[calleeNode] = inlinedNode;
            newNodes.Add(inlinedNode);
            Debug.Assert(
                inlinedNode.BasicBlock.Statements.Count == calleeNode.BasicBlock.Statements.Count,
                string.Format("Clone code produced {0} statements instead of {1}", inlinedNode.BasicBlock.Statements.Count, calleeNode.BasicBlock.Statements.Count)
            );

            // rename all variables in callee so they don't clash with variables in caller
            CodeUtility.MatchAndReplaceCode<IVariableReferenceExpression>(
                inlinedNode.BasicBlock,
                delegate(IVariableReferenceExpression expression)
                {
                    return true;
                },
                delegate(IVariableReferenceExpression expression)
                {
                    VariableReference variableReplacement;
                    if (!variableReplacements.TryGetValue(expression.Variable.Name, out variableReplacement))
                    {
                        if (callerMethodCompileInfo.IsTemporary(expression.Variable))
                        {
                            variableReplacement = callerMethodCompileInfo.NewTemporary(expression.Variable.VariableType);
                        }
                        else if (callerMethodCompileInfo.IsFrozen(expression.Variable))
                        {
                            variableReplacement = callerMethodCompileInfo.NewFrozen(expression.Variable.VariableType);
                        }
                        else
                        {
                            VariableDefinition variableDefinition;
                            if (!renamedLocalsMap.TryGetValue(expression.Variable.Name, out variableDefinition))
                            {
                                int index = callerMethodCompileInfo.Method.Body.Variables.Count;
                                string name = "V_" + index; // TODO: Extract into constant and helper method
                                TypeReference type = expression.Variable.VariableType;
                                variableDefinition = new VariableDefinition(name, index, callerMethodCompileInfo.Method, type);
                                callerMethodCompileInfo.Method.Body.Variables.Add(variableDefinition);
                                renamedLocalsMap[expression.Variable.Name] = variableDefinition;
                            }
                            variableReplacement = variableDefinition;
                        }
                        variableReplacements[expression.Variable.Name] = variableReplacement;
                    }
                    expression.Variable = variableReplacement;
                    return expression;
                },
                true
            );

            // replace all instances of "this" in callee with the target object
            if (thisReplacement != null)
            {
                CodeUtility.MatchAndReplaceCode<IExpression>(
                    inlinedNode.BasicBlock,
                    delegate(IExpression expression)
                    {
                        return expression is IThisReferenceExpression;
                    },
                    delegate(IExpression expression)
                    {
                        return thisReplacement;
                    },
                    true
                );
            }

            // replace all arguments references
            if (argumentReplacements != null)
            {
                CodeUtility.MatchAndReplaceCode<IExpression>(
                    inlinedNode.BasicBlock,
                    delegate(IExpression expression)
                    {
                        return expression is IArgumentReferenceExpression;
                    },
                    delegate(IExpression expression)
                    {
                        IArgumentReferenceExpression argumentReferenceExpression = (IArgumentReferenceExpression)expression;
                        IExpression replacementExpression;
                        if (!argumentReplacements.TryGetValue(argumentReferenceExpression.Parameter.Name, out replacementExpression))
                        {
                            throw new CompilerException(
                                string.Format(
                                    "Error while inlining call to {0}. Could not find argument replacement for parameter \"{1}\". Parameter sequence is {2}.",
                                    calleeMethodCompileInfo.Method,
                                    argumentReferenceExpression.Parameter.Name,
                                    argumentReferenceExpression.Parameter.Sequence
                                )
                            );
                        }
                        else
                        {
                            return replacementExpression;
                        }
                    },
                    true
                );
            }

            if (inlinedNode.FlowControl == FlowControl.Throw)
            {
                // TODO: fixup exception handling info
                throw new CannotInlineMethodException("Contain throw statement");
            }
            else if (inlinedNode.FlowControl == FlowControl.ConditionalBranch)
            {
                // TODO: Fix this so that conditioanl branches can be inlined
                throw new CannotInlineMethodException("Contains a conditional branch");
            }
            else if (inlinedNode.FlowControl == FlowControl.Return)
            {
                // replace return statement with assignment to variable being assigned to in caller
                Debug.Assert(inlinedNode.BasicBlock.Statements.Count == 1, string.Format("Return basic block has {0} statements", inlinedNode.BasicBlock.Statements.Count));
                Debug.Assert(inlinedNode.BasicBlock.Statements[0] is IMethodReturnStatement);
                IMethodReturnStatement methodReturnStatement = (IMethodReturnStatement)inlinedNode.BasicBlock.Statements[0];

                inlinedNode.BasicBlock.Statements.Clear();
                inlinedNode.BasicBlock.Statements.Add(new AssignStatement(returnValueTarget, methodReturnStatement.Expression));

                // add edge between this return node and the caller node's successor
                Debug.Assert(inlinedNode.SuccessorCount == 0);
                Debug.Assert(callerSuccessorNode != null);
                cfg.AddEdge(inlinedNode, callerSuccessorNode);

                // flow control is no longer return
                inlinedNode.FlowControl = FlowControl.Next;
            }

            foreach (CFGEdge outEdge in calleeNode.Graph.OutEdges(calleeNode))
            {
                CFGNode newSuccessorNode = ProcessCFGNode(
                    outEdge.Target, callerNode, callerSuccessorNode,
                    thisReplacement, returnValueTarget,
                    calleeMethodCompileInfo, callerMethodCompileInfo,
                    renamedLocalsMap,
                    variableReplacements,
                    argumentReplacements,
                    processedNodes,
                    newNodes
                );
                cfg.AddEdge(inlinedNode, newSuccessorNode, outEdge.BranchCondition);
            }

            return inlinedNode;
        }
Esempio n. 38
0
 private CFGEdge AddEdge(CFGNode source, CFGNode target)
 {
     return _cfg.AddEdge(source, target);
 }
Esempio n. 39
0
        public override bool Match(CFGNode target)
        {
            Condition.WorkingSet = WorkingSet;
            Condition.Matched += MatchedHandler;
            MatchedNodes = new Set<CFGNode>();
            if (!Condition.Match(target))
            {
                Condition.Matched -= MatchedHandler;
                return false;
            }
            Condition.Matched -= MatchedHandler;
            int topologicalOrder = -1;
            foreach (CFGNode node in MatchedNodes)
            {
                if (CompileInfo.TopologicalOrder[node] > topologicalOrder)
                {
                    topologicalOrder = CompileInfo.TopologicalOrder[node];
                }
            }
            if (CompileInfo.TopologicalSort.Count == topologicalOrder)
            {
                return false;
            }
            target = CompileInfo.TopologicalSort[topologicalOrder];

            LoopTreeVertex loopTreeVertex = null;
            if (!CompileInfo.Loop.TryGetValue(target, out loopTreeVertex))
            {
                return false;
            }
            if (target.Graph.OutDegree(target) != 2) // TODO: Always 2 successors?
            {
                return false;
            }

            QuickGraph.Collections.EdgeCollection edges = target.Graph.OutEdges(target);
            CFGEdge edge1 = (CFGEdge)edges[0];
            CFGEdge edge2 = (CFGEdge)edges[1];
            CFGNode thenNode, elseNode;
            if (edge1.BranchCondition.Type == BranchConditionType.True)
            {
                thenNode = edge1.Target;
                if (edge2.BranchCondition.Type != BranchConditionType.False)
                {
                    return false;
                }
                elseNode = edge2.Target;
            }
            else if (edge2.BranchCondition.Type == BranchConditionType.True)
            {
                thenNode = edge2.Target;
                if (edge1.BranchCondition.Type != BranchConditionType.False)
                {
                    return false;
                }
                elseNode = edge1.Target;
            }
            else
            {
                return false;
            }
            if (!PassesFilter(thenNode)) // only then node needs to be in working set
            {
                return false;
            }

            // find loop end deepest
            CFGNode loopEnd = loopTreeVertex.Ends[loopTreeVertex.Ends.Count - 1];
            while (CompileInfo.Loop.TryGetValue(loopEnd, out loopTreeVertex))
            {
                loopEnd = loopTreeVertex.Ends[loopTreeVertex.Ends.Count - 1];
            }

            // body is all nodes between header and end node in topological sort (including end node)
            Set<CFGNode> bodySet = new Set<CFGNode>();
            CFGNode firstBodyNode = null;
            for (int i = CompileInfo.TopologicalOrder[thenNode]; i <= CompileInfo.TopologicalOrder[loopEnd]; i++)
            {
                if (PassesFilter(CompileInfo.TopologicalSort[i]))
                {
                    if (firstBodyNode == null)
                    {
                        firstBodyNode = CompileInfo.TopologicalSort[i];
                    }
                    bodySet.Add(CompileInfo.TopologicalSort[i]);
                }
            }

            PatternMatchEventHandler<CFGPatternMatch> bodyMatchedHandler = MatchedHandler;

            this.Body.WorkingSet = bodySet;

            this.Body.Matched += bodyMatchedHandler;

            if (this.Body.Match(firstBodyNode))
            {
                this.Body.Matched -= MatchedHandler;

                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;

                return true;
            }
            else
            {
                this.Body.Matched -= MatchedHandler;
                return false;
            }
        }
Esempio n. 40
0
        public override bool Match(CFGNode target)
        {
            IsMatched = false;
            Expression.WorkingSet = WorkingSet;
            Expression.Matched += MatchedHandler;
            MatchedNodes = new Set<CFGNode>();
            if (!Expression.Match(target))
            {
                Expression.Matched -= MatchedHandler;
                return false;
            }
            Expression.Matched -= MatchedHandler;
            int topologicalOrder = -1;
            foreach (CFGNode node in MatchedNodes)
            {
                if (CompileInfo.TopologicalOrder[node] > topologicalOrder)
                {
                    topologicalOrder = CompileInfo.TopologicalOrder[node];
                }
            }
            if (CompileInfo.TopologicalSort.Count == topologicalOrder)
            {
                return false;
            }
            target = CompileInfo.TopologicalSort[topologicalOrder];

            if(target.Graph.OutDegree(target) < 2){
                return false;
            }
            if (target.FlowControl != FlowControl.ConditionalBranch)
            {
                return false;
            }
            Set<CFGNode> firstCaseNodes = new Set<CFGNode>();
            SwitchConditions = new List<IExpression>();
            foreach (CFGEdge edge in target.Graph.OutEdges(target))
            {
                if (edge.BranchCondition.Type == BranchConditionType.SwitchCaseDefault)
                {
                    SwitchConditions.Add(null);
                    firstCaseNodes.Add(edge.Target);
                }
                else if (edge.BranchCondition.Type == BranchConditionType.SwitchCaseCondition)
                {
                    SwitchConditions.Add((IExpression)edge.BranchCondition.Data);
                    firstCaseNodes.Add(edge.Target);
                }
                else if(edge.BranchCondition.Type != BranchConditionType.SwitchFallThrough)
                {
                    return false;
                }
            }

            List<Set<CFGNode>> switchCaseTcs = new List<Set<CFGNode>>();
            foreach (CFGNode node in firstCaseNodes)
            {
                switchCaseTcs.Add(CompileInfo.ForwardOnlyTransitiveClosure[node]);
            }
            Set<CFGNode> afterSwitchSet = switchCaseTcs[0];
            for (int i = 1; i < switchCaseTcs.Count; i++)
            {
                afterSwitchSet &= switchCaseTcs[i];
            }
            SwitchCases = new List<BlockStatementPattern>();
            for (int i = 0; i < switchCaseTcs.Count; i++)
            {
                Set<CFGNode> switchCaseSet = switchCaseTcs[i];
                switchCaseSet.Add(firstCaseNodes[i]);
                for (int j = 0; j < switchCaseTcs.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    switchCaseSet -= switchCaseTcs[j];
                }
                switchCaseSet -= afterSwitchSet;
                CostRestrictedBlockStatementPattern pattern = new CostRestrictedBlockStatementPattern(CompileInfo);
                pattern.Matched += MatchedHandler;
                pattern.WorkingSet = switchCaseSet;
                if (!pattern.Match(firstCaseNodes[i]))
                {
                    pattern.Matched -= MatchedHandler;
                    return false;
                }
                pattern.Matched -= MatchedHandler;
                SwitchCases.Add(pattern);
            }

            OnMatched(new CFGPatternMatch(MatchedNodes));
            IsMatched = true;
            return true;
        }
Esempio n. 41
0
 public CFGPatternMatch(CFGNode node)
     : this(new Set<CFGNode>(node))
 {
 }
        public override bool Match(CFGNode target)
        {
            IsMatched = false;

            DoStatementPattern.WorkingSet = WorkingSet;
            if (DoStatementPattern.Match(target) && DoStatementPattern.Cost < MaxCost)
            {
                StatementPattern = DoStatementPattern;
                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;
                return true;
            }

            WhileStatementPattern.WorkingSet = WorkingSet;
            if (WhileStatementPattern.Match(target) && WhileStatementPattern.Cost < MaxCost)
            {
                StatementPattern = WhileStatementPattern;
                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;
                return true;
            }

            SwitchStatementPattern.WorkingSet = WorkingSet;
            if (SwitchStatementPattern.Match(target) && SwitchStatementPattern.Cost < MaxCost)
            {
                StatementPattern = SwitchStatementPattern;
                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;
                return true;
            }

            ConditionStatementPattern.WorkingSet = WorkingSet;
            if (ConditionStatementPattern.Match(target) && ConditionStatementPattern.Cost < MaxCost)
            {
                StatementPattern = ConditionStatementPattern;
                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;
                return true;
            }

            if (target.BasicBlock.Statements.Count > 0)
            {
                if ((target.FlowControl != FlowControl.Branch && target.FlowControl != FlowControl.ConditionalBranch))
                {
                    IStatement statement = target.BasicBlock.Statements[0] as IStatement;
                    if (statement != null)
                    {
                        StatementPattern = null;
                        _cost = 1;
                        MatchedStatement = statement;
                        OnMatched(new CFGPatternMatch(target));
                        IsMatched = true;
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else
            {
                StatementPattern = null;
                _cost = 0;
                MatchedStatement = new NopStatement();
                OnMatched(new CFGPatternMatch(target));
                IsMatched = true;
                return true;
            }

            return false;
        }
Esempio n. 43
0
        public override bool Match(CFGNode target)
        {
            IsMatched = false;
            MatchedNodes = new Set<CFGNode>();
            LoopTreeVertex loopTreeVertex = null;
            if (!CompileInfo.Loop.TryGetValue(target, out loopTreeVertex))
            {
                return false;
            }

            // find loop end
            CFGNode loopEnd = loopTreeVertex.Ends[loopTreeVertex.Ends.Count - 1];
            if (!PassesFilter(loopEnd))
            {
                return false;
            }
            if (target.Graph.OutDegree(loopEnd) != 2) // TODO: Always 2 successors?
            {
                return false;
            }

            QuickGraph.Collections.EdgeCollection edges = target.Graph.OutEdges(loopEnd);
            CFGEdge edge1 = (CFGEdge)edges[0];
            CFGEdge edge2 = (CFGEdge)edges[1];
            CFGNode thenNode, elseNode;
            if (edge1.BranchCondition.Type == BranchConditionType.True && CompileInfo.TopologicalOrder[edge1.Target] < CompileInfo.TopologicalOrder[edge1.Source])
            {
                thenNode = edge1.Target;
                if (edge2.BranchCondition.Type != BranchConditionType.False || CompileInfo.TopologicalOrder[edge2.Target] < CompileInfo.TopologicalOrder[edge2.Source])
                {
                    return false;
                }
                elseNode = edge2.Target;
            }
            else if (edge2.BranchCondition.Type == BranchConditionType.True && CompileInfo.TopologicalOrder[edge2.Target] < CompileInfo.TopologicalOrder[edge2.Source])
            {
                thenNode = edge2.Target;
                if (edge1.BranchCondition.Type != BranchConditionType.False || CompileInfo.TopologicalOrder[edge1.Target] < CompileInfo.TopologicalOrder[edge1.Source])
                {
                    return false;
                }
                elseNode = edge1.Target;
            }
            else
            {
                return false;
            }
            if (!PassesFilter(thenNode) | !PassesFilter(elseNode))
            {
                return false;
            }

            // body is all nodes between header and end node in topological sort (including end node)
            Set<CFGNode> bodySet = new Set<CFGNode>();
            CFGNode firstBodyNode = target;
            for (int i = CompileInfo.TopologicalOrder[target]; i < CompileInfo.TopologicalOrder[loopEnd]; i++)
            {
                if (PassesFilter(CompileInfo.TopologicalSort[i]))
                {
                    bodySet.Add(CompileInfo.TopologicalSort[i]);
                }
            }

            PatternMatchEventHandler<CFGPatternMatch> bodyMatchedHandler = MatchedHandler;

            this.Body.WorkingSet = bodySet;
            this.Body.Matched += bodyMatchedHandler;

            if (this.Body.Match(firstBodyNode))
            {
                this.Body.Matched -= MatchedHandler;

                Condition.WorkingSet = new Set<CFGNode>(loopEnd);
                Condition.Matched += MatchedHandler;
                if (!Condition.Match(loopEnd))
                {
                    Condition.Matched -= MatchedHandler;
                    return false;
                }
                Condition.Matched -= MatchedHandler;

                OnMatched(new CFGPatternMatch(MatchedNodes));
                IsMatched = true;

                return true;
            }
            else
            {
                this.Body.Matched -= MatchedHandler;
                return false;
            }
        }