Search in sources :

Example 6 with MemEvent

use of com.dat3m.dartagnan.program.event.core.MemEvent in project Dat3M by hernanponcedeleon.

the class RelRf method applyLocalConsistency.

private void applyLocalConsistency() {
    // Remove future reads
    maxTupleSet.removeIf(Tuple::isBackward);
    // Remove past reads
    ExecutionAnalysis exec = analysisContext.get(ExecutionAnalysis.class);
    AliasAnalysis alias = analysisContext.get(AliasAnalysis.class);
    Set<Tuple> deletedTuples = new HashSet<>();
    for (Event r : task.getProgram().getCache().getEvents(FilterBasic.get(READ))) {
        MemEvent read = (MemEvent) r;
        // The set of same-thread writes as well as init writes that could be read from (all before the read)
        // sorted by order (init events first)
        List<MemEvent> possibleWrites = maxTupleSet.getBySecond(read).stream().map(Tuple::getFirst).filter(e -> (e.getThread() == read.getThread() || e.is(INIT))).map(x -> (MemEvent) x).sorted((o1, o2) -> o1.is(INIT) == o2.is(INIT) ? (o1.getCId() - o2.getCId()) : o1.is(INIT) ? -1 : 1).collect(Collectors.toList());
        // The set of writes that won't be readable due getting overwritten.
        Set<MemEvent> deletedWrites = new HashSet<>();
        // - w2 must alias with either w1 or r.
        for (int i = 0; i < possibleWrites.size(); i++) {
            MemEvent w1 = possibleWrites.get(i);
            for (MemEvent w2 : possibleWrites.subList(i + 1, possibleWrites.size())) {
                // executed
                if ((exec.isImplied(w1, w2) || exec.isImplied(read, w2)) && (alias.mustAlias(w1, w2) || alias.mustAlias(w2, read))) {
                    deletedWrites.add(w1);
                    break;
                }
            }
        }
        for (Event w : deletedWrites) {
            deletedTuples.add(new Tuple(w, read));
        }
    }
    maxTupleSet.removeAll(deletedTuples);
}
Also used : AliasAnalysis(com.dat3m.dartagnan.program.analysis.AliasAnalysis) java.util(java.util) BooleanType(org.sosy_lab.java_smt.api.FormulaType.BooleanType) Store(com.dat3m.dartagnan.program.event.core.Store) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) org.sosy_lab.java_smt.api(org.sosy_lab.java_smt.api) Relation(com.dat3m.dartagnan.wmm.relation.Relation) Utils(com.dat3m.dartagnan.expression.utils.Utils) RF(com.dat3m.dartagnan.wmm.relation.RelationNameRepository.RF) Collectors(java.util.stream.Collectors) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) FilterAbstract(com.dat3m.dartagnan.program.filter.FilterAbstract) Tag(com.dat3m.dartagnan.program.event.Tag) EndAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic) WmmAnalysis(com.dat3m.dartagnan.wmm.analysis.WmmAnalysis) Logger(org.apache.logging.log4j.Logger) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) FilterIntersection(com.dat3m.dartagnan.program.filter.FilterIntersection) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) Load(com.dat3m.dartagnan.program.event.core.Load) LogManager(org.apache.logging.log4j.LogManager) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) AliasAnalysis(com.dat3m.dartagnan.program.analysis.AliasAnalysis) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 7 with MemEvent

use of com.dat3m.dartagnan.program.event.core.MemEvent in project Dat3M by hernanponcedeleon.

the class FindSpinLoops method isSideEffectFree.

private boolean isSideEffectFree(Label loopBegin, CondJump loopEnd) {
    Event cur = loopBegin.getSuccessor();
    // Unsafe means the loop read from the registers before writing to them.
    Set<Register> unsafeRegisters = new HashSet<>();
    // Safe means the loop wrote to these register before using them
    Set<Register> safeRegisters = new HashSet<>();
    while (cur != loopEnd) {
        if (cur instanceof MemEvent) {
            if (cur.is(Tag.WRITE)) {
                // Writes always cause side effects
                return false;
            }
            MemEvent memEvent = (MemEvent) cur;
            Set<Register> addrRegs = memEvent.getAddress().getRegs();
            unsafeRegisters.addAll(Sets.difference(addrRegs, safeRegisters));
        }
        if (cur instanceof RegReaderData) {
            RegReaderData reader = (RegReaderData) cur;
            Set<Register> dataRegs = reader.getDataRegs();
            unsafeRegisters.addAll(Sets.difference(dataRegs, safeRegisters));
        }
        if (cur instanceof RegWriter) {
            RegWriter writer = (RegWriter) cur;
            if (unsafeRegisters.contains(writer.getResultRegister())) {
                return false;
            } else {
                safeRegisters.add(writer.getResultRegister());
            }
        }
        cur = cur.getSuccessor();
    }
    return true;
}
Also used : Register(com.dat3m.dartagnan.program.Register) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) HashSet(java.util.HashSet)

Example 8 with MemEvent

use of com.dat3m.dartagnan.program.event.core.MemEvent 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);
}
Also used : Options(org.sosy_lab.common.configuration.Options) Property(com.dat3m.dartagnan.configuration.Property) Utils.intVar(com.dat3m.dartagnan.wmm.utils.Utils.intVar) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Utils.edge(com.dat3m.dartagnan.wmm.utils.Utils.edge) HashMap(java.util.HashMap) Thread(com.dat3m.dartagnan.program.Thread) ArrayList(java.util.ArrayList) Wmm(com.dat3m.dartagnan.wmm.Wmm) Map(java.util.Map) SolverContext(org.sosy_lab.java_smt.api.SolverContext) Program(com.dat3m.dartagnan.program.Program) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) BigInteger(java.math.BigInteger) RelRf(com.dat3m.dartagnan.wmm.relation.base.memory.RelRf) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) EnumSet(java.util.EnumSet) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) Utils.generalEqual(com.dat3m.dartagnan.expression.utils.Utils.generalEqual) AliasAnalysis(com.dat3m.dartagnan.program.analysis.AliasAnalysis) RelCo(com.dat3m.dartagnan.wmm.relation.base.memory.RelCo) Configuration(org.sosy_lab.common.configuration.Configuration) Collectors(java.util.stream.Collectors) Label(com.dat3m.dartagnan.program.event.core.Label) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) IntegerFormulaManager(org.sosy_lab.java_smt.api.IntegerFormulaManager) Tag(com.dat3m.dartagnan.program.event.Tag) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) Context(com.dat3m.dartagnan.verification.Context) RelationNameRepository(com.dat3m.dartagnan.wmm.relation.RelationNameRepository) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Event(com.dat3m.dartagnan.program.event.core.Event) Preconditions(com.google.common.base.Preconditions) Load(com.dat3m.dartagnan.program.event.core.Load) LogManager(org.apache.logging.log4j.LogManager) FilterMinus(com.dat3m.dartagnan.program.filter.FilterMinus) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) IntegerFormulaManager(org.sosy_lab.java_smt.api.IntegerFormulaManager) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Thread(com.dat3m.dartagnan.program.Thread)

Example 9 with MemEvent

use of com.dat3m.dartagnan.program.event.core.MemEvent 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));
    }
}
Also used : Options(org.sosy_lab.common.configuration.Options) java.util(java.util) Configuration(org.sosy_lab.common.configuration.Configuration) IntStream.range(java.util.stream.IntStream.range) Thread(com.dat3m.dartagnan.program.Thread) Collectors(java.util.stream.Collectors) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Context(com.dat3m.dartagnan.verification.Context) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Collectors.toList(java.util.stream.Collectors.toList) Logger(org.apache.logging.log4j.Logger) Verify.verify(com.google.common.base.Verify.verify) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) CondJump(com.dat3m.dartagnan.program.event.core.CondJump) LogManager(org.apache.logging.log4j.LogManager) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) CondJump(com.dat3m.dartagnan.program.event.core.CondJump) Register(com.dat3m.dartagnan.program.Register) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter)

Example 10 with MemEvent

use of com.dat3m.dartagnan.program.event.core.MemEvent 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();
    }
}
Also used : Configuration(org.sosy_lab.common.configuration.Configuration) ASSERTION(com.dat3m.dartagnan.program.event.Tag.ASSERTION) Set(java.util.Set) Thread(com.dat3m.dartagnan.program.Thread) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Tag(com.dat3m.dartagnan.program.event.Tag) HashSet(java.util.HashSet) Lists(com.google.common.collect.Lists) Logger(org.apache.logging.log4j.Logger) VISIBLE(com.dat3m.dartagnan.program.event.Tag.VISIBLE) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) LogManager(org.apache.logging.log4j.LogManager) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) HashSet(java.util.HashSet)

Aggregations

MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)17 Event (com.dat3m.dartagnan.program.event.core.Event)12 AliasAnalysis (com.dat3m.dartagnan.program.analysis.AliasAnalysis)8 Tuple (com.dat3m.dartagnan.wmm.utils.Tuple)8 TupleSet (com.dat3m.dartagnan.wmm.utils.TupleSet)6 Thread (com.dat3m.dartagnan.program.Thread)5 Tag (com.dat3m.dartagnan.program.event.Tag)5 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)5 WmmAnalysis (com.dat3m.dartagnan.wmm.analysis.WmmAnalysis)5 Collectors (java.util.stream.Collectors)5 Program (com.dat3m.dartagnan.program.Program)4 Register (com.dat3m.dartagnan.program.Register)4 Load (com.dat3m.dartagnan.program.event.core.Load)4 RegWriter (com.dat3m.dartagnan.program.event.core.utils.RegWriter)4 java.util (java.util)4 LogManager (org.apache.logging.log4j.LogManager)4 Logger (org.apache.logging.log4j.Logger)4 Store (com.dat3m.dartagnan.program.event.core.Store)3 RegReaderData (com.dat3m.dartagnan.program.event.core.utils.RegReaderData)3 EndAtomic (com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic)3