Search in sources :

Example 1 with RegReaderData

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

the class ExecutionModel method trackDependencies.

private void trackDependencies(Event e) {
    while (!endIfs.isEmpty() && e.getCId() >= endIfs.peek().getCId()) {
        // We exited an If and remove the dependencies associated with it
        // We do this inside a loop just in case multiple Ifs are left simultaneously
        endIfs.pop();
        curCtrlDeps.removeAll(ifCtrlDeps.pop());
    }
    if (e instanceof MemEvent) {
        // ---- Track address dependency ----
        MemEvent memEvent = (MemEvent) e;
        HashSet<EventData> deps = new HashSet<>();
        for (Register reg : memEvent.getAddress().getRegs()) {
            deps.addAll(lastRegWrites.get(reg));
        }
        addrDepMap.put(eventMap.get(e), deps);
    }
    if (e.is(Tag.VISIBLE)) {
        // ---- Track ctrl dependency ----
        // TODO: This may be done more efficiently, as many events share the same set of ctrldeps.
        ctrlDepMap.put(eventMap.get(e), new HashSet<>(curCtrlDeps));
    }
    if (e instanceof RegReaderData) {
        // ---- Track data dependency ----
        RegReaderData reader = (RegReaderData) e;
        HashSet<EventData> deps = new HashSet<>();
        for (Register r : reader.getDataRegs()) {
            deps.addAll(lastRegWrites.getOrDefault(r, Collections.emptySet()));
        }
        if (e instanceof Store) {
            // ---- visible data dependency ----
            dataDepMap.put(eventMap.get(e), deps);
        }
        if (e instanceof RegWriter) {
            // ---- internal data dependency ----
            RegWriter writer = (RegWriter) e;
            lastRegWrites.put(writer.getResultRegister(), deps);
        }
        if (e instanceof CondJump) {
            if (e instanceof IfAsJump) {
                // Remember what dependencies were added when entering the If so we can remove them when exiting
                HashSet<EventData> addedDeps = new HashSet<>(Sets.difference(deps, curCtrlDeps));
                ifCtrlDeps.push(addedDeps);
                endIfs.push(((IfAsJump) e).getEndIf());
            }
            // Jumps add all dependencies
            curCtrlDeps.addAll(deps);
        }
    }
    if (e instanceof Load) {
        // ---- Update lastRegWrites ----
        Load load = (Load) e;
        lastRegWrites.compute(load.getResultRegister(), (k, v) -> new HashSet<>()).add(eventMap.get(e));
    }
}
Also used : java.util(java.util) CO(com.dat3m.dartagnan.wmm.relation.RelationNameRepository.CO) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) com.dat3m.dartagnan.program.event.core(com.dat3m.dartagnan.program.event.core) RF(com.dat3m.dartagnan.wmm.relation.RelationNameRepository.RF) Thread(com.dat3m.dartagnan.program.Thread) FilterAbstract(com.dat3m.dartagnan.program.filter.FilterAbstract) EndAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic) Model(org.sosy_lab.java_smt.api.Model) Wmm(com.dat3m.dartagnan.wmm.Wmm) ImmutableList(com.google.common.collect.ImmutableList) SolverContext(org.sosy_lab.java_smt.api.SolverContext) Program(com.dat3m.dartagnan.program.Program) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) BigInteger(java.math.BigInteger) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) VerificationTask(com.dat3m.dartagnan.verification.VerificationTask) RelCo(com.dat3m.dartagnan.wmm.relation.base.memory.RelCo) BeginAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic) Relation(com.dat3m.dartagnan.wmm.relation.Relation) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Tag(com.dat3m.dartagnan.program.event.Tag) Preconditions(com.google.common.base.Preconditions) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData)

Example 2 with RegReaderData

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

the class FindSpinLoops method isSideEffectFree.

private boolean isSideEffectFree(Label loopBegin, CondJump loopEnd) {
    Event cur = loopBegin.getSuccessor();
    // Unsafe means the loop read from the registers before writing to them.
    Set<Register> unsafeRegisters = new HashSet<>();
    // Safe means the loop wrote to these register before using them
    Set<Register> safeRegisters = new HashSet<>();
    while (cur != loopEnd) {
        if (cur instanceof MemEvent) {
            if (cur.is(Tag.WRITE)) {
                // Writes always cause side effects
                return false;
            }
            MemEvent memEvent = (MemEvent) cur;
            Set<Register> addrRegs = memEvent.getAddress().getRegs();
            unsafeRegisters.addAll(Sets.difference(addrRegs, safeRegisters));
        }
        if (cur instanceof RegReaderData) {
            RegReaderData reader = (RegReaderData) cur;
            Set<Register> dataRegs = reader.getDataRegs();
            unsafeRegisters.addAll(Sets.difference(dataRegs, safeRegisters));
        }
        if (cur instanceof RegWriter) {
            RegWriter writer = (RegWriter) cur;
            if (unsafeRegisters.contains(writer.getResultRegister())) {
                return false;
            } else {
                safeRegisters.add(writer.getResultRegister());
            }
        }
        cur = cur.getSuccessor();
    }
    return true;
}
Also used : Register(com.dat3m.dartagnan.program.Register) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) HashSet(java.util.HashSet)

Example 3 with RegReaderData

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

the class Dependency method process.

private void process(Thread thread, ExecutionAnalysis exec) {
    Map<Event, Set<Writer>> jumps = new HashMap<>();
    Set<Writer> state = new HashSet<>();
    for (Register register : thread.getRegisters()) {
        state.add(new Writer(register, null));
    }
    for (Event event : thread.getEvents()) {
        // merge with incoming jumps
        Set<Writer> j = jumps.remove(event);
        if (j != null) {
            state.addAll(j);
        }
        // collecting dependencies, mixing 'data' and 'addr'
        Set<Register> registers = new HashSet<>();
        if (event instanceof RegReaderData) {
            registers.addAll(((RegReaderData) event).getDataRegs());
        }
        if (event instanceof MemEvent) {
            registers.addAll(((MemEvent) event).getAddress().getRegs());
        }
        if (!registers.isEmpty()) {
            Map<Register, State> result = new HashMap<>();
            for (Register register : registers) {
                if (register.getThreadId() == Register.NO_THREAD) {
                    continue;
                }
                State writers;
                if (register.getThreadId() != event.getThread().getId()) {
                    writers = finalWriters.get(register);
                    checkArgument(writers != null, "Helper thread %s should be listed after their creator thread %s.", thread.getId(), register.getThreadId());
                    if (writers.may.size() != 1) {
                        logger.warn("Writers {} for inter-thread register {} read by event {} of thread {}", writers.may, register, event, thread.getId());
                    }
                } else {
                    writers = process(state, register, exec);
                    if (!writers.initialized) {
                        logger.warn("Uninitialized register {} read by event {} of thread {}", register, event, thread.getId());
                    }
                }
                result.put(register, writers);
            }
            map.put(event, result);
        }
        // update state, if changed by event
        if (event instanceof RegWriter) {
            Register register = ((RegWriter) event).getResultRegister();
            if (event.cfImpliesExec()) {
                state.removeIf(e -> e.register.equals(register));
            }
            state.add(new Writer(register, event));
        }
        // copy state, if branching
        if (event instanceof CondJump) {
            jumps.computeIfAbsent(((CondJump) event).getLabel(), k -> new HashSet<>()).addAll(state);
            if (((CondJump) event).isGoto()) {
                state.clear();
            }
        }
    }
    if (!jumps.isEmpty()) {
        logger.warn("Thread {} contains jumps to removed labels {}", thread.getId(), jumps.keySet());
        for (Set<Writer> j : jumps.values()) {
            state.addAll(j);
        }
    }
    for (Register register : thread.getRegisters()) {
        finalWriters.put(register, process(state, register, exec));
    }
}
Also used : Options(org.sosy_lab.common.configuration.Options) java.util(java.util) Configuration(org.sosy_lab.common.configuration.Configuration) IntStream.range(java.util.stream.IntStream.range) Thread(com.dat3m.dartagnan.program.Thread) Collectors(java.util.stream.Collectors) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Context(com.dat3m.dartagnan.verification.Context) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Collectors.toList(java.util.stream.Collectors.toList) Logger(org.apache.logging.log4j.Logger) Verify.verify(com.google.common.base.Verify.verify) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) CondJump(com.dat3m.dartagnan.program.event.core.CondJump) LogManager(org.apache.logging.log4j.LogManager) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) CondJump(com.dat3m.dartagnan.program.event.core.CondJump) Register(com.dat3m.dartagnan.program.Register) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter)

Example 4 with RegReaderData

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

the class DeadAssignmentElimination method eliminateDeadStores.

private void eliminateDeadStores(Thread thread) {
    Set<Event> removed = new HashSet<>();
    // Registers that are used by other threads or assertions cannot be removed
    Set<Register> usedRegs = new HashSet<>();
    if (program.getAss() != null) {
        usedRegs.addAll(program.getAss().getRegs());
    }
    program.getCache().getEvents(FilterBasic.get(ASSERTION)).stream().filter(RegWriter.class::isInstance).map(RegWriter.class::cast).map(RegWriter::getResultRegister).forEach(usedRegs::add);
    program.getEvents().stream().filter(o -> !o.getThread().equals(thread)).filter(o -> o instanceof RegReaderData).forEach(o -> usedRegs.addAll(((RegReaderData) o).getDataRegs()));
    for (Event e : Lists.reverse(thread.getEvents())) {
        if (e instanceof RegWriter && !e.is(VISIBLE) && !usedRegs.contains(((RegWriter) e).getResultRegister())) {
            // Invisible RegWriters that write to an unused reg can get removed
            removed.add(e);
        }
        // An event that was not removed adds its dependencies to the used registers
        if (!removed.contains(e)) {
            if (e instanceof RegReaderData) {
                // Data & Ctrl dependencies
                usedRegs.addAll(((RegReaderData) e).getDataRegs());
            }
            if (e instanceof MemEvent) {
                // Address dependencies
                usedRegs.addAll(((MemEvent) e).getAddress().getRegs());
            }
        }
    }
    // Here is the actual removal
    Event pred = null;
    Event cur = thread.getEntry();
    while (cur != null) {
        if (removed.contains(cur) && !cur.is(Tag.NOOPT)) {
            cur.delete();
            cur = pred;
        }
        pred = cur;
        cur = cur.getSuccessor();
    }
}
Also used : Configuration(org.sosy_lab.common.configuration.Configuration) ASSERTION(com.dat3m.dartagnan.program.event.Tag.ASSERTION) Set(java.util.Set) Thread(com.dat3m.dartagnan.program.Thread) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Tag(com.dat3m.dartagnan.program.event.Tag) HashSet(java.util.HashSet) Lists(com.google.common.collect.Lists) Logger(org.apache.logging.log4j.Logger) VISIBLE(com.dat3m.dartagnan.program.event.Tag.VISIBLE) Program(com.dat3m.dartagnan.program.Program) Event(com.dat3m.dartagnan.program.event.core.Event) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) LogManager(org.apache.logging.log4j.LogManager) FilterBasic(com.dat3m.dartagnan.program.filter.FilterBasic) InvalidConfigurationException(org.sosy_lab.common.configuration.InvalidConfigurationException) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) RegReaderData(com.dat3m.dartagnan.program.event.core.utils.RegReaderData) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) HashSet(java.util.HashSet)

Aggregations

Register (com.dat3m.dartagnan.program.Register)4 RegReaderData (com.dat3m.dartagnan.program.event.core.utils.RegReaderData)4 RegWriter (com.dat3m.dartagnan.program.event.core.utils.RegWriter)4 Program (com.dat3m.dartagnan.program.Program)3 Thread (com.dat3m.dartagnan.program.Thread)3 Event (com.dat3m.dartagnan.program.event.core.Event)3 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)3 Tag (com.dat3m.dartagnan.program.event.Tag)2 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)2 java.util (java.util)2 HashSet (java.util.HashSet)2 Collectors (java.util.stream.Collectors)2 LogManager (org.apache.logging.log4j.LogManager)2 Logger (org.apache.logging.log4j.Logger)2 Configuration (org.sosy_lab.common.configuration.Configuration)2 InvalidConfigurationException (org.sosy_lab.common.configuration.InvalidConfigurationException)2 ASSERTION (com.dat3m.dartagnan.program.event.Tag.ASSERTION)1 VISIBLE (com.dat3m.dartagnan.program.event.Tag.VISIBLE)1 com.dat3m.dartagnan.program.event.core (com.dat3m.dartagnan.program.event.core)1 CondJump (com.dat3m.dartagnan.program.event.core.CondJump)1