Search in sources :

Example 11 with Event

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

the class Acyclic method consistent.

@Override
public BooleanFormula consistent(SolverContext ctx) {
    FormulaManager fmgr = ctx.getFormulaManager();
    BooleanFormulaManager bmgr = fmgr.getBooleanFormulaManager();
    IntegerFormulaManager imgr = fmgr.getIntegerFormulaManager();
    BooleanFormula enc = bmgr.makeTrue();
    for (Tuple tuple : rel.getEncodeTupleSet()) {
        Event e1 = tuple.getFirst();
        Event e2 = tuple.getSecond();
        enc = bmgr.and(enc, bmgr.implication(rel.getSMTVar(tuple, ctx), imgr.lessThan(Utils.intVar(rel.getName(), e1, ctx), Utils.intVar(rel.getName(), e2, ctx))));
    }
    return enc;
}
Also used : Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 12 with Event

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

the class Acyclic method reduceWithMinSets.

private void reduceWithMinSets(TupleSet encodeSet) {
    /*
            ASSUMPTION: MinSet is acyclic!
            IDEA:
                Edges that are (must-)transitively implied do not need to get encoded.
                For this, we compute a (must-)transitive closure and a (must-)transitive reduction of must(rel).
                The difference "must(rel)+ \ red(must(rel))" does not net to be encoded.
                Note that it this is sound if the closure gets underapproximated and/or the reduction
                gets over approximated.
            COMPUTATION:
                (1) We compute an approximate (must-)transitive closure of must(rel)
                    - must(rel) is likely to be already transitive per thread (due to mostly coming from po)
                      Hence, we get a reasonable approximation by closing transitively over thread-crossing edges only.
                (2) We compute a (must) transitive reduction of the transitively closed must(rel)+.
                    - Since must(rel)+ is transitive, it suffice to check for each edge (a, c) if there
                      is an intermediate event b such that (a, b) and (b, c) are in must(rel)+
                      and b is implied by either a or c.
                    - It is possible to reduce must(rel) but that may give a less precise result.
         */
    ExecutionAnalysis exec = analysisContext.get(ExecutionAnalysis.class);
    TupleSet minSet = rel.getMinTupleSet();
    // (1) Approximate transitive closure of minSet (only gets computed when crossEdges are available)
    List<Tuple> crossEdges = minSet.stream().filter(t -> t.isCrossThread() && !t.getFirst().is(Tag.INIT)).collect(Collectors.toList());
    TupleSet transMinSet = crossEdges.isEmpty() ? minSet : new TupleSet(minSet);
    for (Tuple crossEdge : crossEdges) {
        Event e1 = crossEdge.getFirst();
        Event e2 = crossEdge.getSecond();
        List<Event> ingoing = new ArrayList<>();
        // ingoing events + self
        ingoing.add(e1);
        minSet.getBySecond(e1).stream().map(Tuple::getFirst).filter(e -> exec.isImplied(e, e1)).forEach(ingoing::add);
        List<Event> outgoing = new ArrayList<>();
        // outgoing edges + self
        outgoing.add(e2);
        minSet.getByFirst(e2).stream().map(Tuple::getSecond).filter(e -> exec.isImplied(e, e2)).forEach(outgoing::add);
        for (Event in : ingoing) {
            for (Event out : outgoing) {
                transMinSet.add(new Tuple(in, out));
            }
        }
    }
    // (2) Approximate reduction of transitive must-set: red(must(r)+).
    // Note: We reduce the transitive closure which may have more edges
    // that can be used to perform reduction
    TupleSet reduct = TupleSet.approximateTransitiveMustReduction(exec, transMinSet);
    // Remove (must(r)+ \ red(must(r)+)
    encodeSet.removeIf(t -> transMinSet.contains(t) && !reduct.contains(t));
}
Also used : Utils(com.dat3m.dartagnan.wmm.utils.Utils) java.util(java.util) 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) Collectors(java.util.stream.Collectors) Tag(com.dat3m.dartagnan.program.event.Tag) DependencyGraph(com.dat3m.dartagnan.utils.dependable.DependencyGraph) Logger(org.apache.logging.log4j.Logger) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) GlobalSettings(com.dat3m.dartagnan.GlobalSettings) LogManager(org.apache.logging.log4j.LogManager) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Example 13 with Event

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

the class RelCrit method encodeApprox.

// TODO: Not the most efficient implementation
// Let's see if we need to keep a reference to a thread in events for anything else, and then optimize this method
@Override
protected BooleanFormula encodeApprox(SolverContext ctx) {
    BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
    BooleanFormula enc = bmgr.makeTrue();
    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()) {
                    Tuple tuple = new Tuple(lock, unlock);
                    if (encodeTupleSet.contains(tuple)) {
                        BooleanFormula relation = bmgr.and(getExecPair(lock, unlock, ctx));
                        for (Event otherLock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_LOCK))) {
                            if (lock.getCId() < otherLock.getCId() && otherLock.getCId() < unlock.getCId()) {
                                relation = bmgr.and(relation, bmgr.not(this.getSMTVar(otherLock, unlock, ctx)));
                            }
                        }
                        for (Event otherUnlock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_UNLOCK))) {
                            if (lock.getCId() < otherUnlock.getCId() && otherUnlock.getCId() < unlock.getCId()) {
                                relation = bmgr.and(relation, bmgr.not(this.getSMTVar(lock, otherUnlock, ctx)));
                            }
                        }
                        enc = bmgr.and(enc, bmgr.equivalence(this.getSMTVar(tuple, ctx), relation));
                    }
                }
            }
        }
    }
    return enc;
}
Also used : BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) Event(com.dat3m.dartagnan.program.event.core.Event) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) Thread(com.dat3m.dartagnan.program.Thread)

Example 14 with Event

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

the class RelRMW method getMaxTupleSet.

@Override
public TupleSet getMaxTupleSet() {
    if (maxTupleSet == null) {
        logger.info("Computing maxTupleSet for " + getName());
        baseMaxTupleSet = new TupleSet();
        // RMWLoad -> RMWStore
        FilterAbstract filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), FilterBasic.get(Tag.WRITE));
        for (Event store : task.getProgram().getCache().getEvents(filter)) {
            if (store instanceof RMWStore) {
                baseMaxTupleSet.add(new Tuple(((RMWStore) store).getLoadEvent(), store));
            }
        }
        // Locks: Load -> Assume/CondJump -> Store
        FilterAbstract locks = FilterUnion.get(FilterBasic.get(Tag.C11.LOCK), FilterBasic.get(Tag.Linux.LOCK_READ));
        filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), locks);
        for (Event e : task.getProgram().getCache().getEvents(filter)) {
            // Connect Load to Store
            baseMaxTupleSet.add(new Tuple(e, e.getSuccessor().getSuccessor()));
        }
        // Atomics blocks: BeginAtomic -> EndAtomic
        filter = FilterIntersection.get(FilterBasic.get(Tag.RMW), FilterBasic.get(SVCOMPATOMIC));
        for (Event end : task.getProgram().getCache().getEvents(filter)) {
            List<Event> block = ((EndAtomic) end).getBlock().stream().filter(x -> x.is(Tag.VISIBLE)).collect(Collectors.toList());
            for (int i = 0; i < block.size(); i++) {
                for (int j = i + 1; j < block.size(); j++) {
                    baseMaxTupleSet.add(new Tuple(block.get(i), block.get(j)));
                }
            }
        }
        removeMutuallyExclusiveTuples(baseMaxTupleSet);
        maxTupleSet = new TupleSet();
        maxTupleSet.addAll(baseMaxTupleSet);
        // to find guaranteed pairs (the encoding can then also be improved)
        for (Thread thread : task.getProgram().getThreads()) {
            for (Event load : thread.getCache().getEvents(loadExclFilter)) {
                for (Event store : thread.getCache().getEvents(storeExclFilter)) {
                    if (load.getCId() < store.getCId()) {
                        maxTupleSet.add(new Tuple(load, store));
                    }
                }
            }
        }
        removeMutuallyExclusiveTuples(maxTupleSet);
        logger.info("maxTupleSet size for " + getName() + ": " + maxTupleSet.size());
    }
    return maxTupleSet;
}
Also used : SVCOMPATOMIC(com.dat3m.dartagnan.program.event.Tag.SVCOMP.SVCOMPATOMIC) BooleanType(org.sosy_lab.java_smt.api.FormulaType.BooleanType) FilterUnion(com.dat3m.dartagnan.program.filter.FilterUnion) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Thread(com.dat3m.dartagnan.program.Thread) FilterAbstract(com.dat3m.dartagnan.program.filter.FilterAbstract) EndAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) FilterIntersection(com.dat3m.dartagnan.program.filter.FilterIntersection) SolverContext(org.sosy_lab.java_smt.api.SolverContext) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) RMW(com.dat3m.dartagnan.wmm.relation.RelationNameRepository.RMW) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) Utils.generalEqual(com.dat3m.dartagnan.expression.utils.Utils.generalEqual) VerificationTask(com.dat3m.dartagnan.verification.VerificationTask) FormulaManager(org.sosy_lab.java_smt.api.FormulaManager) Collectors(java.util.stream.Collectors) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Sets(com.google.common.collect.Sets) Tag(com.dat3m.dartagnan.program.event.Tag) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) RMWStore(com.dat3m.dartagnan.program.event.core.rmw.RMWStore) Context(com.dat3m.dartagnan.verification.Context) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Event(com.dat3m.dartagnan.program.event.core.Event) StaticRelation(com.dat3m.dartagnan.wmm.relation.base.stat.StaticRelation) LogManager(org.apache.logging.log4j.LogManager) Flag(com.dat3m.dartagnan.wmm.utils.Flag) TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) FilterAbstract(com.dat3m.dartagnan.program.filter.FilterAbstract) RMWStore(com.dat3m.dartagnan.program.event.core.rmw.RMWStore) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) Thread(com.dat3m.dartagnan.program.Thread)

Example 15 with Event

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

the class BasicRegRelation method mkTupleSets.

private void mkTupleSets() {
    maxTupleSet = new TupleSet();
    minTupleSet = new TupleSet();
    Dependency dep = analysisContext.requires(Dependency.class);
    for (Event regReader : getEvents()) {
        for (Register register : getRegisters(regReader)) {
            Dependency.State r = dep.of(regReader, register);
            for (Event regWriter : r.may) {
                maxTupleSet.add(new Tuple(regWriter, regReader));
            }
            for (Event regWriter : r.must) {
                minTupleSet.add(new Tuple(regWriter, regReader));
            }
        }
    }
}
Also used : TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) Register(com.dat3m.dartagnan.program.Register) Event(com.dat3m.dartagnan.program.event.core.Event) Dependency(com.dat3m.dartagnan.program.analysis.Dependency) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple)

Aggregations

Event (com.dat3m.dartagnan.program.event.core.Event)104 Tuple (com.dat3m.dartagnan.wmm.utils.Tuple)34 Thread (com.dat3m.dartagnan.program.Thread)32 Register (com.dat3m.dartagnan.program.Register)25 TupleSet (com.dat3m.dartagnan.wmm.utils.TupleSet)25 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)20 Tag (com.dat3m.dartagnan.program.event.Tag)16 Label (com.dat3m.dartagnan.program.event.core.Label)16 Collectors (java.util.stream.Collectors)16 BooleanFormula (org.sosy_lab.java_smt.api.BooleanFormula)16 BooleanFormulaManager (org.sosy_lab.java_smt.api.BooleanFormulaManager)16 LogManager (org.apache.logging.log4j.LogManager)15 Logger (org.apache.logging.log4j.Logger)15 Program (com.dat3m.dartagnan.program.Program)12 ExecutionAnalysis (com.dat3m.dartagnan.program.analysis.ExecutionAnalysis)12 RegWriter (com.dat3m.dartagnan.program.event.core.utils.RegWriter)12 java.util (java.util)12 SolverContext (org.sosy_lab.java_smt.api.SolverContext)12 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)11 CondJump (com.dat3m.dartagnan.program.event.core.CondJump)10