Exemplo n.º 1
0
    public void Setup()
    {
        // identifiers.json holds sample tree constructed from V1 urls
        var identifiersJson = System.IO.File.ReadAllText("identifiers.json");
        var tree            = System.Text.Json.JsonSerializer.Deserialize <IDTree>(identifiersJson);

        idReplacer = new IdentifierReplacer(tree);
    }
Exemplo n.º 2
0
        public override void Process()
        {
            var movedBlocks = new HashSet<Block>();
            var stack = new Stack<IEnumerator<Block>>();
            stack.Push(new Block[] { Block }.Cast<Block>().GetEnumerator());
            var replacer = new IdentifierReplacer(ProcNew.Frame);
            while (stack.Count != 0)
            {
                DumpBlocks(Block.Procedure);
                var e = stack.Peek();
                if (!e.MoveNext())
                {
                    stack.Pop();
                    continue;
                }
                var b = e.Current;
                if (b.Procedure == ProcNew || b == b.Procedure.ExitBlock || b.Procedure.EntryBlock.Succ[0] == b)
                    continue;

                Debug.Print("PromoteBlock visiting block {0}", b.Name);
                b.Procedure.RemoveBlock(b);
                ProcNew.AddBlock(b);
                b.Procedure = ProcNew;
                movedBlocks.Add(b);
                foreach (var stm in b.Statements)
                {
                    stm.Instruction = replacer.ReplaceIdentifiers(stm.Instruction);
                }
                if (b.Succ.Count > 0)
                    stack.Push(b.Succ.GetEnumerator());
            }
            foreach (var b in movedBlocks)
            {
                FixExitEdges(b);
                FixInboundEdges(b);
                FixOutboundEdges(b);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Remove temporary assignment from the result. That is, removing
        /// assignment "t1 = x" where t1 is a temporary variable. This kind
        /// of assginment can be safely removed, but now all nodes that
        /// connect to "t1" should re-connect to "x". For example, "a = t1"
        /// now should be updated to "a = x".
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        public static NodeToCodeResult ConstantPropagationForTemp(NodeToCodeResult result, IEnumerable <string> outputVariables)
        {
            var tempVars = new HashSet <string>(
                result.OutputMap.Where(p => p.Key.StartsWith(Constants.kTempVarForNonAssignment))
                .Select(p => p.Value));

            var nonTempAsts     = new List <AssociativeNode>();
            var tempAssignments = new List <Tuple <IdentifierNode, AssociativeNode> >();

            foreach (var ast in result.AstNodes)
            {
                var expr = ast as BinaryExpressionNode;
                if (expr == null || expr.Optr != Operator.assign)
                {
                    nonTempAsts.Add(ast);
                    continue;
                }

                var lhs = expr.LeftNode as IdentifierNode;
                var rhs = expr.RightNode;
                if (lhs == null ||
                    !tempVars.Contains(lhs.Value) ||
                    outputVariables.Contains(lhs.Value) ||
                    !(rhs.IsLiteral || rhs is IdentifierNode))
                {
                    nonTempAsts.Add(ast);
                    continue;
                }

                IdentifierFinder finder       = new IdentifierFinder(lhs.Value, false);
                bool             isReferenced = result.AstNodes.Any(n => n.Accept(finder));

                bool isRhsDefined = false;
                if (rhs is IdentifierNode)
                {
                    var defFinder = new IdentifierFinder((rhs as IdentifierNode).Value, true);
                    isRhsDefined = result.AstNodes.Any(n => n.Accept(defFinder));
                }

                if (isReferenced || isRhsDefined)
                {
                    tempAssignments.Add(Tuple.Create(lhs, rhs));
                }
                else
                {
                    nonTempAsts.Add(ast);
                }
            }

            foreach (var pair in tempAssignments)
            {
                // Update the map.
                var keys = result.OutputMap.Keys.ToList();
                for (int i = 0; i < keys.Count; ++i)
                {
                    var value = result.OutputMap[keys[i]];
                    if (value.Equals(pair.Item1.Value))
                    {
                        var rhs = pair.Item2 as IdentifierNode;
                        if (rhs != null)
                        {
                            result.OutputMap[keys[i]] = rhs.Value;
                        }
                    }
                }

                // Update ASTs.
                IdentifierReplacer replacer = new IdentifierReplacer(pair.Item1.Value, pair.Item2);
                foreach (var ast in nonTempAsts)
                {
                    ast.Accept(replacer);
                }
            }

            return(new NodeToCodeResult(nonTempAsts, result.InputMap, result.OutputMap));
        }