use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class PropertyEncoder method encodeDataRaces.
public BooleanFormula encodeDataRaces(SolverContext ctx) {
final String hb = "hb";
checkState(memoryModel.getAxioms().stream().anyMatch(ax -> ax.isAcyclicity() && ax.getRelation().getName().equals(hb)), "The provided WMM needs an 'acyclic(hb)' axiom to encode data races.");
logger.info("Encoding data-races");
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
IntegerFormulaManager imgr = ctx.getFormulaManager().getIntegerFormulaManager();
BooleanFormula enc = bmgr.makeFalse();
for (Thread t1 : program.getThreads()) {
for (Thread t2 : program.getThreads()) {
if (t1.getId() == t2.getId()) {
continue;
}
for (Event e1 : t1.getCache().getEvents(FilterMinus.get(FilterBasic.get(Tag.WRITE), FilterBasic.get(Tag.INIT)))) {
MemEvent w = (MemEvent) e1;
for (Event e2 : t2.getCache().getEvents(FilterMinus.get(FilterBasic.get(Tag.MEMORY), FilterBasic.get(Tag.INIT)))) {
MemEvent m = (MemEvent) e2;
if (w.hasFilter(Tag.RMW) && m.hasFilter(Tag.RMW)) {
continue;
}
if (w.canRace() && m.canRace() && alias.mayAlias(w, m)) {
BooleanFormula conflict = bmgr.and(m.exec(), w.exec(), edge(hb, m, w, ctx), generalEqual(w.getMemAddressExpr(), m.getMemAddressExpr(), ctx), imgr.equal(intVar(hb, w, ctx), imgr.add(intVar(hb, m, ctx), imgr.makeNumber(BigInteger.ONE))));
enc = bmgr.or(enc, conflict);
}
}
}
}
}
// We use the SMT variable to extract from the model if the property was violated
enc = bmgr.equivalence(RACES.getSMTVariable(ctx), enc);
return bmgr.and(RACES.getSMTVariable(ctx), enc);
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class PropertyEncoder method encodeLiveness.
public BooleanFormula encodeLiveness(SolverContext ctx) {
// Further, we assume that the spinloops are indeed correct, i.e., side-effect free
class SpinLoop {
public List<Load> loads = new ArrayList<>();
public Event bound;
}
logger.info("Encoding liveness");
Map<Thread, List<SpinLoop>> spinloopsMap = new HashMap<>();
// Find spinloops of all threads
for (Thread t : program.getThreads()) {
List<Event> spinStarts = t.getEvents().stream().filter(e -> e instanceof Label && e.is(Tag.SPINLOOP)).collect(Collectors.toList());
List<SpinLoop> spinLoops = new ArrayList<>();
spinloopsMap.put(t, spinLoops);
for (Event start : spinStarts) {
SpinLoop loop = new SpinLoop();
Event cur = start.getSuccessor();
while (!cur.is(Tag.SPINLOOP)) {
if (cur.is(Tag.READ)) {
loop.loads.add((Load) cur);
}
cur = cur.getSuccessor();
}
loop.bound = cur;
spinLoops.add(loop);
}
}
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
RelRf rf = (RelRf) memoryModel.getRelationRepository().getRelation(RelationNameRepository.RF);
RelCo co = (RelCo) memoryModel.getRelationRepository().getRelation(RelationNameRepository.CO);
// Compute "stuckness": A thread is stuck if it reaches a spinloop bound event
// while reading from a co-maximal write.
Map<Thread, BooleanFormula> isStuckMap = new HashMap<>();
for (Thread t : program.getThreads()) {
List<SpinLoop> loops = spinloopsMap.get(t);
if (loops.isEmpty()) {
continue;
}
BooleanFormula isStuck = bmgr.makeFalse();
for (SpinLoop pair : loops) {
BooleanFormula allCoMaximalLoad = bmgr.makeTrue();
for (Load load : pair.loads) {
BooleanFormula coMaximalLoad = bmgr.makeFalse();
for (Tuple rfEdge : rf.getMaxTupleSet().getBySecond(load)) {
coMaximalLoad = bmgr.or(coMaximalLoad, bmgr.and(rf.getSMTVar(rfEdge, ctx), co.getLastCoVar(rfEdge.getFirst(), ctx)));
}
allCoMaximalLoad = bmgr.and(allCoMaximalLoad, coMaximalLoad);
}
isStuck = bmgr.or(isStuck, bmgr.and(pair.bound.exec(), allCoMaximalLoad));
}
isStuckMap.put(t, isStuck);
}
// LivenessViolation <=> allStuckOrDone /\ atLeastOneStuck
BooleanFormula allStuckOrDone = bmgr.makeTrue();
BooleanFormula atLeastOneStuck = bmgr.makeFalse();
for (Thread t : program.getThreads()) {
BooleanFormula isStuck = isStuckMap.getOrDefault(t, bmgr.makeFalse());
BooleanFormula isDone = t.getCache().getEvents(FilterBasic.get(Tag.BOUND)).stream().map(e -> bmgr.not(e.exec())).reduce(bmgr.makeTrue(), bmgr::and);
atLeastOneStuck = bmgr.or(atLeastOneStuck, isStuck);
allStuckOrDone = bmgr.and(allStuckOrDone, bmgr.or(isStuck, isDone));
}
// We use the SMT variable to extract from the model if the property was violated
BooleanFormula enc = bmgr.equivalence(LIVENESS.getSMTVariable(ctx), bmgr.and(allStuckOrDone, atLeastOneStuck));
return bmgr.and(LIVENESS.getSMTVariable(ctx), enc);
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class SymmetryEncoder method encodeFullSymmetry.
public BooleanFormula encodeFullSymmetry(SolverContext ctx) {
BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
BooleanFormula enc = bmgr.makeTrue();
if (rel == null) {
return enc;
}
for (EquivalenceClass<Thread> symmClass : symm.getNonTrivialClasses()) {
enc = bmgr.and(enc, encodeSymmetryClass(symmClass, ctx));
}
return enc;
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class BranchEquivalence method run.
private void run() {
Map<Thread, Map<Event, Branch>> threadBranches = new HashMap<>();
for (Thread t : program.getThreads()) {
// Step (1)
Map<Event, Branch> branchMap = new HashMap<>();
Map<Event, Branch> finalBranchMap = new HashMap<>();
threadBranches.put(t, branchMap);
computeBranches(t.getEntry(), branchMap, finalBranchMap);
// Step (2)-(3)
for (Branch b : branchMap.values()) {
computeMustPredSet(b);
computeMustSuccSet(b);
computeReachableBranches(b);
}
// Step (4)-(5)
createBranchClasses(branchMap);
}
// Step (6)
mergeInitialClasses();
// Step (7)
computeUnreachableClass();
// Bonus
computeExclusiveClasses(threadBranches);
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class Dependency method fromConfig.
/**
* Performs a dependency analysis on a program.
* @param program
* Instruction lists to be analyzed.
* @param analysisContext
* Collection of other analyses previously performed on {@code program}.
* Should include {@link ExecutionAnalysis}.
* @param config
* Mapping from keywords to values,
* further specifying the behavior of this analysis.
* See this class's list of options for details.
* @throws InvalidConfigurationException
* Some option was provided with an unsupported type.
*/
public static Dependency fromConfig(Program program, Context analysisContext, Configuration config) throws InvalidConfigurationException {
logger.info("Analyze dependencies");
ExecutionAnalysis exec = analysisContext.requires(ExecutionAnalysis.class);
Dependency result = new Dependency();
config.inject(result);
for (Thread t : program.getThreads()) {
result.process(t, exec);
}
return result;
}
Aggregations