Search in sources :

Example 1 with Load

use of dartagnan.program.Load in project Dat3M by hernanponcedeleon.

the class Domain method encode.

public static BoolExpr encode(Program program, Context ctx) throws Z3Exception {
    BoolExpr enc = ctx.mkTrue();
    Set<Event> mEvents = program.getEvents().stream().filter(e -> e instanceof MemEvent).collect(Collectors.toSet());
    Set<Event> barriers = program.getEvents().stream().filter(e -> e instanceof Barrier).collect(Collectors.toSet());
    Set<Event> eventsL = program.getEvents().stream().filter(e -> e instanceof MemEvent || e instanceof Local).collect(Collectors.toSet());
    for (Event e : eventsL) {
        enc = ctx.mkAnd(enc, ctx.mkNot(edge("ii", e, e, ctx)));
        enc = ctx.mkAnd(enc, ctx.mkNot(edge("ic", e, e, ctx)));
        enc = ctx.mkAnd(enc, ctx.mkNot(edge("ci", e, e, ctx)));
        enc = ctx.mkAnd(enc, ctx.mkNot(edge("cc", e, e, ctx)));
    }
    for (Event e1 : mEvents) {
        for (Event e2 : mEvents) {
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("rf", e1, e2, ctx), ctx.mkAnd(e1.executes(ctx), e2.executes(ctx))));
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("co", e1, e2, ctx), ctx.mkAnd(e1.executes(ctx), e2.executes(ctx))));
            if (!(e1 instanceof Init)) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("IM", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("IW", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("IR", e1, e2, ctx)));
            } else {
                enc = ctx.mkAnd(enc, edge("IM", e1, e2, ctx));
            }
            if (!(e2 instanceof Init)) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("MI", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("WI", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("RI", e1, e2, ctx)));
            } else {
                enc = ctx.mkAnd(enc, edge("MI", e1, e2, ctx));
            }
            if (!(e1 instanceof Load)) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("RM", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("RW", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("RR", e1, e2, ctx)));
            } else {
                enc = ctx.mkAnd(enc, edge("RM", e1, e2, ctx));
            }
            if (!(e2 instanceof Load)) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("MR", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("WR", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("RR", e1, e2, ctx)));
            } else {
                enc = ctx.mkAnd(enc, edge("MR", e1, e2, ctx));
            }
            if (!(e1 instanceof Store || e1 instanceof Init)) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("WM", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("WW", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("WR", e1, e2, ctx)));
            } else {
                enc = ctx.mkAnd(enc, edge("WM", e1, e2, ctx));
            }
            if (!(e2 instanceof Store || e2 instanceof Init)) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("MW", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("WW", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("RW", e1, e2, ctx)));
            } else {
                enc = ctx.mkAnd(enc, edge("MW", e1, e2, ctx));
            }
            if (e1 instanceof Load && e2 instanceof Load) {
                enc = ctx.mkAnd(enc, edge("RR", e1, e2, ctx));
            }
            if (e1 instanceof Load && (e2 instanceof Init || e2 instanceof Store)) {
                enc = ctx.mkAnd(enc, edge("RW", e1, e2, ctx));
            }
            if ((e1 instanceof Init || e1 instanceof Store) && (e2 instanceof Init || e2 instanceof Store)) {
                enc = ctx.mkAnd(enc, edge("WW", e1, e2, ctx));
            }
            if ((e1 instanceof Init || e1 instanceof Store) && e2 instanceof Load) {
                enc = ctx.mkAnd(enc, edge("WR", e1, e2, ctx));
            }
            if (e1 == e2) {
                enc = ctx.mkAnd(enc, edge("id", e1, e2, ctx));
            } else {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("id", e1, e2, ctx)));
            }
            if (e1.getMainThread() == e2.getMainThread()) {
                enc = ctx.mkAnd(enc, edge("int", e1, e2, ctx));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("ext", e1, e2, ctx)));
                if (e1.getEId() < e2.getEId()) {
                    enc = ctx.mkAnd(enc, edge("po", e1, e2, ctx));
                    if (e1.getCondLevel() < e2.getCondLevel() && e1 instanceof Load && e2.getCondRegs().contains(e1.getReg())) {
                        enc = ctx.mkAnd(enc, edge("ctrlDirect", e1, e2, ctx));
                    } else {
                        enc = ctx.mkAnd(enc, ctx.mkNot(edge("ctrlDirect", e1, e2, ctx)));
                    }
                } else {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("po", e1, e2, ctx)));
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("ctrl", e1, e2, ctx)));
                }
                boolean noMfence = true;
                boolean noSync = true;
                boolean noLwsync = true;
                boolean noIsync = true;
                boolean noIsh = true;
                boolean noIsb = true;
                for (Event b : barriers.stream().filter(e -> e.getMainThread() == e1.getMainThread() && e1.getEId() < e.getEId() && e.getEId() < e2.getEId()).collect(Collectors.toSet())) {
                    if (b instanceof Mfence) {
                        noMfence = false;
                    }
                    if (b instanceof Sync) {
                        noSync = false;
                    }
                    if (b instanceof Lwsync) {
                        noLwsync = false;
                    }
                    if (b instanceof Isync) {
                        noIsync = false;
                    }
                    if (b instanceof Ish) {
                        noIsh = false;
                    }
                    if (b instanceof Isb) {
                        noIsb = false;
                    }
                }
                if (noMfence) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("mfence", e1, e2, ctx)));
                }
                if (noSync) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("sync", e1, e2, ctx)));
                }
                if (noLwsync) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("lwsync", e1, e2, ctx)));
                }
                if (noIsync) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("isync", e1, e2, ctx)));
                }
                if (noIsh) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("ish", e1, e2, ctx)));
                }
                if (noIsb) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("isb", e1, e2, ctx)));
                }
            } else {
                enc = ctx.mkAnd(enc, edge("ext", e1, e2, ctx));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("int", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("po", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("ctrl", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("ii", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("ic", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("ci", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("cc", e1, e2, ctx)));
            }
            if (e1.getLoc() == e2.getLoc()) {
                enc = ctx.mkAnd(enc, edge("loc", e1, e2, ctx));
            } else {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("loc", e1, e2, ctx)));
            }
            if (!((e1 instanceof Store || e1 instanceof Init) && e2 instanceof Load && e1.getLoc() == e2.getLoc())) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("rf", e1, e2, ctx)));
            }
            if (!((e1 instanceof Store || e1 instanceof Init) && (e2 instanceof Store || e2 instanceof Init) && e1.getLoc() == e2.getLoc())) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("co", e1, e2, ctx)));
            }
            if (!(e1.getMainThread() == e2.getMainThread() && e1.getEId() < e2.getEId())) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("mfence", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("sync", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("lwsync", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("isync", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("ish", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("isb", e1, e2, ctx)));
            }
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("rfe", e1, e2, ctx), ctx.mkAnd(edge("rf", e1, e2, ctx), edge("ext", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("rfi", e1, e2, ctx), ctx.mkAnd(edge("rf", e1, e2, ctx), edge("int", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("coe", e1, e2, ctx), ctx.mkAnd(edge("co", e1, e2, ctx), edge("ext", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("coi", e1, e2, ctx), ctx.mkAnd(edge("co", e1, e2, ctx), edge("int", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("fre", e1, e2, ctx), ctx.mkAnd(edge("fr", e1, e2, ctx), edge("ext", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("fri", e1, e2, ctx), ctx.mkAnd(edge("fr", e1, e2, ctx), edge("int", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("poloc", e1, e2, ctx), ctx.mkAnd(edge("po", e1, e2, ctx), edge("loc", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("ctrlisync", e1, e2, ctx), ctx.mkAnd(edge("ctrl", e1, e2, ctx), edge("isync", e1, e2, ctx))));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("ctrlisb", e1, e2, ctx), ctx.mkAnd(edge("ctrl", e1, e2, ctx), edge("isb", e1, e2, ctx))));
        }
    }
    for (Event e1 : mEvents) {
        for (Event e2 : mEvents) {
            BoolExpr mfences = ctx.mkFalse();
            BoolExpr syncs = ctx.mkFalse();
            BoolExpr lwsyncs = ctx.mkFalse();
            BoolExpr isyncs = ctx.mkFalse();
            BoolExpr ishs = ctx.mkFalse();
            BoolExpr isbs = ctx.mkFalse();
            for (Event b : barriers) {
                if (b instanceof Mfence && e1.getMainThread() == b.getMainThread() && b.getMainThread() == e2.getMainThread() && e1.getEId() < b.getEId() && b.getEId() < e2.getEId()) {
                    mfences = ctx.mkOr(mfences, b.executes(ctx));
                    enc = ctx.mkAnd(enc, ctx.mkImplies(ctx.mkAnd(e1.executes(ctx), ctx.mkAnd(b.executes(ctx), e2.executes(ctx))), edge("mfence", e1, e2, ctx)));
                }
                if (b instanceof Sync && e1.getMainThread() == b.getMainThread() && b.getMainThread() == e2.getMainThread() && e1.getEId() < b.getEId() && b.getEId() < e2.getEId()) {
                    syncs = ctx.mkOr(syncs, b.executes(ctx));
                    enc = ctx.mkAnd(enc, ctx.mkImplies(ctx.mkAnd(e1.executes(ctx), ctx.mkAnd(b.executes(ctx), e2.executes(ctx))), edge("sync", e1, e2, ctx)));
                }
                if (b instanceof Lwsync && e1.getMainThread() == b.getMainThread() && b.getMainThread() == e2.getMainThread() && e1.getEId() < b.getEId() && b.getEId() < e2.getEId()) {
                    lwsyncs = ctx.mkOr(lwsyncs, b.executes(ctx));
                    enc = ctx.mkAnd(enc, ctx.mkImplies(ctx.mkAnd(e1.executes(ctx), ctx.mkAnd(b.executes(ctx), e2.executes(ctx))), edge("lwsync", e1, e2, ctx)));
                }
                if (b instanceof Isync && e1.getMainThread() == b.getMainThread() && b.getMainThread() == e2.getMainThread() && e1.getEId() < b.getEId() && b.getEId() < e2.getEId()) {
                    isyncs = ctx.mkOr(isyncs, b.executes(ctx));
                    enc = ctx.mkAnd(enc, ctx.mkImplies(ctx.mkAnd(e1.executes(ctx), ctx.mkAnd(b.executes(ctx), e2.executes(ctx))), edge("isync", e1, e2, ctx)));
                }
                if (b instanceof Ish && e1.getMainThread() == b.getMainThread() && b.getMainThread() == e2.getMainThread() && e1.getEId() < b.getEId() && b.getEId() < e2.getEId()) {
                    ishs = ctx.mkOr(ishs, b.executes(ctx));
                    enc = ctx.mkAnd(enc, ctx.mkImplies(ctx.mkAnd(e1.executes(ctx), ctx.mkAnd(b.executes(ctx), e2.executes(ctx))), edge("ish", e1, e2, ctx)));
                }
                if (b instanceof Isb && e1.getMainThread() == b.getMainThread() && b.getMainThread() == e2.getMainThread() && e1.getEId() < b.getEId() && b.getEId() < e2.getEId()) {
                    isbs = ctx.mkOr(isbs, b.executes(ctx));
                    enc = ctx.mkAnd(enc, ctx.mkImplies(ctx.mkAnd(e1.executes(ctx), ctx.mkAnd(b.executes(ctx), e2.executes(ctx))), edge("isb", e1, e2, ctx)));
                }
            }
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("mfence", e1, e2, ctx), mfences));
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("sync", e1, e2, ctx), syncs));
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("lwsync", e1, e2, ctx), lwsyncs));
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("isync", e1, e2, ctx), isyncs));
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("ish", e1, e2, ctx), ishs));
            enc = ctx.mkAnd(enc, ctx.mkImplies(edge("isb", e1, e2, ctx), isbs));
        }
    }
    for (Event e1 : eventsL) {
        for (Event e2 : eventsL) {
            if (e1.getMainThread() != e2.getMainThread() || e2.getEId() < e1.getEId() || e1 == e2) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", e1, e2, ctx)));
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("data", e1, e2, ctx)));
            }
            if (e2 instanceof Store) {
                if (!e2.getLastModMap().get(e2.getReg()).contains(e1)) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", e1, e2, ctx)));
                }
            }
            if (e2 instanceof Load) {
                if (!e2.getLastModMap().keySet().contains(e2.getLoc())) {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", e1, e2, ctx)));
                }
            }
            if (e2 instanceof Local && e2.getExpr() instanceof AConst) {
                enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", e1, e2, ctx)));
            }
        }
    }
    for (Event e : eventsL) {
        if (e instanceof Store) {
            BoolExpr orClause = ctx.mkFalse();
            for (Event x : eventsL) {
                if (e.getLastModMap().get(e.getReg()).contains(x)) {
                    orClause = ctx.mkOr(orClause, edge("idd", x, e, ctx));
                } else {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", x, e, ctx)));
                }
            }
            enc = ctx.mkAnd(enc, orClause);
        }
        if (e instanceof Load) {
            if (!e.getLastModMap().keySet().contains(e.getLoc())) {
                continue;
            }
            BoolExpr orClause = ctx.mkFalse();
            for (Event x : eventsL) {
                if (e.getLastModMap().get(e.getLoc()).contains(x)) {
                    orClause = ctx.mkOr(orClause, edge("idd", x, e, ctx));
                } else {
                    enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", x, e, ctx)));
                }
            }
            enc = ctx.mkAnd(enc, orClause);
        }
        if (e instanceof Local) {
            for (Register reg : e.getExpr().getRegs()) {
                BoolExpr orClause = ctx.mkFalse();
                for (Event x : eventsL) {
                    if (e.getLastModMap().get(reg).contains(x)) {
                        orClause = ctx.mkOr(orClause, edge("idd", x, e, ctx));
                    } else {
                        enc = ctx.mkAnd(enc, ctx.mkNot(edge("idd", x, e, ctx)));
                    }
                }
                enc = ctx.mkAnd(enc, orClause);
            }
        }
    }
    for (Event e1 : mEvents) {
        for (Event e2 : mEvents) {
            BoolExpr ctrlClause = edge("ctrlDirect", e1, e2, ctx);
            BoolExpr orClause = ctx.mkFalse();
            for (Event e3 : mEvents) {
                ctrlClause = ctx.mkOr(ctrlClause, ctx.mkAnd(edge("ctrl", e1, e3, ctx), edge("po", e3, e2, ctx)));
                orClause = ctx.mkOr(orClause, ctx.mkAnd(edge("rf", e3, e1, ctx), edge("co", e3, e2, ctx)));
            }
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("fr", e1, e2, ctx), orClause));
            enc = ctx.mkAnd(enc, ctx.mkEq(edge("ctrl", e1, e2, ctx), ctrlClause));
        }
    }
    Set<Location> locs = mEvents.stream().filter(e -> e instanceof MemEvent).map(e -> e.getLoc()).collect(Collectors.toSet());
    for (Location loc : locs) {
        Set<Event> writesEventsLoc = mEvents.stream().filter(e -> (e instanceof Store || e instanceof Init) && e.getLoc() == loc).collect(Collectors.toSet());
        enc = ctx.mkAnd(enc, satTO("co", writesEventsLoc, ctx));
    }
    for (Event e : mEvents.stream().filter(e -> e instanceof Init).collect(Collectors.toSet())) {
        enc = ctx.mkAnd(enc, ctx.mkEq(intVar("co", e, ctx), ctx.mkInt(1)));
    }
    for (Event w1 : mEvents.stream().filter(e -> e instanceof Init || e instanceof Store).collect(Collectors.toSet())) {
        Set<Event> writeSameLoc = mEvents.stream().filter(e -> (e instanceof Init || e instanceof Store) && w1.getLoc() == e.getLoc()).collect(Collectors.toSet());
        BoolExpr lastCoOrder = w1.executes(ctx);
        for (Event w2 : writeSameLoc) {
            lastCoOrder = ctx.mkAnd(lastCoOrder, ctx.mkNot(edge("co", w1, w2, ctx)));
        }
        enc = ctx.mkAnd(enc, ctx.mkImplies(lastCoOrder, ctx.mkEq(lastValueLoc(w1.getLoc(), ctx), ((MemEvent) w1).ssaLoc)));
    }
    for (Event r1 : eventsL.stream().filter(e -> e instanceof Load || e instanceof Local).collect(Collectors.toSet())) {
        Set<Event> modRegLater = eventsL.stream().filter(e -> (e instanceof Load || e instanceof Local) && r1.getReg() == e.getReg() && r1.getEId() < e.getEId()).collect(Collectors.toSet());
        BoolExpr lastModReg = r1.executes(ctx);
        for (Event r2 : modRegLater) {
            lastModReg = ctx.mkAnd(lastModReg, ctx.mkNot(r2.executes(ctx)));
        }
        enc = ctx.mkAnd(enc, ctx.mkImplies(lastModReg, ctx.mkEq(lastValueReg(r1.getReg(), ctx), ssaReg(r1.getReg(), r1.getSsaRegIndex(), ctx))));
    }
    for (Event e : mEvents.stream().filter(e -> e instanceof Load).collect(Collectors.toSet())) {
        Set<Event> storeEventsLoc = mEvents.stream().filter(x -> (x instanceof Store || x instanceof Init) && e.getLoc() == x.getLoc()).collect(Collectors.toSet());
        Set<BoolExpr> rfPairs = new HashSet<BoolExpr>();
        for (Event w : storeEventsLoc) {
            rfPairs.add(edge("rf", w, e, ctx));
        }
        enc = ctx.mkAnd(enc, ctx.mkImplies(e.executes(ctx), encodeEO(rfPairs, ctx)));
    }
    return enc;
}
Also used : Utils.lastValueReg(dartagnan.utils.Utils.lastValueReg) EncodingsCAT.encodeEO(dartagnan.wmm.EncodingsCAT.encodeEO) Lwsync(dartagnan.program.Lwsync) Utils.intVar(dartagnan.utils.Utils.intVar) Barrier(dartagnan.program.Barrier) AConst(dartagnan.expression.AConst) Mfence(dartagnan.program.Mfence) HashSet(java.util.HashSet) Ish(dartagnan.program.Ish) Register(dartagnan.program.Register) Load(dartagnan.program.Load) MemEvent(dartagnan.program.MemEvent) Isb(dartagnan.program.Isb) Program(dartagnan.program.Program) Utils.edge(dartagnan.utils.Utils.edge) Store(dartagnan.program.Store) Location(dartagnan.program.Location) Sync(dartagnan.program.Sync) com.microsoft.z3(com.microsoft.z3) Event(dartagnan.program.Event) EncodingsCAT.satTO(dartagnan.wmm.EncodingsCAT.satTO) Set(java.util.Set) Collectors(java.util.stream.Collectors) Init(dartagnan.program.Init) Local(dartagnan.program.Local) Isync(dartagnan.program.Isync) Utils.ssaReg(dartagnan.utils.Utils.ssaReg) Utils.lastValueLoc(dartagnan.utils.Utils.lastValueLoc) Load(dartagnan.program.Load) Local(dartagnan.program.Local) Store(dartagnan.program.Store) Barrier(dartagnan.program.Barrier) AConst(dartagnan.expression.AConst) Init(dartagnan.program.Init) Lwsync(dartagnan.program.Lwsync) Register(dartagnan.program.Register) MemEvent(dartagnan.program.MemEvent) Mfence(dartagnan.program.Mfence) MemEvent(dartagnan.program.MemEvent) Event(dartagnan.program.Event) Isb(dartagnan.program.Isb) Sync(dartagnan.program.Sync) Isync(dartagnan.program.Isync) Ish(dartagnan.program.Ish) Location(dartagnan.program.Location) HashSet(java.util.HashSet)

Example 2 with Load

use of dartagnan.program.Load in project Dat3M by hernanponcedeleon.

the class Encodings method encodeReachedState.

public static BoolExpr encodeReachedState(Program p, Model model, Context ctx) {
    Set<Location> locs = p.getEvents().stream().filter(e -> e instanceof MemEvent).map(e -> e.getLoc()).collect(Collectors.toSet());
    BoolExpr reachedState = ctx.mkTrue();
    for (Location loc : locs) {
        reachedState = ctx.mkAnd(reachedState, ctx.mkEq(ctx.mkIntConst(loc.getName() + "_final"), model.getConstInterp(ctx.mkIntConst(loc.getName() + "_final"))));
    }
    Set<Event> executedEvents = p.getEvents().stream().filter(e -> model.getConstInterp(e.executes(ctx)).isTrue()).collect(Collectors.toSet());
    Set<Register> regs = executedEvents.stream().filter(e -> e instanceof Local | e instanceof Load).map(e -> e.getReg()).collect(Collectors.toSet());
    for (Register reg : regs) {
        Set<Integer> ssaRegIndexes = new HashSet<Integer>();
        for (Event e : executedEvents) {
            if (!(e instanceof Load | e instanceof Local)) {
                continue;
            }
            if (e.getReg() != reg) {
                continue;
            }
            ssaRegIndexes.add(e.getSsaRegIndex());
        }
        Integer lastRegIndex = Collections.max(ssaRegIndexes);
        String regVarName = String.format("T%s_%s_%s", reg.getMainThread(), reg.getName(), lastRegIndex);
        reachedState = ctx.mkAnd(reachedState, ctx.mkEq(ctx.mkIntConst(regVarName), model.getConstInterp(ctx.mkIntConst(regVarName))));
    }
    return reachedState;
}
Also used : IntStream(java.util.stream.IntStream) com.microsoft.z3(com.microsoft.z3) Event(dartagnan.program.Event) Set(java.util.Set) Assert(dartagnan.expression.Assert) Utils(dartagnan.utils.Utils) Collectors(java.util.stream.Collectors) Init(dartagnan.program.Init) HashSet(java.util.HashSet) Register(dartagnan.program.Register) Local(dartagnan.program.Local) Load(dartagnan.program.Load) MemEvent(dartagnan.program.MemEvent) Program(dartagnan.program.Program) Collections(java.util.Collections) Store(dartagnan.program.Store) Location(dartagnan.program.Location) Load(dartagnan.program.Load) Local(dartagnan.program.Local) Register(dartagnan.program.Register) MemEvent(dartagnan.program.MemEvent) Event(dartagnan.program.Event) MemEvent(dartagnan.program.MemEvent) Location(dartagnan.program.Location) HashSet(java.util.HashSet)

Example 3 with Load

use of dartagnan.program.Load in project Dat3M by hernanponcedeleon.

the class Encodings method encodeCommonExecutions.

public static BoolExpr encodeCommonExecutions(Program p1, Program p2, Context ctx) throws Z3Exception {
    BoolExpr enc = ctx.mkTrue();
    Set<Event> lEventsP1 = p1.getEvents().stream().filter(e -> e instanceof MemEvent | e instanceof Local).collect(Collectors.toSet());
    Set<Event> lEventsP2 = p2.getEvents().stream().filter(e -> e instanceof MemEvent | e instanceof Local).collect(Collectors.toSet());
    Set<Event> rEventsP1 = p1.getEvents().stream().filter(e -> e instanceof Load).collect(Collectors.toSet());
    Set<Event> wEventsP1 = p1.getEvents().stream().filter(e -> e instanceof Store || e instanceof Init).collect(Collectors.toSet());
    Set<Event> rEventsP2 = p2.getEvents().stream().filter(e -> e instanceof Load).collect(Collectors.toSet());
    Set<Event> wEventsP2 = p2.getEvents().stream().filter(e -> e instanceof Store || e instanceof Init).collect(Collectors.toSet());
    for (Event e1 : lEventsP1) {
        for (Event e2 : lEventsP2) {
            if (e1.getHLId().equals(e2.getHLId())) {
                enc = ctx.mkAnd(enc, ctx.mkEq(e1.executes(ctx), e2.executes(ctx)));
            }
        }
    }
    for (Event r1 : rEventsP1) {
        for (Event r2 : rEventsP2) {
            if (r1.getHLId().equals(r2.getHLId())) {
                for (Event w1 : wEventsP1) {
                    for (Event w2 : wEventsP2) {
                        if (r1.getLoc() != w1.getLoc()) {
                            continue;
                        }
                        if (r2.getLoc() != w2.getLoc()) {
                            continue;
                        }
                        if (w1.getHLId().equals(w2.getHLId())) {
                            enc = ctx.mkAnd(enc, ctx.mkEq(Utils.edge("rf", w1, r1, ctx), Utils.edge("rf", w2, r2, ctx)));
                        }
                    }
                }
            }
        }
    }
    for (Event w1P1 : wEventsP1) {
        for (Event w1P2 : wEventsP2) {
            if (w1P1.getHLId().equals(w1P2.getHLId())) {
                for (Event w2P1 : wEventsP1) {
                    for (Event w2P2 : wEventsP2) {
                        if (w1P1.getLoc() != w2P1.getLoc()) {
                            continue;
                        }
                        if (w1P1.getLoc() != w2P2.getLoc()) {
                            continue;
                        }
                        if (w1P1 == w2P1 | w1P2 == w2P2) {
                            continue;
                        }
                        if (w2P1.getHLId().equals(w2P2.getHLId())) {
                            enc = ctx.mkAnd(enc, ctx.mkEq(Utils.edge("co", w1P1, w2P1, ctx), Utils.edge("co", w1P2, w2P2, ctx)));
                        }
                    }
                }
            }
        }
    }
    return enc;
}
Also used : IntStream(java.util.stream.IntStream) com.microsoft.z3(com.microsoft.z3) Event(dartagnan.program.Event) Set(java.util.Set) Assert(dartagnan.expression.Assert) Utils(dartagnan.utils.Utils) Collectors(java.util.stream.Collectors) Init(dartagnan.program.Init) HashSet(java.util.HashSet) Register(dartagnan.program.Register) Local(dartagnan.program.Local) Load(dartagnan.program.Load) MemEvent(dartagnan.program.MemEvent) Program(dartagnan.program.Program) Collections(java.util.Collections) Store(dartagnan.program.Store) Location(dartagnan.program.Location) Load(dartagnan.program.Load) Init(dartagnan.program.Init) MemEvent(dartagnan.program.MemEvent) Event(dartagnan.program.Event) MemEvent(dartagnan.program.MemEvent) Local(dartagnan.program.Local) Store(dartagnan.program.Store)

Example 4 with Load

use of dartagnan.program.Load in project Dat3M by hernanponcedeleon.

the class Utils method drawGraph.

public static void drawGraph(Program p, Context ctx, Model model, String filename, String[] relations) throws IOException {
    File newTextFile = new File(filename);
    FileWriter fw = new FileWriter(newTextFile);
    GraphViz gv = new GraphViz();
    gv.addln(gv.start_graph());
    gv.addln("  subgraph cluster_Source { rank=sink; fontsize=20; label = \"Program Compiled to Source Architecture\"; color=red; shape=box;");
    int tid = 0;
    for (dartagnan.program.Thread t : p.getThreads()) {
        tid++;
        if (!(t instanceof Init)) {
            gv.addln("    subgraph cluster_Thread_Source" + t.getTId() + " { rank=sink; fontsize=15; label = \"Thread " + tid + "\"; color=magenta; shape=box;");
        }
        for (Event e : p.getEvents()) {
            String label = "";
            if (!(e instanceof MemEvent)) {
                continue;
            }
            if ((e instanceof Store || e instanceof Init) && model.getConstInterp(e.executes(ctx)).isTrue()) {
                label = "W_" + e.getLoc() + "_" + model.getConstInterp(((MemEvent) e).ssaLoc).toString() + "\\n";
            }
            if (e instanceof Load && model.getConstInterp(e.executes(ctx)).isTrue()) {
                label = "R_" + e.getLoc() + "_" + model.getConstInterp(((MemEvent) e).ssaLoc).toString() + "\\n";
            }
            for (Event eHL : p.getEvents().stream().filter(x -> x instanceof MemEvent).collect(Collectors.toSet())) {
                if (!(e instanceof Init) && e.getHLId() != null && e.getHLId() == eHL.hashCode()) {
                    label = label + eHL.toString().replaceAll("\\s", "");
                }
            }
            if ((e instanceof Store || e instanceof Load) && e.getMainThread() == t.getTId() && model.getConstInterp(e.executes(ctx)).isTrue()) {
                gv.addln("      " + e.repr() + " [label=\"" + label + "\", shape=\"box\", color=\"blue\", group=s" + e.getMainThread() + "];");
            }
            if (e instanceof Init && e.getMainThread() == t.getTId() && model.getConstInterp(e.executes(ctx)).isTrue()) {
                gv.addln("      " + e.repr() + " [label=\"" + label + "\", shape=\"box\", color=\"blue\", root=true];");
            }
        }
        if (!(t instanceof Init)) {
            gv.addln("    }");
        }
    }
    for (Event e1 : p.getEvents()) {
        for (Event e2 : p.getEvents()) {
            if (!(e1 instanceof MemEvent && e2 instanceof MemEvent)) {
                continue;
            }
            if (!(model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue())) {
                continue;
            }
            if (model.getConstInterp(edge("rf", e1, e2, ctx)).isTrue() && model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue()) {
                gv.addln("      " + e1.repr() + " -> " + e2.repr() + " [label=\"rf\", color=\"red\", fontcolor=\"red\", weight=1];");
            }
            if (model.getConstInterp(edge("fr", e1, e2, ctx)).isTrue() && model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue()) {
                gv.addln("      " + e1.repr() + " -> " + e2.repr() + " [label=\"fr\", color=\"#ffa040\", fontcolor=\"#ffa040\", weight=1];");
            }
            if (e1.getLoc() == e2.getLoc() && (e1 instanceof Store || e1 instanceof Init) && (e2 instanceof Store || e2 instanceof Init) && Integer.parseInt(model.getConstInterp(intVar("co", e1, ctx)).toString()) == Integer.parseInt(model.getConstInterp(intVar("co", e2, ctx)).toString()) - 1 && model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue()) {
                gv.addln("      " + e1.repr() + " -> " + e2.repr() + " [label=\"co\", color=\"brown\", fontcolor=\"brown\", weight=1];");
            }
            if (model.getConstInterp(edge("sync", e1, e2, ctx)).isTrue() && model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue()) {
                gv.addln("      " + e1.repr() + " -> " + e2.repr() + " [label=\"sync\", color=\"black\", fontcolor=\"black\", weight=1];");
            }
            if (model.getConstInterp(edge("lwsync", e1, e2, ctx)).isTrue() && model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue()) {
                gv.addln("      " + e1.repr() + " -> " + e2.repr() + " [label=\"lwsync\", color=\"black\", fontcolor=\"black\", weight=1];");
            }
            if (model.getConstInterp(edge("mfence", e1, e2, ctx)).isTrue() && model.getConstInterp(e1.executes(ctx)).isTrue() && model.getConstInterp(e2.executes(ctx)).isTrue()) {
                gv.addln("      " + e1.repr() + " -> " + e2.repr() + " [label=\"mfence\", color=\"black\", fontcolor=\"black\", weight=1];");
            }
        }
    }
    gv.addln("  }");
    gv.addln(gv.end_graph());
    fw.write(gv.getDotSource());
    fw.close();
    return;
}
Also used : Arrays(java.util.Arrays) com.microsoft.z3(com.microsoft.z3) Event(dartagnan.program.Event) FileWriter(java.io.FileWriter) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) File(java.io.File) Init(dartagnan.program.Init) Register(dartagnan.program.Register) Load(dartagnan.program.Load) MemEvent(dartagnan.program.MemEvent) Program(dartagnan.program.Program) Store(dartagnan.program.Store) Location(dartagnan.program.Location) Load(dartagnan.program.Load) FileWriter(java.io.FileWriter) Store(dartagnan.program.Store) Init(dartagnan.program.Init) MemEvent(dartagnan.program.MemEvent) Event(dartagnan.program.Event) MemEvent(dartagnan.program.MemEvent) File(java.io.File)

Example 5 with Load

use of dartagnan.program.Load in project Dat3M by hernanponcedeleon.

the class Encodings method AssertFromModel.

public static Assert AssertFromModel(Program p, Model model, Context ctx) {
    Assert ass = new Assert();
    Set<Location> locs = p.getEvents().stream().filter(e -> e instanceof MemEvent).map(e -> e.getLoc()).collect(Collectors.toSet());
    for (Location loc : locs) {
        ass.addPair(loc, Integer.valueOf(model.getConstInterp(ctx.mkIntConst(loc.getName() + "_final")).toString()));
    }
    Set<Event> executedEvents = p.getEvents().stream().filter(e -> model.getConstInterp(e.executes(ctx)).isTrue()).collect(Collectors.toSet());
    Set<Register> regs = executedEvents.stream().filter(e -> e instanceof Local | e instanceof Load).map(e -> e.getReg()).collect(Collectors.toSet());
    for (Register reg : regs) {
        Set<Integer> ssaRegIndexes = new HashSet<Integer>();
        for (Event e : executedEvents) {
            if (!(e instanceof Load | e instanceof Local)) {
                continue;
            }
            if (e.getReg() != reg) {
                continue;
            }
            ssaRegIndexes.add(e.getSsaRegIndex());
        }
        Integer lastRegIndex = Collections.max(ssaRegIndexes);
        String regVarName = String.format("T%s_%s_%s", reg.getMainThread(), reg.getName(), lastRegIndex);
        ass.addPair(reg, Integer.valueOf(model.getConstInterp(ctx.mkIntConst(regVarName)).toString()));
    }
    return ass;
}
Also used : IntStream(java.util.stream.IntStream) com.microsoft.z3(com.microsoft.z3) Event(dartagnan.program.Event) Set(java.util.Set) Assert(dartagnan.expression.Assert) Utils(dartagnan.utils.Utils) Collectors(java.util.stream.Collectors) Init(dartagnan.program.Init) HashSet(java.util.HashSet) Register(dartagnan.program.Register) Local(dartagnan.program.Local) Load(dartagnan.program.Load) MemEvent(dartagnan.program.MemEvent) Program(dartagnan.program.Program) Collections(java.util.Collections) Store(dartagnan.program.Store) Location(dartagnan.program.Location) Load(dartagnan.program.Load) Local(dartagnan.program.Local) Assert(dartagnan.expression.Assert) Register(dartagnan.program.Register) MemEvent(dartagnan.program.MemEvent) Event(dartagnan.program.Event) MemEvent(dartagnan.program.MemEvent) Location(dartagnan.program.Location) HashSet(java.util.HashSet)

Aggregations

Event (dartagnan.program.Event)8 Load (dartagnan.program.Load)8 Location (dartagnan.program.Location)8 MemEvent (dartagnan.program.MemEvent)8 Register (dartagnan.program.Register)8 com.microsoft.z3 (com.microsoft.z3)7 Init (dartagnan.program.Init)7 Local (dartagnan.program.Local)7 Program (dartagnan.program.Program)7 Store (dartagnan.program.Store)7 Collectors (java.util.stream.Collectors)7 Set (java.util.Set)6 HashSet (java.util.HashSet)4 Assert (dartagnan.expression.Assert)3 HighLocation (dartagnan.program.HighLocation)3 Utils (dartagnan.utils.Utils)3 Utils.edge (dartagnan.utils.Utils.edge)3 Utils.lastValueLoc (dartagnan.utils.Utils.lastValueLoc)3 Utils.lastValueReg (dartagnan.utils.Utils.lastValueReg)3 Utils.ssaReg (dartagnan.utils.Utils.ssaReg)3