void AnalyseAssignment(Variable variable, List <Tuple <IRegion, Expr> > defs, Graph <Block> cfg, HashSet <Variable> modSet) { // Ensure defs[0] refers to the definition from the outermost region // This also checks that the definitions are in different regions if (!OrderDefs(defs, cfg)) { return; } var regionId = defs[1].Item1.Identifier(); var varDefAnalysis = verifier.varDefAnalysesRegion[impl]; var varDef = varDefAnalysis.GetPossibleInductionVariableDefintion(variable.Name, regionId); if (varDef == null) { return; } HashSet <string> loopFreeVars; var defInd = varDefAnalysis.SubstDefinitions(varDef, impl.Name, out loopFreeVars); if (loopFreeVars.Any(i => i != variable.Name)) { return; } var modSetLoop = LoopInvariantGenerator.GetModifiedVariables(defs[1].Item1); var v = new VariablesOccurringInExpressionVisitor(); v.Visit(defs[0].Item2); if (v.GetVariables().Intersect(modSetLoop).Any()) { return; } AddDefinitionPair(variable, defInd, defs[0].Item2, regionId, modSet); }
void AnalyseRegion(IRegion region, Graph <Block> cfg) { var header = region.Header(); var blockVarDefs = new Dictionary <Block, VarDefs>(); var blocks = region.SubBlocks().Where(i => i != header); var modSet = LoopInvariantGenerator.GetModifiedVariables(region); blockVarDefs[header] = new VarDefs(header, cfg.BackEdgeNodes(header), modSet); blockVarDefs[header].Initialize(); foreach (var b in blocks) { blockVarDefs[b] = new VarDefs(b, cfg.Predecessors(b), modSet); } var changed = true; while (changed) { changed = false; foreach (var b in blocks) { if (blockVarDefs[b].ComputeTransfer(blockVarDefs)) { changed = true; } } } possibleInductionVarDefs[region.Identifier()] = blockVarDefs[header].FindSelfReferentialVariables(blockVarDefs) .ToDictionary(i => i.Item1.Name, i => i.Item2); }
void Analyse() { var cfg = verifier.Program.ProcessLoops(impl); var modSet = LoopInvariantGenerator.GetModifiedVariables(verifier.RootRegion(impl)); var multiDefMap = new VarDefMap(); FindAssignments(verifier.RootRegion(impl), multiDefMap); foreach (var e in multiDefMap.Where(i => i.Value.Count == 2)) { AnalyseAssignment(e.Key, e.Value, cfg, modSet); } }