use of com.dat3m.dartagnan.program.event.core.Event in project Dat3M by hernanponcedeleon.
the class AtomicAsLock method run.
private void run(MemoryObject address, Thread thread) {
Label end;
if (thread.getExit() instanceof Label) {
end = (Label) thread.getExit();
} else {
end = newLabel("__VERIFIER_atomic_thread_end");
thread.getExit().setSuccessor(end);
thread.updateExit(end);
}
Register register = thread.newRegister(ARCH_PRECISION);
for (Event predecessor = thread.getEntry(); predecessor != null; ) {
Event event = predecessor.getSuccessor();
boolean begin = event instanceof BeginAtomic;
if (begin || event instanceof EndAtomic) {
Event load = EventFactory.newLoad(register, address, null);
Event check = EventFactory.newJump(new Atom(register, NEQ, begin ? IValue.ZERO : IValue.ONE), end);
Event store = EventFactory.newStore(address, begin ? IValue.ONE : IValue.ZERO, null);
load.setOId(event.getOId());
check.setOId(event.getOId());
store.setOId(event.getOId());
load.addFilters(Tag.C11.LOCK, Tag.RMW);
check.addFilters(Tag.C11.LOCK, Tag.RMW);
store.addFilters(Tag.C11.LOCK, Tag.RMW);
predecessor.setSuccessor(load);
load.setSuccessor(check);
check.setSuccessor(store);
store.setSuccessor(event.getSuccessor());
predecessor = store;
} else {
predecessor = event;
}
}
}
use of com.dat3m.dartagnan.program.event.core.Event in project Dat3M by hernanponcedeleon.
the class EndAtomic method findEnclosedEvents.
private void findEnclosedEvents(BranchEquivalence eq) {
enclosedEvents = new ArrayList<>();
BranchEquivalence.Class startClass = eq.getEquivalenceClass(begin);
BranchEquivalence.Class endClass = eq.getEquivalenceClass(this);
if (!startClass.getReachableClasses().contains(endClass)) {
logger.warn("BeginAtomic" + begin.getCId() + "can't reach EndAtomic " + this.getCId());
}
for (BranchEquivalence.Class c : startClass.getReachableClasses()) {
for (Event e : c) {
if (begin.getCId() <= e.getCId() && e.getCId() <= this.getCId()) {
if (!eq.isImplied(e, begin)) {
logger.warn(e + " is inside atomic block but can be reached from the outside");
}
enclosedEvents.add(e);
e.addFilters(RMW);
}
}
}
enclosedEvents.sort(Comparator.naturalOrder());
enclosedEvents = ImmutableList.copyOf(enclosedEvents);
}
use of com.dat3m.dartagnan.program.event.core.Event in project Dat3M by hernanponcedeleon.
the class DeadAssignmentElimination method eliminateDeadStores.
private void eliminateDeadStores(Thread thread) {
Set<Event> removed = new HashSet<>();
// Registers that are used by other threads or assertions cannot be removed
Set<Register> usedRegs = new HashSet<>();
if (program.getAss() != null) {
usedRegs.addAll(program.getAss().getRegs());
}
program.getCache().getEvents(FilterBasic.get(ASSERTION)).stream().filter(RegWriter.class::isInstance).map(RegWriter.class::cast).map(RegWriter::getResultRegister).forEach(usedRegs::add);
program.getEvents().stream().filter(o -> !o.getThread().equals(thread)).filter(o -> o instanceof RegReaderData).forEach(o -> usedRegs.addAll(((RegReaderData) o).getDataRegs()));
for (Event e : Lists.reverse(thread.getEvents())) {
if (e instanceof RegWriter && !e.is(VISIBLE) && !usedRegs.contains(((RegWriter) e).getResultRegister())) {
// Invisible RegWriters that write to an unused reg can get removed
removed.add(e);
}
// An event that was not removed adds its dependencies to the used registers
if (!removed.contains(e)) {
if (e instanceof RegReaderData) {
// Data & Ctrl dependencies
usedRegs.addAll(((RegReaderData) e).getDataRegs());
}
if (e instanceof MemEvent) {
// Address dependencies
usedRegs.addAll(((MemEvent) e).getAddress().getRegs());
}
}
}
// Here is the actual removal
Event pred = null;
Event cur = thread.getEntry();
while (cur != null) {
if (removed.contains(cur) && !cur.is(Tag.NOOPT)) {
cur.delete();
cur = pred;
}
pred = cur;
cur = cur.getSuccessor();
}
}
use of com.dat3m.dartagnan.program.event.core.Event in project Dat3M by hernanponcedeleon.
the class DeadCodeElimination method eliminateDeadCode.
private void eliminateDeadCode(Thread thread, int startId) {
Event entry = thread.getEntry();
Event exit = thread.getExit();
if (entry.is(Tag.INIT)) {
return;
}
Set<Event> reachableEvents = new HashSet<>();
computeReachableEvents(entry, reachableEvents);
Event pred = null;
Event cur = entry;
int id = startId;
while (cur != null) {
if (!reachableEvents.contains(cur) && cur != exit && !cur.is(Tag.NOOPT)) {
cur.delete();
cur = pred;
} else {
cur.setOId(id++);
}
pred = cur;
cur = cur.getSuccessor();
}
}
use of com.dat3m.dartagnan.program.event.core.Event in project Dat3M by hernanponcedeleon.
the class FindSpinLoops method detectAndMarkSpinLoops.
private void detectAndMarkSpinLoops(Thread t) {
Event curr = t.getEntry();
while (curr != null) {
// Find start of spinloop that is not already marked.
if (curr instanceof Label && !curr.is(Tag.SPINLOOP)) {
Label label = (Label) curr;
// Importantly, this looks for the LAST backjump to the label
List<CondJump> backjumps = label.getJumpSet().stream().filter(x -> x.getOId() > label.getOId()).sorted().collect(Collectors.toList());
if (!backjumps.isEmpty()) {
Label loopStart = label;
CondJump loopEnd = backjumps.get(backjumps.size() - 1);
if (isSideEffectFree(loopStart, loopEnd)) {
loopStart.addFilters(Tag.SPINLOOP, Tag.NOOPT);
backjumps.forEach(x -> x.addFilters(Tag.SPINLOOP, Tag.NOOPT));
spinloops++;
}
}
}
curr = curr.getSuccessor();
}
t.clearCache();
}
Aggregations