use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class ExecutionModel method extractEventsFromModel.
// ========================== Internal methods =========================
private void extractEventsFromModel() {
// TODO(TH): We might also want to extract events such as inline assertions
// and whether they were violated or not.
int id = 0;
eventList.clear();
threadList.clear();
threadEventsMap.clear();
atomicBlocksMap.clear();
// This one can probably be constant and need not be rebuilt!
addressInitMap.clear();
addressWritesMap.clear();
addressReadsMap.clear();
writeReadsMap.clear();
fenceMap.clear();
eventMap.clear();
addrDepMap.clear();
dataDepMap.clear();
ctrlDepMap.clear();
List<Thread> threadList = new ArrayList<>(getProgram().getThreads());
List<Integer> threadEndIndexList = new ArrayList<>(threadList.size());
Map<Thread, List<List<Integer>>> atomicBlockRangesMap = new HashMap<>();
for (Thread thread : threadList) {
initDepTracking();
List<List<Integer>> atomicBlockRanges = atomicBlockRangesMap.computeIfAbsent(thread, key -> new ArrayList<>());
Event e = thread.getEntry();
int atomicBegin = -1;
int localId = 0;
do {
if (!e.wasExecuted(model)) {
e = e.getSuccessor();
continue;
}
if (eventFilter.filter(e)) {
addEvent(e, id++, localId++);
}
trackDependencies(e);
// ===== Atomic blocks =====
if (e instanceof BeginAtomic) {
atomicBegin = id;
} else if (e instanceof EndAtomic) {
Preconditions.checkState(atomicBegin != -1, "EndAtomic without matching BeginAtomic in model");
atomicBlockRanges.add(ImmutableList.of(atomicBegin, id));
atomicBegin = -1;
}
if (e instanceof CondJump) {
CondJump jump = (CondJump) e;
if (jump.didJump(model, context)) {
e = jump.getLabel();
continue;
}
}
e = e.getSuccessor();
} while (e != null);
// We have a BeginAtomic without EndAtomic since the program terminated within the block
if (atomicBegin != -1) {
atomicBlockRanges.add(ImmutableList.of(atomicBegin, id));
}
// -----------
threadEndIndexList.add(id);
}
// Get sublists for all threads
int start = 0;
for (int i = 0; i < threadList.size(); i++) {
Thread thread = threadList.get(i);
int end = threadEndIndexList.get(i);
if (start != end) {
this.threadList.add(thread);
threadEventsMap.put(thread, Collections.unmodifiableList(eventList.subList(start, end)));
atomicBlocksMap.put(thread, new ArrayList<>());
for (List<Integer> aRange : atomicBlockRangesMap.get(thread)) {
atomicBlocksMap.get(thread).add(eventList.subList(aRange.get(0), aRange.get(1)));
}
}
start = end;
}
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class RelCtrlDirect method getMaxTupleSet.
@Override
public TupleSet getMaxTupleSet() {
if (maxTupleSet == null) {
maxTupleSet = new TupleSet();
// NOTE: If's (under Linux) have different notion of ctrl dependency than conditional jumps!
for (Thread thread : task.getProgram().getThreads()) {
for (Event e1 : thread.getCache().getEvents(FilterBasic.get(Tag.CMP))) {
for (Event e2 : ((IfAsJump) e1).getBranchesEvents()) {
maxTupleSet.add(new Tuple(e1, e2));
}
}
// Relates jumps (except those implementing Ifs and their internal jump to end) with all later events
List<Event> condJumps = thread.getCache().getEvents(FilterMinus.get(FilterBasic.get(Tag.JUMP), FilterUnion.get(FilterBasic.get(Tag.CMP), FilterBasic.get(Tag.IFI))));
if (!condJumps.isEmpty()) {
for (Event e2 : thread.getCache().getEvents(FilterBasic.get(Tag.ANY))) {
for (Event e1 : condJumps) {
if (e1.getCId() < e2.getCId()) {
maxTupleSet.add(new Tuple(e1, e2));
}
}
}
}
}
removeMutuallyExclusiveTuples(maxTupleSet);
}
return maxTupleSet;
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class RelCrit method getMaxTupleSet.
@Override
public TupleSet getMaxTupleSet() {
if (maxTupleSet == null) {
maxTupleSet = new TupleSet();
for (Thread thread : task.getProgram().getThreads()) {
for (Event lock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_LOCK))) {
for (Event unlock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_UNLOCK))) {
if (lock.getCId() < unlock.getCId()) {
maxTupleSet.add(new Tuple(lock, unlock));
}
}
}
}
removeMutuallyExclusiveTuples(maxTupleSet);
}
return maxTupleSet;
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class RelRMW method encodeApprox.
@Override
protected BooleanFormula encodeApprox(SolverContext ctx) {
FormulaManager fmgr = ctx.getFormulaManager();
BooleanFormulaManager bmgr = fmgr.getBooleanFormulaManager();
// Encode base (not exclusive pairs) RMW
TupleSet origEncodeTupleSet = encodeTupleSet;
encodeTupleSet = new TupleSet(Sets.intersection(encodeTupleSet, baseMaxTupleSet));
BooleanFormula enc = super.encodeApprox(ctx);
encodeTupleSet = origEncodeTupleSet;
// Encode RMW for exclusive pairs
BooleanFormula unpredictable = bmgr.makeFalse();
for (Thread thread : task.getProgram().getThreads()) {
for (Event store : thread.getCache().getEvents(storeExclFilter)) {
BooleanFormula storeExec = bmgr.makeFalse();
for (Event load : thread.getCache().getEvents(loadExclFilter)) {
if (load.getCId() < store.getCId()) {
// Encode if load and store form an exclusive pair
BooleanFormula isPair = exclPair(load, store, ctx);
BooleanFormula isExecPair = bmgr.and(isPair, store.exec());
enc = bmgr.and(enc, bmgr.equivalence(isPair, pairingCond(thread, load, store, ctx)));
// If load and store have the same address
BooleanFormula sameAddress = generalEqual(((MemEvent) load).getMemAddressExpr(), ((MemEvent) store).getMemAddressExpr(), ctx);
unpredictable = bmgr.or(unpredictable, bmgr.and(isExecPair, bmgr.not(sameAddress)));
// Relation between exclusive load and store
enc = bmgr.and(enc, bmgr.equivalence(this.getSMTVar(load, store, ctx), bmgr.and(isExecPair, sameAddress)));
// Can be executed if addresses mismatch, but behaviour is "constrained unpredictable"
// The implementation does not include all possible unpredictable cases: in case of address
// mismatch, addresses of read and write are unknown, i.e. read and write can use any address
storeExec = bmgr.or(storeExec, isPair);
}
}
enc = bmgr.and(enc, bmgr.implication(store.exec(), storeExec));
}
}
return bmgr.and(enc, bmgr.equivalence(Flag.ARM_UNPREDICTABLE_BEHAVIOUR.repr(ctx), unpredictable));
}
use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.
the class RelFencerel method getMinTupleSet.
@Override
public TupleSet getMinTupleSet() {
if (minTupleSet == null) {
ExecutionAnalysis exec = analysisContext.get(ExecutionAnalysis.class);
minTupleSet = new TupleSet();
for (Thread t : task.getProgram().getThreads()) {
List<Event> fences = t.getCache().getEvents(FilterBasic.get(fenceName));
List<Event> memEvents = t.getCache().getEvents(FilterBasic.get(Tag.MEMORY));
for (Event fence : fences) {
int numEventsBeforeFence = (int) memEvents.stream().mapToInt(Event::getCId).filter(id -> id < fence.getCId()).count();
List<Event> eventsBefore = memEvents.subList(0, numEventsBeforeFence);
List<Event> eventsAfter = memEvents.subList(numEventsBeforeFence, memEvents.size());
for (Event e1 : eventsBefore) {
boolean isImpliedByE1 = exec.isImplied(e1, fence);
for (Event e2 : eventsAfter) {
if (isImpliedByE1 || exec.isImplied(e2, fence)) {
minTupleSet.add(new Tuple(e1, e2));
}
}
}
}
}
removeMutuallyExclusiveTuples(minTupleSet);
}
return minTupleSet;
}
Aggregations