Search in sources :

Example 1 with Load

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

the class WitnessBuilder method build.

public WitnessGraph build() {
    for (Thread t : task.getProgram().getThreads()) {
        for (Event e : t.getEntry().getSuccessors()) {
            eventThreadMap.put(e, t.getId() - 1);
        }
    }
    WitnessGraph graph = new WitnessGraph();
    graph.addAttribute(UNROLLBOUND.toString(), valueOf(task.getProgram().getUnrollingBound()));
    graph.addAttribute(WITNESSTYPE.toString(), type + "_witness");
    graph.addAttribute(SOURCECODELANG.toString(), "C");
    graph.addAttribute(PRODUCER.toString(), "Dartagnan");
    graph.addAttribute(SPECIFICATION.toString(), "CHECK( init(main()), LTL(G ! call(reach_error())))");
    graph.addAttribute(PROGRAMFILE.toString(), originalProgramFilePath);
    graph.addAttribute(PROGRAMHASH.toString(), getFileSHA256(new File(originalProgramFilePath)));
    graph.addAttribute(ARCHITECTURE.toString(), "32bit");
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    // "If the timestamp is in UTC time, it ends with a 'Z'."
    // https://github.com/sosy-lab/sv-witnesses/blob/main/README-GraphML.md
    graph.addAttribute(CREATIONTIME.toString(), df.format(new Date()) + "Z");
    Node v0 = new Node("N0");
    v0.addAttribute("entry", "true");
    Node v1 = new Node("N1");
    Node v2 = new Node("N2");
    Edge edge = new Edge(v0, v1);
    edge.addAttribute(CREATETHREAD.toString(), "0");
    graph.addEdge(edge);
    edge = new Edge(v1, v2);
    edge.addAttribute(THREADID.toString(), "0");
    edge.addAttribute(ENTERFUNCTION.toString(), "main");
    graph.addEdge(edge);
    int nextNode = 2;
    int threads = 1;
    if (type.equals("correctness")) {
        return graph;
    }
    try (Model model = prover.getModel()) {
        List<Event> execution = reOrderBasedOnAtomicity(task.getProgram(), getSCExecutionOrder(model));
        for (int i = 0; i < execution.size(); i++) {
            Event e = execution.get(i);
            if (i + 1 < execution.size()) {
                Event next = execution.get(i + 1);
                if (e.getCLine() == next.getCLine() && e.getThread() == next.getThread()) {
                    continue;
                }
            }
            edge = new Edge(new Node("N" + nextNode), new Node("N" + (nextNode + 1)));
            edge.addAttribute(THREADID.toString(), valueOf(eventThreadMap.get(e)));
            edge.addAttribute(STARTLINE.toString(), valueOf(e.getCLine()));
            // CLines and thus won't create an edge (as expected)
            if (e.hasFilter(WRITE) && e.hasFilter(PTHREAD)) {
                edge.addAttribute(CREATETHREAD.toString(), valueOf(threads));
                threads++;
            }
            if (e instanceof Load) {
                RegWriter l = (RegWriter) e;
                edge.addAttribute(EVENTID.toString(), valueOf(e.getUId()));
                edge.addAttribute(LOADEDVALUE.toString(), l.getWrittenValue(e, model, ctx).toString());
            }
            if (e instanceof Store) {
                Store s = (Store) e;
                edge.addAttribute(EVENTID.toString(), valueOf(e.getUId()));
                edge.addAttribute(STOREDVALUE.toString(), s.getMemValue().getIntValue(s, model, ctx).toString());
            }
            graph.addEdge(edge);
            nextNode++;
            if (e.hasFilter(Tag.ASSERTION)) {
                break;
            }
        }
    } catch (SolverException ignore) {
    // The if above guarantees that if we reach this try, a Model exists
    }
    graph.getNode("N" + nextNode).addAttribute("violation", "true");
    return graph;
}
Also used : Load(com.dat3m.dartagnan.program.event.core.Load) Store(com.dat3m.dartagnan.program.event.core.Store) Thread(com.dat3m.dartagnan.program.Thread) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) SimpleDateFormat(java.text.SimpleDateFormat) DateFormat(java.text.DateFormat) Model(org.sosy_lab.java_smt.api.Model) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) SolverException(org.sosy_lab.java_smt.api.SolverException) File(java.io.File) SimpleDateFormat(java.text.SimpleDateFormat)

Example 2 with Load

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

the class WitnessGraph method encode.

public BooleanFormula encode(Program program, SolverContext ctx) {
    BooleanFormulaManager bmgr = ctx.getFormulaManager().getBooleanFormulaManager();
    IntegerFormulaManager imgr = ctx.getFormulaManager().getIntegerFormulaManager();
    BooleanFormula enc = bmgr.makeTrue();
    List<Event> previous = new ArrayList<>();
    for (Edge edge : edges.stream().filter(Edge::hasCline).collect(Collectors.toList())) {
        List<Event> events = program.getCache().getEvents(FilterBasic.get(MEMORY)).stream().filter(e -> e.getCLine() == edge.getCline()).collect(Collectors.toList());
        if (!previous.isEmpty() && !events.isEmpty()) {
            enc = bmgr.and(enc, bmgr.or(Lists.cartesianProduct(previous, events).stream().map(p -> edge("hb", p.get(0), p.get(1), ctx)).toArray(BooleanFormula[]::new)));
        }
        if (!events.isEmpty()) {
            previous = events;
        }
        if (edge.hasAttributed(EVENTID.toString()) && edge.hasAttributed(LOADEDVALUE.toString())) {
            int id = Integer.parseInt(edge.getAttributed(EVENTID.toString()));
            if (program.getCache().getEvents(FilterBasic.get(READ)).stream().anyMatch(e -> e.getUId() == id)) {
                Load load = (Load) program.getCache().getEvents(FilterBasic.get(READ)).stream().filter(e -> e.getUId() == id).findFirst().get();
                BigInteger value = new BigInteger(edge.getAttributed(LOADEDVALUE.toString()));
                enc = bmgr.and(enc, generalEqual(load.getResultRegisterExpr(), imgr.makeNumber(value), ctx));
            }
        }
        if (edge.hasAttributed(EVENTID.toString()) && edge.hasAttributed(STOREDVALUE.toString())) {
            int id = Integer.parseInt(edge.getAttributed(EVENTID.toString()));
            if (program.getCache().getEvents(FilterBasic.get(WRITE)).stream().anyMatch(e -> e.getUId() == id)) {
                Store store = (Store) program.getCache().getEvents(FilterBasic.get(WRITE)).stream().filter(e -> e.getUId() == id).findFirst().get();
                BigInteger value = new BigInteger(edge.getAttributed(STOREDVALUE.toString()));
                enc = bmgr.and(enc, generalEqual(store.getMemValueExpr(), imgr.makeNumber(value), ctx));
            }
        }
    }
    return enc;
}
Also used : java.util(java.util) Store(com.dat3m.dartagnan.program.event.core.Store) PROGRAMFILE(com.dat3m.dartagnan.witness.GraphAttributes.PROGRAMFILE) FileWriter(java.io.FileWriter) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) EdgeAttributes(com.dat3m.dartagnan.witness.EdgeAttributes) Utils.edge(com.dat3m.dartagnan.wmm.utils.Utils.edge) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) IntegerFormulaManager(org.sosy_lab.java_smt.api.IntegerFormulaManager) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) Tag(com.dat3m.dartagnan.program.event.Tag) Lists(com.google.common.collect.Lists) Files(com.google.common.io.Files) SolverContext(org.sosy_lab.java_smt.api.SolverContext) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) BigInteger(java.math.BigInteger) Load(com.dat3m.dartagnan.program.event.core.Load) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) Utils.generalEqual(com.dat3m.dartagnan.expression.utils.Utils.generalEqual) Load(com.dat3m.dartagnan.program.event.core.Load) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) Event(com.dat3m.dartagnan.program.event.core.Event) BigInteger(java.math.BigInteger) Store(com.dat3m.dartagnan.program.event.core.Store) IntegerFormulaManager(org.sosy_lab.java_smt.api.IntegerFormulaManager) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula)

Example 3 with Load

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

the class RelRf method atomicBlockOptimization.

private void atomicBlockOptimization() {
    // TODO: This function can not only reduce rf-edges
    // but we could also figure out implied coherences:
    // Assume w1 and w2 are aliasing in the same block and w1 is before w2,
    // then if w1 is co-before some external w3, then so is w2, i.e.
    // co(w1, w3) => co(w2, w3), but we also have co(w2, w3) => co(w1, w3)
    // so co(w1, w3) <=> co(w2, w3).
    // This information is not expressible in terms of min/must sets, but
    // we could still encode it.
    int sizeBefore = maxTupleSet.size();
    // Atomics blocks: BeginAtomic -> EndAtomic
    ExecutionAnalysis exec = analysisContext.get(ExecutionAnalysis.class);
    AliasAnalysis alias = analysisContext.get(AliasAnalysis.class);
    FilterAbstract filter = FilterIntersection.get(FilterBasic.get(RMW), FilterBasic.get(SVCOMP.SVCOMPATOMIC));
    for (Event end : task.getProgram().getCache().getEvents(filter)) {
        // Collect memEvents of the atomic block
        List<Store> writes = new ArrayList<>();
        List<Load> reads = new ArrayList<>();
        EndAtomic endAtomic = (EndAtomic) end;
        for (Event b : endAtomic.getBlock()) {
            if (b instanceof Load) {
                reads.add((Load) b);
            } else if (b instanceof Store) {
                writes.add((Store) b);
            }
        }
        for (Load r : reads) {
            // If there is any write w inside the atomic block that is guaranteed to
            // execute before the read and that aliases with it,
            // then the read won't be able to read any external writes
            boolean hasImpliedWrites = writes.stream().anyMatch(w -> w.getCId() < r.getCId() && exec.isImplied(r, w) && alias.mustAlias(r, w));
            if (hasImpliedWrites) {
                maxTupleSet.removeIf(t -> t.getSecond() == r && t.isCrossThread());
            }
        }
    }
    logger.info("Atomic block optimization eliminated " + (sizeBefore - maxTupleSet.size()) + " reads");
}
Also used : Load(com.dat3m.dartagnan.program.event.core.Load) EndAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) FilterAbstract(com.dat3m.dartagnan.program.filter.FilterAbstract) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) Store(com.dat3m.dartagnan.program.event.core.Store) AliasAnalysis(com.dat3m.dartagnan.program.analysis.AliasAnalysis)

Example 4 with Load

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

the class UnrollExceptionsTest method RMWStore.

// These events cannot be unrolled. They are generated during compilation.
@Test(expected = ProgramProcessingException.class)
public void RMWStore() throws Exception {
    ProgramBuilder pb = new ProgramBuilder(SourceLanguage.LITMUS);
    pb.initThread(0);
    MemoryObject object = pb.getOrNewObject("X");
    Label start = pb.getOrCreateLabel("loopStart");
    pb.addChild(0, start);
    Load load = EventFactory.newRMWLoad(pb.getOrCreateRegister(0, "r1", 32), object, null);
    pb.addChild(0, EventFactory.newRMWStore(load, object, IValue.ONE, null));
    pb.addChild(0, EventFactory.newGoto(start));
    LoopUnrolling processor = LoopUnrolling.newInstance();
    processor.setUnrollingBound(2);
    processor.run(pb.build());
}
Also used : Load(com.dat3m.dartagnan.program.event.core.Load) ProgramBuilder(com.dat3m.dartagnan.parsers.program.utils.ProgramBuilder) MemoryObject(com.dat3m.dartagnan.program.memory.MemoryObject) Label(com.dat3m.dartagnan.program.event.core.Label) LoopUnrolling(com.dat3m.dartagnan.program.processing.LoopUnrolling) Test(org.junit.Test)

Example 5 with Load

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

the class VisitorBase method visitRMW.

@Override
public List<Event> visitRMW(RMW e) {
    Register resultRegister = e.getResultRegister();
    IExpr address = e.getAddress();
    String mo = e.getMo();
    Register dummyReg = e.getThread().newRegister(resultRegister.getPrecision());
    Load load = newRMWLoad(dummyReg, address, mo);
    RMWStore store = newRMWStore(load, address, e.getMemValue(), mo);
    return eventSequence(load, store, newLocal(resultRegister, dummyReg));
}
Also used : Load(com.dat3m.dartagnan.program.event.core.Load) Register(com.dat3m.dartagnan.program.Register) RMWStore(com.dat3m.dartagnan.program.event.core.rmw.RMWStore) IExpr(com.dat3m.dartagnan.expression.IExpr)

Aggregations

Load (com.dat3m.dartagnan.program.event.core.Load)7 Event (com.dat3m.dartagnan.program.event.core.Event)4 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)3 Store (com.dat3m.dartagnan.program.event.core.Store)3 Utils.generalEqual (com.dat3m.dartagnan.expression.utils.Utils.generalEqual)2 Program (com.dat3m.dartagnan.program.Program)2 Register (com.dat3m.dartagnan.program.Register)2 Thread (com.dat3m.dartagnan.program.Thread)2 AliasAnalysis (com.dat3m.dartagnan.program.analysis.AliasAnalysis)2 Tag (com.dat3m.dartagnan.program.event.Tag)2 Label (com.dat3m.dartagnan.program.event.core.Label)2 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)2 Utils.edge (com.dat3m.dartagnan.wmm.utils.Utils.edge)2 BigInteger (java.math.BigInteger)2 Collectors (java.util.stream.Collectors)2 BooleanFormula (org.sosy_lab.java_smt.api.BooleanFormula)2 BooleanFormulaManager (org.sosy_lab.java_smt.api.BooleanFormulaManager)2 IntegerFormulaManager (org.sosy_lab.java_smt.api.IntegerFormulaManager)2 SolverContext (org.sosy_lab.java_smt.api.SolverContext)2 Property (com.dat3m.dartagnan.configuration.Property)1