示例#1
0
 public static TransferFunction <ConstPropBlockInfo> TransferFunction()
 => new TransferFunction <ConstPropBlockInfo>(bi =>
 {
     var m = bi.IN.ToDictionary(e => e.Key);
     foreach (var command in bi.Commands)
     {
         if (command.operation == ThreeOperator.Goto ||
             command.operation == ThreeOperator.IfGoto ||
             command.operation == ThreeOperator.None ||
             command.operation == ThreeOperator.Println ||
             command.arg1 is ThreeAddressLogicValue ||
             command.arg1 is ThreeAddressDoubleValue ||
             command.arg2 is ThreeAddressLogicValue ||
             command.arg2 is ThreeAddressDoubleValue)
         {
             continue;
         }
         if (command.operation == ThreeOperator.Assign)
         {
             m[command.result] = new ConstPropKeyValue(command.result,
                                                       GetSemilatticeEl(command.arg1, m));
         }
         else
         {
             var el1 = GetSemilatticeEl(command.arg1, m);
             var el2 = GetSemilatticeEl(command.arg2, m);
             if (el1.Constantness == ValConstType.Const &&
                 el2.Constantness == ValConstType.Const)
             {
                 m[command.result] = new ConstPropKeyValue(command.result,
                                                           new ConstPropSemilatticeEl(ValConstType.Const,
                                                                                      EvalConst(el1.Value, el2.Value, command.operation)));
             }
             else if (el1.Constantness == ValConstType.NAC ||
                      el2.Constantness == ValConstType.NAC)
             {
                 m[command.result] = new ConstPropKeyValue(command.result,
                                                           new ConstPropSemilatticeEl(ValConstType.NAC));
             }
             else
             {
                 m[command.result] = new ConstPropKeyValue(command.result,
                                                           new ConstPropSemilatticeEl(ValConstType.Undef));
             }
         }
     }
     var Out = new ConstPropBlockInfo(bi);
     Out.OUT = new HashSet <ConstPropKeyValue>(m.Values);
     return(Out);
 });
        public void IterativeAlgorithm(List <LinkedList <ThreeCode> > blocks)
        {
            // построение CFG по блокам
            controlFlowGraph = new CFG(blocks.ToList());
            // создание информации о блоках
            var blocksInfo = new List <ConstPropBlockInfo>();
            var m          = new Dictionary <string, ConstPropSemilatticeEl>();

            for (int i = 0; i < blocks.Count; i++)
            {
                foreach (var c in blocks[i].Where(com =>
                                                  com.operation != ThreeOperator.Goto && com.operation != ThreeOperator.IfGoto))
                {
                    string[] vars = new string[]
                    { c.result
                      , (c.arg1 as ThreeAddressStringValue)?.Value
                      , (c.arg2 as ThreeAddressStringValue)?.Value };

                    foreach (var v in vars)
                    {
                        if (v != null && v != "" && !m.ContainsKey(v))
                        {
                            m[v] = new ConstPropSemilatticeEl(ValConstType.Undef);
                        }
                    }
                }
            }
            for (int i = 0; i < blocks.Count; i++)
            {
                blocksInfo.Add(new ConstPropBlockInfo(blocks[i]));
            }

            // оператор сбора в задаче о распространении констант
            Func <List <ConstPropBlockInfo>, CFG, int, ConstPropBlockInfo> meetOperator =
                (blocksInfos, graph, index) =>
            {
                var inputIndexes = graph.cfg.GetInputNodes(index);
                var resInfo      = new ConstPropBlockInfo(blocksInfos[index]);
                foreach (var i in inputIndexes)
                {
                    var resIn = resInfo.IN.ToDictionary(e => e.Key);
                    foreach (var Out in blocksInfos[i].OUT)
                    {
                        if (resIn[Out.Key].Value.Constantness == ValConstType.Undef)
                        {
                            resIn[Out.Key] = new ConstPropKeyValue(Out.Key, Out.Value);
                        }
                        else if (resIn[Out.Key].Value.Constantness == ValConstType.NAC ||
                                 Out.Value.Constantness == ValConstType.NAC ||
                                 (resIn[Out.Key].Value.Constantness == ValConstType.Const &&
                                  Out.Value.Constantness == ValConstType.Const &&
                                  resIn[Out.Key].Value.Value != Out.Value.Value))
                        {
                            resIn[Out.Key] = new ConstPropKeyValue(Out.Key,
                                                                   new ConstPropSemilatticeEl(ValConstType.NAC));
                        }
                    }

                    resInfo.IN = new HashSet <ConstPropKeyValue>(resIn.Values);
                }
                return(resInfo);
            };

            var transferFunction = TransferFunction();

            // создание объекта итерационного алгоритма
            var iterativeAlgorithm = new IterativeAlgorithm <ConstPropKeyValue>(blocksInfo,
                                                                                controlFlowGraph, meetOperator, true, new HashSet <ConstPropKeyValue>(m),
                                                                                new HashSet <ConstPropKeyValue>(m), transferFunction);

            // выполнение алгоритма
            iterativeAlgorithm.Perform();
            Ins = iterativeAlgorithm.GetINs();
        }