Search in sources :

Example 26 with Label

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

the class AtomicAsLock method run.

private void run(MemoryObject address, Thread thread) {
    Label end;
    if (thread.getExit() instanceof Label) {
        end = (Label) thread.getExit();
    } else {
        end = newLabel("__VERIFIER_atomic_thread_end");
        thread.getExit().setSuccessor(end);
        thread.updateExit(end);
    }
    Register register = thread.newRegister(ARCH_PRECISION);
    for (Event predecessor = thread.getEntry(); predecessor != null; ) {
        Event event = predecessor.getSuccessor();
        boolean begin = event instanceof BeginAtomic;
        if (begin || event instanceof EndAtomic) {
            Event load = EventFactory.newLoad(register, address, null);
            Event check = EventFactory.newJump(new Atom(register, NEQ, begin ? IValue.ZERO : IValue.ONE), end);
            Event store = EventFactory.newStore(address, begin ? IValue.ONE : IValue.ZERO, null);
            load.setOId(event.getOId());
            check.setOId(event.getOId());
            store.setOId(event.getOId());
            load.addFilters(Tag.C11.LOCK, Tag.RMW);
            check.addFilters(Tag.C11.LOCK, Tag.RMW);
            store.addFilters(Tag.C11.LOCK, Tag.RMW);
            predecessor.setSuccessor(load);
            load.setSuccessor(check);
            check.setSuccessor(store);
            store.setSuccessor(event.getSuccessor());
            predecessor = store;
        } else {
            predecessor = event;
        }
    }
}
Also used : EndAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic) Register(com.dat3m.dartagnan.program.Register) BeginAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic) Label(com.dat3m.dartagnan.program.event.core.Label) EventFactory.newLabel(com.dat3m.dartagnan.program.event.EventFactory.newLabel) Event(com.dat3m.dartagnan.program.event.core.Event) Atom(com.dat3m.dartagnan.expression.Atom)

Example 27 with Label

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

the class FindSpinLoops method detectAndMarkSpinLoops.

private void detectAndMarkSpinLoops(Thread t) {
    Event curr = t.getEntry();
    while (curr != null) {
        // Find start of spinloop that is not already marked.
        if (curr instanceof Label && !curr.is(Tag.SPINLOOP)) {
            Label label = (Label) curr;
            // Importantly, this looks for the LAST backjump to the label
            List<CondJump> backjumps = label.getJumpSet().stream().filter(x -> x.getOId() > label.getOId()).sorted().collect(Collectors.toList());
            if (!backjumps.isEmpty()) {
                Label loopStart = label;
                CondJump loopEnd = backjumps.get(backjumps.size() - 1);
                if (isSideEffectFree(loopStart, loopEnd)) {
                    loopStart.addFilters(Tag.SPINLOOP, Tag.NOOPT);
                    backjumps.forEach(x -> x.addFilters(Tag.SPINLOOP, Tag.NOOPT));
                    spinloops++;
                }
            }
        }
        curr = curr.getSuccessor();
    }
    t.clearCache();
}
Also used : Label(com.dat3m.dartagnan.program.event.core.Label) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) CondJump(com.dat3m.dartagnan.program.event.core.CondJump)

Example 28 with Label

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

the class LoopUnrolling method unrollLoop.

private void unrollLoop(CondJump loopBackJump, int bound) {
    Label loopBegin = loopBackJump.getLabel();
    Preconditions.checkArgument(bound >= 1, "Positive unrolling bound expected.");
    Preconditions.checkArgument(loopBegin.getOId() < loopBackJump.getOId(), "The jump does not belong to a loop.");
    Preconditions.checkArgument(loopBackJump.getUId() < 0, "The loop has already been unrolled");
    // (1) Collect continue points of the loop
    List<CondJump> continues = new ArrayList<>();
    for (Event e = loopBegin; e != null && e != loopBackJump; e = e.getSuccessor()) {
        if (e instanceof CondJump && ((CondJump) e).getLabel() == loopBegin) {
            continues.add((CondJump) e);
        }
    }
    continues.add(loopBackJump);
    // (2) Collect forward jumps from the outside into the loop
    List<CondJump> enterJumps = new ArrayList<>();
    for (Event e = loopBegin; e != null && e != loopBackJump; e = e.getSuccessor()) {
        if (e instanceof Label) {
            Label label = (Label) e;
            label.getJumpSet().stream().filter(j -> j.getOId() < loopBegin.getOId()).forEach(enterJumps::add);
        }
    }
    int iterCounter = 0;
    while (--bound >= 0) {
        iterCounter++;
        if (bound == 0) {
            Label exit = (Label) loopBackJump.getThread().getExit();
            loopBegin.setName(loopBegin.getName() + "_" + iterCounter);
            for (CondJump cont : continues) {
                if (!cont.isGoto()) {
                    logger.warn("Conditional jump {} was replaced by unconditional bound event", cont);
                }
                CondJump boundEvent = EventFactory.newGoto(exit);
                // Keep tags of original jump.
                boundEvent.addFilters(cont.getFilters());
                boundEvent.addFilters(Tag.BOUND, Tag.NOOPT);
                cont.getPredecessor().setSuccessor(boundEvent);
                boundEvent.setSuccessor(cont.getSuccessor());
                cont.delete();
            }
        } else {
            Map<Event, Event> copyCtx = new HashMap<>();
            List<Event> copies = copyPath(loopBegin, loopBackJump, copyCtx);
            ((Label) copyCtx.get(loopBegin)).setName(loopBegin.getName() + "_" + iterCounter);
            // Insert copies at right place
            loopBegin.getPredecessor().setSuccessor(copies.get(0));
            copies.get(copies.size() - 1).setSuccessor(loopBegin);
            // Update entering jumps to go to the copies.
            for (CondJump enterJump : enterJumps) {
                enterJump.updateReferences(copyCtx);
            }
            enterJumps.clear();
            // All "continues" that were copied need to get updated to jump forward to the next iteration.
            for (CondJump cont : continues) {
                if (cont == loopBackJump) {
                    continue;
                }
                CondJump copy = (CondJump) copyCtx.get(cont);
                copy.updateReferences(Map.of(copy.getLabel(), loopBegin));
                enterJumps.add(cont);
            }
        }
    }
}
Also used : Printer(com.dat3m.dartagnan.utils.printer.Printer) PRINT_PROGRAM_AFTER_UNROLLING(com.dat3m.dartagnan.configuration.OptionNames.PRINT_PROGRAM_AFTER_UNROLLING) HashMap(java.util.HashMap) Thread(com.dat3m.dartagnan.program.Thread) Label(com.dat3m.dartagnan.program.event.core.Label) org.sosy_lab.common.configuration(org.sosy_lab.common.configuration) ArrayList(java.util.ArrayList) Tag(com.dat3m.dartagnan.program.event.Tag) EventFactory(com.dat3m.dartagnan.program.event.EventFactory) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Map(java.util.Map) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) Preconditions(com.google.common.base.Preconditions) BOUND(com.dat3m.dartagnan.configuration.OptionNames.BOUND) CondJump(com.dat3m.dartagnan.program.event.core.CondJump) LogManager(org.apache.logging.log4j.LogManager) HashMap(java.util.HashMap) Label(com.dat3m.dartagnan.program.event.core.Label) ArrayList(java.util.ArrayList) Event(com.dat3m.dartagnan.program.event.core.Event) CondJump(com.dat3m.dartagnan.program.event.core.CondJump)

Example 29 with Label

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

the class RemoveDeadCondJumps method eliminateDeadCondJumps.

private void eliminateDeadCondJumps(Thread thread) {
    Map<Event, List<Event>> immediateLabelPredecessors = new HashMap<>();
    List<Event> removed = new ArrayList<>();
    Event pred = thread.getEntry();
    Event current = pred.getSuccessor();
    // We fill the map of predecessors
    while (current != null) {
        if (current instanceof CondJump) {
            CondJump jump = (CondJump) current;
            // After constant propagation some jumps have False as condition and are dead
            if (jump.isDead()) {
                removed.add(jump);
            } else {
                immediateLabelPredecessors.computeIfAbsent(jump.getLabel(), key -> new ArrayList<>()).add(jump);
            }
        } else if (current instanceof Label && !(pred instanceof CondJump && ((CondJump) pred).isGoto())) {
            immediateLabelPredecessors.computeIfAbsent(current, key -> new ArrayList<>()).add(pred);
        }
        pred = current;
        current = current.getSuccessor();
    }
    // We check which ifs can be removed
    for (Event label : immediateLabelPredecessors.keySet()) {
        Event next = label.getSuccessor();
        List<Event> preds = immediateLabelPredecessors.get(label);
        // BOUND events
        if (next instanceof CondJump && preds.stream().allMatch(e -> mutuallyExclusiveIfs((CondJump) next, e))) {
            removed.add(next);
        }
        // SPINLOOP events
        if (next != null && preds.size() == 1 && preds.get(0).getSuccessor().equals(label)) {
            removed.add(label);
        }
    }
    // Here is the actual removal
    pred = null;
    Event cur = thread.getEntry();
    boolean dead = false;
    while (cur != null) {
        if (dead && cur instanceof Label && !immediateLabelPredecessors.getOrDefault(cur, List.of()).isEmpty()) {
            dead = false;
        }
        if (dead && cur instanceof CondJump && immediateLabelPredecessors.containsKey(((CondJump) cur).getLabel())) {
            immediateLabelPredecessors.get(((CondJump) cur).getLabel()).remove(cur);
        }
        if (dead && immediateLabelPredecessors.containsKey(cur.getSuccessor())) {
            immediateLabelPredecessors.get(cur.getSuccessor()).remove(cur);
        }
        if ((dead || removed.contains(cur)) && !cur.is(Tag.NOOPT)) {
            cur.delete();
            cur = pred;
        }
        if (cur instanceof CondJump && ((CondJump) cur).isGoto()) {
            dead = true;
        }
        pred = cur;
        cur = cur.getSuccessor();
    }
}
Also used : Atom(com.dat3m.dartagnan.expression.Atom) Configuration(org.sosy_lab.common.configuration.Configuration) HashMap(java.util.HashMap) Thread(com.dat3m.dartagnan.program.Thread) Label(com.dat3m.dartagnan.program.event.core.Label) ArrayList(java.util.ArrayList) Tag(com.dat3m.dartagnan.program.event.Tag) List(java.util.List) Logger(org.apache.logging.log4j.Logger) BExprUn(com.dat3m.dartagnan.expression.BExprUn) Map(java.util.Map) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) Preconditions(com.google.common.base.Preconditions) CondJump(com.dat3m.dartagnan.program.event.core.CondJump) LogManager(org.apache.logging.log4j.LogManager) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Label(com.dat3m.dartagnan.program.event.core.Label) Event(com.dat3m.dartagnan.program.event.core.Event) ArrayList(java.util.ArrayList) List(java.util.List) CondJump(com.dat3m.dartagnan.program.event.core.CondJump)

Example 30 with Label

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

the class Simplifier method simplifyJump.

private boolean simplifyJump(CondJump jump) {
    Label label = jump.getLabel();
    Event successor = jump.getSuccessor();
    BExpr expr = jump.getGuard();
    if (label.equals(successor) && expr instanceof BConst) {
        jump.delete();
        return true;
    }
    return false;
}
Also used : BExpr(com.dat3m.dartagnan.expression.BExpr) BConst(com.dat3m.dartagnan.expression.BConst) Label(com.dat3m.dartagnan.program.event.core.Label) Event(com.dat3m.dartagnan.program.event.core.Event)

Aggregations

Label (com.dat3m.dartagnan.program.event.core.Label)33 Event (com.dat3m.dartagnan.program.event.core.Event)15 Register (com.dat3m.dartagnan.program.Register)11 CondJump (com.dat3m.dartagnan.program.event.core.CondJump)9 Atom (com.dat3m.dartagnan.expression.Atom)7 MemoryObject (com.dat3m.dartagnan.program.memory.MemoryObject)7 ProgramBuilder (com.dat3m.dartagnan.parsers.program.utils.ProgramBuilder)6 Test (org.junit.Test)6 LoopUnrolling (com.dat3m.dartagnan.program.processing.LoopUnrolling)5 ParsingException (com.dat3m.dartagnan.exception.ParsingException)4 Program (com.dat3m.dartagnan.program.Program)4 Thread (com.dat3m.dartagnan.program.Thread)4 Preconditions (com.google.common.base.Preconditions)4 HashMap (java.util.HashMap)4 LogManager (org.apache.logging.log4j.LogManager)4 Logger (org.apache.logging.log4j.Logger)4 Tag (com.dat3m.dartagnan.program.event.Tag)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Map (java.util.Map)3