Exemple #1
0
        private static void BackwardDFS(CFG cdfg,
                                        ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> cfgQueries,
                                        Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > > surroundingLoops,
                                        HashSet <EnhancedBasicBlock <Instruction> > visitedBlocks,
                                        EnhancedBasicBlock <Instruction> block,
                                        EnhancedBasicBlock <Instruction> loopHead)
        {
            if (visitedBlocks.Contains(block))
            {
                return;
            }
            visitedBlocks.Add(block);
            List <EnhancedBasicBlock <Instruction> > loops;

            if (!surroundingLoops.TryGetValue(block, out loops))
            {
                loops = new List <EnhancedBasicBlock <Instruction> >();
                surroundingLoops.Add(block, loops);
            }
            surroundingLoops[block].Add(loopHead);
            if (block == loopHead)
            {
                return;
            }

            var predecessors = cfgQueries.PredeccessorsFor(block);

            //Console.WriteLine("{0:X}, Predecessors: {1}", block.Offset, Offsets(predecessors));
            foreach (var p in predecessors)
            {
                BackwardDFS(cdfg, cfgQueries, surroundingLoops, visitedBlocks, p, loopHead);
            }
        }
Exemple #2
0
        public override void Traverse(IMethodBody methodBody)
        {
            sourceEmitterOutput.WriteLine("");
            this.sourceEmitterOutput.WriteLine(MemberHelper.GetMethodSignature(methodBody.MethodDefinition,
                                                                               NameFormattingOptions.Signature | NameFormattingOptions.ReturnType | NameFormattingOptions.ParameterModifiers | NameFormattingOptions.ParameterName));
            sourceEmitterOutput.WriteLine("");
            if (this.pdbReader != null)
            {
                PrintScopes(methodBody);
            }
            else
            {
                PrintLocals(methodBody.LocalVariables);
            }

            this.cdfg = ControlAndDataFlowGraph <AiBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);

            this.cfgQueries = new ControlGraphQueries <AiBasicBlock <Instruction>, Instruction>(this.cdfg);
            SingleAssigner <AiBasicBlock <Instruction>, Instruction> .GetInSingleAssignmentForm(host.NameTable, this.cdfg, this.cfgQueries, this.pdbReader);

            this.valueMappings = new ValueMappings <Instruction>(this.host.PlatformType, new Z3Wrapper.Wrapper(host.PlatformType));
            AbstractInterpreter <AiBasicBlock <Instruction>, Instruction> .InterpretUsingAbstractValues(this.cdfg, this.cfgQueries, this.valueMappings);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.PrintBlock(block);
            }

            sourceEmitterOutput.WriteLine("**************************************************************");
            sourceEmitterOutput.WriteLine();
        }
Exemple #3
0
        private static void ForwardDFS(CFG cdfg,
                                       ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> cfgQueries,
                                       HashSet <EnhancedBasicBlock <Instruction> > currentPath,
                                       HashSet <EnhancedBasicBlock <Instruction> > visitedBlocks,
                                       Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > > surroundingLoops,
                                       EnhancedBasicBlock <Instruction> block)
        {
            if (visitedBlocks.Contains(block))
            {
                return;
            }
            visitedBlocks.Add(block);
            currentPath.Add(block);
            var successors = cdfg.SuccessorsFor(block);

            //Console.WriteLine("{0:X}, Successors: {1}", block.Offset, Offsets(successors));
            foreach (var s in successors)
            {
                if (currentPath.Contains(s))
                {
                    // backedge from block to s
                    //WriteBlockOffset(s, 1);
                    if (!cfgQueries.Dominates(s, block))
                    {
                        throw new NotReducibleFlowGraph();
                    }
                    BackwardDFS(cdfg, cfgQueries, surroundingLoops, new HashSet <EnhancedBasicBlock <Instruction> >(), block, s);
                }
                else
                {
                    ForwardDFS(cdfg, cfgQueries, currentPath, visitedBlocks, surroundingLoops, s);
                }
            }
            currentPath.Remove(block);
        }
    public override void Traverse(IMethodBody methodBody) {
      sourceEmitterOutput.WriteLine("");
      this.sourceEmitterOutput.WriteLine(MemberHelper.GetMethodSignature(methodBody.MethodDefinition,
        NameFormattingOptions.Signature|NameFormattingOptions.ReturnType|NameFormattingOptions.ParameterModifiers|NameFormattingOptions.ParameterName));
      sourceEmitterOutput.WriteLine("");
      if (this.pdbReader != null)
        PrintScopes(methodBody);
      else
        PrintLocals(methodBody.LocalVariables);

      this.cdfg = ControlAndDataFlowGraph<AiBasicBlock<Instruction>, Instruction>.GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);
      this.cfgQueries = new ControlGraphQueries<AiBasicBlock<Instruction>, Instruction>(this.cdfg);
      SingleAssigner<AiBasicBlock<Instruction>, Instruction>.GetInSingleAssignmentForm(host.NameTable, this.cdfg, this.cfgQueries, this.pdbReader);
      this.valueMappings = new ValueMappings<Instruction>(this.host.PlatformType, new Z3Wrapper.Wrapper(host.PlatformType));
      AbstractInterpreter<AiBasicBlock<Instruction>, Instruction>.InterpretUsingAbstractValues(this.cdfg, this.cfgQueries, this.valueMappings);

      var numberOfBlocks = this.cdfg.BlockFor.Count;

      foreach (var block in this.cdfg.AllBlocks) {
        this.PrintBlock(block);
      }

      sourceEmitterOutput.WriteLine("**************************************************************");
      sourceEmitterOutput.WriteLine();
    }
Exemple #5
0
        public override void Visit(IMethodBody methodBody)
        {
            Console.WriteLine();
            Console.WriteLine("==========================");
            Console.WriteLine("{0}", MemberHelper.GetMemberSignature(methodBody.MethodDefinition, NameFormattingOptions.DocumentationId));

            var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader);

            var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);

            var numberOfBlocks = cdfg.BlockFor.Count;

            Console.WriteLine("# blocks: {0}", numberOfBlocks);
            Console.WriteLine("CFG");
            foreach (var block in cdfg.AllBlocks)
            {
                Console.WriteLine("{0:X}, Successors: {1}", block.Offset, Offsets(cdfg.SuccessorsFor(block)));
            }

            Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > > dominators = new Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > >();

            foreach (var b in cdfg.AllBlocks)
            {
                var dom = new List <EnhancedBasicBlock <Instruction> >();
                foreach (var c in cdfg.AllBlocks)
                {
                    if (cfgQueries.Dominates(c, b))
                    {
                        dom.Add(c);
                    }
                }
                dominators.Add(b, dom);
            }

            var surroundingLoops = LoopFinder.GetLoopInformation(cdfg, cfgQueries, methodBody);

            Console.WriteLine("\nLoop information");
            foreach (var b in cdfg.AllBlocks)
            {
                List <EnhancedBasicBlock <Instruction> > loops;
                if (surroundingLoops.TryGetValue(b, out loops))
                {
                    Console.WriteLine("{0:X}: ({1} loop{3}) {2}",
                                      b.Offset,
                                      loops.Count(),
                                      String.Join(",", loops.Select(l => String.Format("{0:X}", l.Offset))),
                                      loops.Count() > 1 ? "s" : ""
                                      );
                }
                else
                {
                    //Console.WriteLine("{0:X} is not contained in a loop", b.Offset);
                }
            }

            return;
        }
Exemple #6
0
        public override void Visit(IMethodBody methodBody)
        {
            var method = methodBody.MethodDefinition;

            this.currentMethod = method;
            if (methodBody.Operations != null)
            {
                var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader);

                var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);
                this.FindObjectSourcesWithoutSinks(method, cdfg);
            }


            return;
        }
Exemple #7
0
        GetLoopInformation(
            CFG cdfg,
            ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> cfgQueries,
            IMethodBody methodBody)
        {
            var surroundingLoops = new Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > >();

            try
            {
                ForwardDFS(cdfg, cfgQueries, new HashSet <EnhancedBasicBlock <Instruction> >(), new HashSet <EnhancedBasicBlock <Instruction> >(), surroundingLoops, cdfg.RootBlocks.First());
            }
            catch (NotReducibleFlowGraph)
            {
                return(new Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > >());
            }
            return(surroundingLoops);
        }
Exemple #8
0
        /// <summary>
        /// Changes a control flow graph from SSA form to a version where the SSA variables are unified into the smallest number of locals.
        /// This is somewhat like register allocation where the number of registers can grow as large as needed, but registers are typed.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="cdfg"></param>
        /// <param name="cfgQueries"></param>
        public MultipleAssigner(IMetadataHost host, ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ControlGraphQueries <BasicBlock, Instruction> cfgQueries)
        {
            Contract.Requires(host != null);
            Contract.Requires(cdfg != null);
            Contract.Requires(cfgQueries != null);

            this.host               = host;
            this.cdfg               = cdfg;
            this.cfgQueries         = cfgQueries;
            this.unifiedLocalFor    = new Hashtable <object, GeneratorLocal>();
            this.availableLocalsFor = new MultiHashtable <GeneratorLocal>();
        }
Exemple #9
0
        public bool AnalyzeMethods()
        {
            foreach (INamedTypeDefinition t in PrimaryModule.GetAllTypes())
            {
                if (t.IsClass && t.Methods.Count() > 0 && !t.Name.Value.StartsWith("<"))
                {
                    Environment.Message("Class {0} has {1} members, {2} methods.", t.Name.Value, t.Members.Count(), t.Methods.Count());
                    List <IMethodDefinition> methods = t.Methods.ToList();
                    foreach (IMethodDefinition m in methods)
                    {
                        ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(MetadataReaderHost, m.Body);

                        ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> query = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);

                        Environment.Message("  Method {0} has visibility {3}, {1} parameters, {2} local variables in body, {4} total basic blocks or nodes and {5} successor edges in CFG.\n", m.Name.Value, m.ParameterCount,
                                            m.Body.LocalVariables.Count(), m.Visibility.ToString(), cdfg.AllBlocks.Count,
                                            cdfg.SuccessorEdges.Count);
                    }
                }
            }
            return(true);
        }
Exemple #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="host"></param>
        /// <param name="cdfg"></param>
        /// <param name="cfgQueries"></param>
        /// <param name="localScopeProvider"></param>
        /// <param name="sourceLocationProvider"></param>
        public LocalMinimizer(IMetadataHost host,
                              ControlAndDataFlowGraph <BasicBlock, Instruction> cdfg, ControlGraphQueries <BasicBlock, Instruction> cfgQueries,
                              ILocalScopeProvider /*?*/ localScopeProvider, ISourceLocationProvider /*?*/ sourceLocationProvider)
        {
            Contract.Requires(host != null);
            Contract.Requires(cdfg != null);
            Contract.Requires(cfgQueries != null);

            this.host = host;
            this.localScopeProvider     = localScopeProvider;
            this.sourceLocationProvider = sourceLocationProvider;
            this.cdfg       = cdfg;
            this.cfgQueries = cfgQueries;
        }