use of com.dat3m.dartagnan.program.event.core.utils.RegWriter in project Dat3M by hernanponcedeleon.
the class AndersenAliasAnalysis method processLocs.
private void processLocs(Program program) {
for (Event ev : program.getCache().getEvents(FilterBasic.get(Tag.MEMORY))) {
MemEvent e = (MemEvent) ev;
IExpr address = e.getAddress();
// Collect for each v events of form: p = *v, *v = q
if (address instanceof Register) {
graph.addEvent((Register) address, e);
continue;
}
Constant addressConstant = new Constant(address);
if (addressConstant.failed) {
// r = *(CompExpr) -> loc(r) = max
if (e instanceof RegWriter) {
Register register = ((RegWriter) e).getResultRegister();
graph.addAllAddresses(register, maxAddressSet);
variables.add(register);
}
// FIXME if e is a store event, then all locations should include its values
eventAddressSpaceMap.put(e, maxAddressSet);
continue;
}
// address is a constant
Location location = addressConstant.location;
if (location == null) {
throw new RuntimeException("memory event accessing a pure constant address");
}
eventAddressSpaceMap.put(e, ImmutableSet.of(location));
if (e instanceof RegWriter) {
graph.addEdge(location, ((RegWriter) e).getResultRegister());
continue;
}
// event is a store operation
Verify.verify(e.is(Tag.WRITE), "memory event that is neither tagged \"W\" nor a register writer");
ExprInterface value = e.getMemValue();
if (value instanceof Register) {
graph.addEdge(value, location);
continue;
}
Constant v = new Constant(value);
if (v.failed) {
graph.addAllAddresses(location, maxAddressSet);
} else if (v.location != null) {
graph.addAddress(location, v.location);
}
variables.add(location);
}
}
use of com.dat3m.dartagnan.program.event.core.utils.RegWriter in project Dat3M by hernanponcedeleon.
the class Dependency method process.
private void process(Thread thread, ExecutionAnalysis exec) {
Map<Event, Set<Writer>> jumps = new HashMap<>();
Set<Writer> state = new HashSet<>();
for (Register register : thread.getRegisters()) {
state.add(new Writer(register, null));
}
for (Event event : thread.getEvents()) {
// merge with incoming jumps
Set<Writer> j = jumps.remove(event);
if (j != null) {
state.addAll(j);
}
// collecting dependencies, mixing 'data' and 'addr'
Set<Register> registers = new HashSet<>();
if (event instanceof RegReaderData) {
registers.addAll(((RegReaderData) event).getDataRegs());
}
if (event instanceof MemEvent) {
registers.addAll(((MemEvent) event).getAddress().getRegs());
}
if (!registers.isEmpty()) {
Map<Register, State> result = new HashMap<>();
for (Register register : registers) {
if (register.getThreadId() == Register.NO_THREAD) {
continue;
}
State writers;
if (register.getThreadId() != event.getThread().getId()) {
writers = finalWriters.get(register);
checkArgument(writers != null, "Helper thread %s should be listed after their creator thread %s.", thread.getId(), register.getThreadId());
if (writers.may.size() != 1) {
logger.warn("Writers {} for inter-thread register {} read by event {} of thread {}", writers.may, register, event, thread.getId());
}
} else {
writers = process(state, register, exec);
if (!writers.initialized) {
logger.warn("Uninitialized register {} read by event {} of thread {}", register, event, thread.getId());
}
}
result.put(register, writers);
}
map.put(event, result);
}
// update state, if changed by event
if (event instanceof RegWriter) {
Register register = ((RegWriter) event).getResultRegister();
if (event.cfImpliesExec()) {
state.removeIf(e -> e.register.equals(register));
}
state.add(new Writer(register, event));
}
// copy state, if branching
if (event instanceof CondJump) {
jumps.computeIfAbsent(((CondJump) event).getLabel(), k -> new HashSet<>()).addAll(state);
if (((CondJump) event).isGoto()) {
state.clear();
}
}
}
if (!jumps.isEmpty()) {
logger.warn("Thread {} contains jumps to removed labels {}", thread.getId(), jumps.keySet());
for (Set<Writer> j : jumps.values()) {
state.addAll(j);
}
}
for (Register register : thread.getRegisters()) {
finalWriters.put(register, process(state, register, exec));
}
}
use of com.dat3m.dartagnan.program.event.core.utils.RegWriter in project Dat3M by hernanponcedeleon.
the class ConstantPropagation method run.
private void run(Thread thread) {
Map<Register, ExprInterface> propagationMap = new HashMap<>();
Map<Label, Map<Register, ExprInterface>> label2PropagationMap = new HashMap<>();
Event pred = thread.getEntry();
Event current = pred.getSuccessor();
while (current != null) {
boolean resetPropMap = false;
// but like this the solver keeps relations between variables)
if (current instanceof RegWriter) {
RegWriter rw = (RegWriter) current;
propagationMap.put(rw.getResultRegister(), rw.getResultRegister());
}
// For Locals, we update
if (current instanceof Local) {
Local l = (Local) current;
// We cannot update the map with the evaluation if the resultRegister is also in the RHS
if (!l.getExpr().getRegs().contains(l.getResultRegister())) {
ExprInterface value = evaluate(l.getExpr(), propagationMap);
if (value == TOP && l.getExpr() instanceof Register) {
// Even if we do not know the concrete value, Registers have a constant value
// thus we add them to the map to achieve more propagations
propagationMap.put(l.getResultRegister(), l.getExpr());
} else {
propagationMap.put(l.getResultRegister(), value);
}
}
}
if (current instanceof CondJump) {
CondJump jump = (CondJump) current;
label2PropagationMap.put(jump.getLabel(), merge(propagationMap, label2PropagationMap.getOrDefault(jump.getLabel(), Collections.emptyMap())));
// A goto will cause the current map to not propagate to the successor
resetPropMap = jump.isGoto();
} else if (current instanceof Label) {
// Merge current map with all possible jumps that target this label
propagationMap = merge(propagationMap, label2PropagationMap.getOrDefault(current, Collections.emptyMap()));
}
if (!current.is(Tag.NOOPT)) {
current.accept(new ConstantPropagationVisitor(propagationMap));
}
current = current.getSuccessor();
if (resetPropMap) {
propagationMap.clear();
}
}
thread.updateExit(thread.getEntry());
thread.clearCache();
}
use of com.dat3m.dartagnan.program.event.core.utils.RegWriter 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.utils.RegWriter in project Dat3M by hernanponcedeleon.
the class ExecutionModel method addEvent.
private void addEvent(Event e, int globalId, int localId) {
EventData data = eventMap.getOrCreate(e);
data.setId(globalId);
data.setLocalId(localId);
eventList.add(data);
data.setWasExecuted(true);
if (data.isMemoryEvent()) {
// ===== Memory Events =====
BigInteger address = ((MemEvent) e).getAddress().getIntValue(e, model, context);
data.setAccessedAddress(address);
if (!addressReadsMap.containsKey(address)) {
addressReadsMap.put(address, new HashSet<>());
addressWritesMap.put(address, new HashSet<>());
}
if (data.isRead()) {
data.setValue(new BigInteger(model.evaluate(((RegWriter) e).getResultRegisterExpr()).toString()));
addressReadsMap.get(address).add(data);
} else if (data.isWrite()) {
data.setValue(((MemEvent) e).getMemValue().getIntValue(e, model, context));
addressWritesMap.get(address).add(data);
writeReadsMap.put(data, new HashSet<>());
if (data.isInit()) {
addressInitMap.put(address, data);
}
} else {
throw new UnsupportedOperationException("Unexpected memory event " + data.getEvent());
}
} else if (data.isFence()) {
// ===== Fences =====
String name = ((Fence) data.getEvent()).getName();
fenceMap.computeIfAbsent(name, key -> new HashSet<>()).add(data);
} else if (data.isJump()) {
// ===== Jumps =====
// We override the meaning of execution here. A jump is executed IFF its condition was true.
data.setWasExecuted(((CondJump) e).didJump(model, context));
} else {
// TODO: Maybe add some other events (e.g. assertions)
// But for now all non-visible events are simply registered without
// having any data extracted
}
}
Aggregations