in Sources/SolToBoogie/ModSetAnalysis.cs [23:126]
public void PerformModSetAnalysis()
{
BoogieProgram prog = context.Program;
List<BoogieImplementation> impls = new List<BoogieImplementation>();
Dictionary<string, BoogieGlobalVariable> globals = new Dictionary<string, BoogieGlobalVariable>();
Dictionary<string, BoogieProcedure> procedures = new Dictionary<string, BoogieProcedure>();
foreach (var decl in prog.Declarations)
{
if (decl is BoogieImplementation)
{
impls.Add((BoogieImplementation) decl);
}
else if (decl is BoogieProcedure)
{
BoogieProcedure proc = (BoogieProcedure) decl;
procedures.Add(proc.Name, proc);
}
else if (decl is BoogieGlobalVariable)
{
var globalVar = (BoogieGlobalVariable) decl;
globals.Add(globalVar.Name, globalVar);
}
}
calculateFlattenCmdLists(impls);
foreach (var impl in impls)
{
HashSet<BoogieGlobalVariable> modSet = new HashSet<BoogieGlobalVariable>();
modSets.Add(impl.Name, modSet);
foreach (var stmt in flattenedCmdLists[impl.Name])
{
switch (stmt)
{
case BoogieHavocCmd havoc:
foreach (var identifier in havoc.Vars)
{
var idName = identifier.Name;
if (globals.ContainsKey(idName))
{
modSet.Add(globals[idName]);
}
}
break;
case BoogieAssignCmd assign:
switch (assign.Lhs)
{
case BoogieIdentifierExpr idExpr:
{
var idName = idExpr.Name;
if (globals.ContainsKey(idName))
modSet.Add(globals[idName]);
break;
}
case BoogieMapSelect mapSelect:
{
var idName = findOutermostIdentifierExpr(mapSelect).Name;
if (globals.ContainsKey(idName))
modSet.Add(globals[idName]);
break;
}
default:
throw new RuntimeWrappedException("unexpected LHS");
}
break;
}
}
}
bool modSetChange;
do
{
modSetChange = false;
foreach (var impl in impls)
{
HashSet<BoogieGlobalVariable> currModSet = modSets[impl.Name];
int oldSize = currModSet.Count;
foreach (var stmt in flattenedCmdLists[impl.Name])
{
if (stmt is BoogieCallCmd)
{
BoogieCallCmd callCmd = (BoogieCallCmd) stmt;
if (modSets.ContainsKey(callCmd.Callee))
{
currModSet.UnionWith(modSets[callCmd.Callee]);
}
}
}
if (currModSet.Count > oldSize)
modSetChange = true;
}
} while (modSetChange);
foreach (var impl in impls)
{
procedures[impl.Name].ModSet = modSets[impl.Name].ToList();
}
}