Search in sources :

Example 11 with RegWriter

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

the class AndersenAliasAnalysis method processLocs.

private void processLocs(Program program) {
    for (Event ev : program.getCache().getEvents(FilterBasic.get(Tag.MEMORY))) {
        MemEvent e = (MemEvent) ev;
        IExpr address = e.getAddress();
        // Collect for each v events of form: p = *v, *v = q
        if (address instanceof Register) {
            graph.addEvent((Register) address, e);
            continue;
        }
        Constant addressConstant = new Constant(address);
        if (addressConstant.failed) {
            // r = *(CompExpr) -> loc(r) = max
            if (e instanceof RegWriter) {
                Register register = ((RegWriter) e).getResultRegister();
                graph.addAllAddresses(register, maxAddressSet);
                variables.add(register);
            }
            // FIXME if e is a store event, then all locations should include its values
            eventAddressSpaceMap.put(e, maxAddressSet);
            continue;
        }
        // address is a constant
        Location location = addressConstant.location;
        if (location == null) {
            throw new RuntimeException("memory event accessing a pure constant address");
        }
        eventAddressSpaceMap.put(e, ImmutableSet.of(location));
        if (e instanceof RegWriter) {
            graph.addEdge(location, ((RegWriter) e).getResultRegister());
            continue;
        }
        // event is a store operation
        Verify.verify(e.is(Tag.WRITE), "memory event that is neither tagged \"W\" nor a register writer");
        ExprInterface value = e.getMemValue();
        if (value instanceof Register) {
            graph.addEdge(value, location);
            continue;
        }
        Constant v = new Constant(value);
        if (v.failed) {
            graph.addAllAddresses(location, maxAddressSet);
        } else if (v.location != null) {
            graph.addAddress(location, v.location);
        }
        variables.add(location);
    }
}
Also used : ExprInterface(com.dat3m.dartagnan.expression.ExprInterface) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) IExpr(com.dat3m.dartagnan.expression.IExpr)

Example 12 with RegWriter

use of com.dat3m.dartagnan.program.event.core.utils.RegWriter 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 13 with RegWriter

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

the class ConstantPropagation method run.

private void run(Thread thread) {
    Map<Register, ExprInterface> propagationMap = new HashMap<>();
    Map<Label, Map<Register, ExprInterface>> label2PropagationMap = new HashMap<>();
    Event pred = thread.getEntry();
    Event current = pred.getSuccessor();
    while (current != null) {
        boolean resetPropMap = false;
        // but like this the solver keeps relations between variables)
        if (current instanceof RegWriter) {
            RegWriter rw = (RegWriter) current;
            propagationMap.put(rw.getResultRegister(), rw.getResultRegister());
        }
        // For Locals, we update
        if (current instanceof Local) {
            Local l = (Local) current;
            // We cannot update the map with the evaluation if the resultRegister is also in the RHS
            if (!l.getExpr().getRegs().contains(l.getResultRegister())) {
                ExprInterface value = evaluate(l.getExpr(), propagationMap);
                if (value == TOP && l.getExpr() instanceof Register) {
                    // Even if we do not know the concrete value, Registers have a constant value
                    // thus we add them to the map to achieve more propagations
                    propagationMap.put(l.getResultRegister(), l.getExpr());
                } else {
                    propagationMap.put(l.getResultRegister(), value);
                }
            }
        }
        if (current instanceof CondJump) {
            CondJump jump = (CondJump) current;
            label2PropagationMap.put(jump.getLabel(), merge(propagationMap, label2PropagationMap.getOrDefault(jump.getLabel(), Collections.emptyMap())));
            // A goto will cause the current map to not propagate to the successor
            resetPropMap = jump.isGoto();
        } else if (current instanceof Label) {
            // Merge current map with all possible jumps that target this label
            propagationMap = merge(propagationMap, label2PropagationMap.getOrDefault(current, Collections.emptyMap()));
        }
        if (!current.is(Tag.NOOPT)) {
            current.accept(new ConstantPropagationVisitor(propagationMap));
        }
        current = current.getSuccessor();
        if (resetPropMap) {
            propagationMap.clear();
        }
    }
    thread.updateExit(thread.getEntry());
    thread.clearCache();
}
Also used : HashMap(java.util.HashMap) Register(com.dat3m.dartagnan.program.Register) RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) HashMap(java.util.HashMap) Map(java.util.Map)

Example 14 with RegWriter

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

Example 15 with RegWriter

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

the class ExecutionModel method addEvent.

private void addEvent(Event e, int globalId, int localId) {
    EventData data = eventMap.getOrCreate(e);
    data.setId(globalId);
    data.setLocalId(localId);
    eventList.add(data);
    data.setWasExecuted(true);
    if (data.isMemoryEvent()) {
        // ===== Memory Events =====
        BigInteger address = ((MemEvent) e).getAddress().getIntValue(e, model, context);
        data.setAccessedAddress(address);
        if (!addressReadsMap.containsKey(address)) {
            addressReadsMap.put(address, new HashSet<>());
            addressWritesMap.put(address, new HashSet<>());
        }
        if (data.isRead()) {
            data.setValue(new BigInteger(model.evaluate(((RegWriter) e).getResultRegisterExpr()).toString()));
            addressReadsMap.get(address).add(data);
        } else if (data.isWrite()) {
            data.setValue(((MemEvent) e).getMemValue().getIntValue(e, model, context));
            addressWritesMap.get(address).add(data);
            writeReadsMap.put(data, new HashSet<>());
            if (data.isInit()) {
                addressInitMap.put(address, data);
            }
        } else {
            throw new UnsupportedOperationException("Unexpected memory event " + data.getEvent());
        }
    } else if (data.isFence()) {
        // ===== Fences =====
        String name = ((Fence) data.getEvent()).getName();
        fenceMap.computeIfAbsent(name, key -> new HashSet<>()).add(data);
    } else if (data.isJump()) {
        // ===== Jumps =====
        // We override the meaning of execution here. A jump is executed IFF its condition was true.
        data.setWasExecuted(((CondJump) e).didJump(model, context));
    } else {
    // TODO: Maybe add some other events (e.g. assertions)
    // But for now all non-visible events are simply registered without
    // having any data extracted
    }
}
Also used : RegWriter(com.dat3m.dartagnan.program.event.core.utils.RegWriter) BigInteger(java.math.BigInteger)

Aggregations

RegWriter (com.dat3m.dartagnan.program.event.core.utils.RegWriter)15 Register (com.dat3m.dartagnan.program.Register)13 Event (com.dat3m.dartagnan.program.event.core.Event)9 Thread (com.dat3m.dartagnan.program.Thread)4 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)4 RegReaderData (com.dat3m.dartagnan.program.event.core.utils.RegReaderData)4 ImmutableList (com.google.common.collect.ImmutableList)4 BigInteger (java.math.BigInteger)4 Collectors (java.util.stream.Collectors)4 Program (com.dat3m.dartagnan.program.Program)3 Dependency (com.dat3m.dartagnan.program.analysis.Dependency)3 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 java.util (java.util)3 Set (java.util.Set)3 BooleanFormula (org.sosy_lab.java_smt.api.BooleanFormula)3 SolverContext (org.sosy_lab.java_smt.api.SolverContext)3 IValue (com.dat3m.dartagnan.expression.IValue)2 Utils.generalEqual (com.dat3m.dartagnan.expression.utils.Utils.generalEqual)2 ExecutionAnalysis (com.dat3m.dartagnan.program.analysis.ExecutionAnalysis)2