Search in sources :

Example 11 with CondJump

use of com.dat3m.dartagnan.program.event.core.CondJump 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 12 with CondJump

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

the class LoopUnrolling method unrollThread.

private void unrollThread(Thread thread, int defaultBound) {
    Event cur = thread.getEntry();
    while (cur != null) {
        Event next = cur.getSuccessor();
        if (cur instanceof CondJump && ((CondJump) cur).getLabel().getOId() < cur.getOId()) {
            CondJump jump = (CondJump) cur;
            if (jump.getLabel().getJumpSet().stream().allMatch(x -> x.getOId() <= jump.getOId())) {
                // TODO: Get different bounds for different loops (e.g. via annotations)
                int bound = jump.is(Tag.SPINLOOP) ? 1 : defaultBound;
                unrollLoop((CondJump) cur, bound);
            }
        }
        cur = next;
    }
}
Also used : Event(com.dat3m.dartagnan.program.event.core.Event) CondJump(com.dat3m.dartagnan.program.event.core.CondJump)

Example 13 with CondJump

use of com.dat3m.dartagnan.program.event.core.CondJump 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 14 with CondJump

use of com.dat3m.dartagnan.program.event.core.CondJump 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)

Aggregations

CondJump (com.dat3m.dartagnan.program.event.core.CondJump)14 Event (com.dat3m.dartagnan.program.event.core.Event)10 Label (com.dat3m.dartagnan.program.event.core.Label)9 Program (com.dat3m.dartagnan.program.Program)4 Thread (com.dat3m.dartagnan.program.Thread)4 LogManager (org.apache.logging.log4j.LogManager)4 Logger (org.apache.logging.log4j.Logger)4 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)3 Preconditions (com.google.common.base.Preconditions)3 HashMap (java.util.HashMap)3 Configuration (org.sosy_lab.common.configuration.Configuration)3 InvalidConfigurationException (org.sosy_lab.common.configuration.InvalidConfigurationException)3 Atom (com.dat3m.dartagnan.expression.Atom)2 BExprUn (com.dat3m.dartagnan.expression.BExprUn)2 ProgramBuilder (com.dat3m.dartagnan.parsers.program.utils.ProgramBuilder)2 Register (com.dat3m.dartagnan.program.Register)2 Tag (com.dat3m.dartagnan.program.event.Tag)2 RegWriter (com.dat3m.dartagnan.program.event.core.utils.RegWriter)2 Context (com.dat3m.dartagnan.verification.Context)2 java.util (java.util)2