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); } }
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(); }
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(); }
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; }
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; }
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); }
/// <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>(); }
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); }
/// <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; }