Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 111 additions & 96 deletions dartagnan/src/main/java/com/dat3m/dartagnan/encoding/ProgramEncoder.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,7 @@ private void computeBranchImplications(BranchDecomposition decomposition) {
final Branch creatorBranch = decomposition.event2BranchMap.get(start.getCreator());
threadInitialBranch.mustPred.add(creatorBranch);
threadInitialBranch.exclusiveBranches.addAll(creatorBranch.exclusiveBranches);
if (!start.mayFailSpuriously()) {
creatorBranch.mustSucc.add(threadInitialBranch);
}
creatorBranch.mustSucc.add(threadInitialBranch);
} else {
unconditionalThreadInitialBranches.add(threadInitialBranch);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.dat3m.dartagnan.program.event;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.program.Function;
import com.dat3m.dartagnan.program.Program;
import com.dat3m.dartagnan.program.Thread;
Expand All @@ -9,7 +8,6 @@
import com.dat3m.dartagnan.program.event.metadata.MetadataMap;
import com.dat3m.dartagnan.verification.Context;
import com.google.common.base.Preconditions;
import org.sosy_lab.java_smt.api.BooleanFormula;

import java.util.*;

Expand Down Expand Up @@ -316,8 +314,4 @@ public boolean cfImpliesExec() {
return !(this instanceof BlockingEvent);
}

@Override
public BooleanFormula encodeExec(EncodingContext ctx) {
return ctx.getBooleanFormulaManager().makeTrue();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.dat3m.dartagnan.program.event;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.program.Function;
import com.dat3m.dartagnan.program.Program;
import com.dat3m.dartagnan.program.Thread;
import com.dat3m.dartagnan.program.event.metadata.Metadata;
import com.dat3m.dartagnan.verification.Context;
import org.sosy_lab.java_smt.api.BooleanFormula;

import java.util.Collection;
import java.util.List;
Expand Down Expand Up @@ -96,6 +94,4 @@ public interface Event extends Comparable<Event> {

// This method needs to get overwritten for conditional events.
boolean cfImpliesExec();

BooleanFormula encodeExec(EncodingContext ctx);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import com.dat3m.dartagnan.program.event.arch.vulkan.*;
import com.dat3m.dartagnan.program.event.core.*;
import com.dat3m.dartagnan.program.event.core.annotations.CodeAnnotation;
import com.dat3m.dartagnan.program.event.core.threading.ThreadArgument;
import com.dat3m.dartagnan.program.event.lang.catomic.*;
import com.dat3m.dartagnan.program.event.lang.dat3m.NonDetChoice;
import com.dat3m.dartagnan.program.event.lang.linux.*;
import com.dat3m.dartagnan.program.event.lang.llvm.*;
import com.dat3m.dartagnan.program.event.lang.spirv.*;
import com.dat3m.dartagnan.program.event.lang.svcomp.*;
import com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic;
import com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic;

public interface EventVisitor<T> {

Expand Down Expand Up @@ -40,6 +42,8 @@ public interface EventVisitor<T> {
// RMW core events
default T visitRMWStore(RMWStore e) { return visitStore(e); }
default T visitRMWStoreExclusive(RMWStoreExclusive e) { return visitStore(e); }
// Threading
default T visitThreadArgument(ThreadArgument e) { return visitEvent(e); }
// Annotations
default T visitCodeAnnotation(CodeAnnotation e) { return visitEvent(e); }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.dat3m.dartagnan.program.event.core;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.expression.Expression;
import com.dat3m.dartagnan.expression.ExpressionFactory;
import com.dat3m.dartagnan.expression.ExpressionVisitor;
Expand All @@ -15,7 +14,6 @@
import com.dat3m.dartagnan.program.event.RegWriter;
import com.dat3m.dartagnan.program.memory.MemoryObject;
import com.google.common.base.Preconditions;
import org.sosy_lab.java_smt.api.BooleanFormula;

import java.math.BigInteger;
import java.util.HashSet;
Expand Down Expand Up @@ -129,11 +127,4 @@ public <T> T accept(EventVisitor<T> visitor) {
return visitor.visitAlloc(this);
}

@Override
public BooleanFormula encodeExec(EncodingContext ctx) {
return ctx.getBooleanFormulaManager().and(
super.encodeExec(ctx),
ctx.getExpressionEncoder().assignEqualAt(ctx.result(this), this, getAllocatedObject(), this)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.dat3m.dartagnan.program.event.core;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.expression.Expression;
import com.dat3m.dartagnan.expression.ExpressionVisitor;
import com.dat3m.dartagnan.expression.type.BooleanType;
Expand All @@ -9,8 +8,6 @@
import com.dat3m.dartagnan.program.event.EventVisitor;
import com.dat3m.dartagnan.program.event.RegReader;
import com.google.common.base.Preconditions;
import org.sosy_lab.java_smt.api.BooleanFormula;
import org.sosy_lab.java_smt.api.BooleanFormulaManager;

import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -45,14 +42,6 @@ public String defaultString() {
return "assume(" + expr + ")";
}

@Override
public BooleanFormula encodeExec(EncodingContext ctx) {
BooleanFormulaManager bmgr = ctx.getBooleanFormulaManager();
return bmgr.and(
super.encodeExec(ctx),
bmgr.implication(ctx.execution(this), ctx.getExpressionEncoder().encodeBooleanAt(expr, this).formula()));
}

@Override
public void transformExpressions(ExpressionVisitor<? extends Expression> exprTransformer) {
this.expr = expr.accept(exprTransformer);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.dat3m.dartagnan.program.event.core;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.program.event.BlockingEvent;
import com.dat3m.dartagnan.program.event.EventVisitor;
import com.dat3m.dartagnan.program.event.Tag;
import org.sosy_lab.java_smt.api.BooleanFormula;

public class ControlBarrier extends GenericVisibleEvent implements BlockingEvent {

Expand Down Expand Up @@ -56,8 +54,4 @@ public <T> T accept(EventVisitor<T> visitor) {
return visitor.visitControlBarrier(this);
}

@Override
public BooleanFormula encodeExec(EncodingContext ctx) {
return ctx.getBooleanFormulaManager().implication(ctx.execution(this), ctx.controlFlow(this));
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
package com.dat3m.dartagnan.program.event.core;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.encoding.ExpressionEncoder;
import com.dat3m.dartagnan.expression.Expression;
import com.dat3m.dartagnan.program.Register;
import com.dat3m.dartagnan.program.event.*;
import org.sosy_lab.java_smt.api.BooleanFormula;
import org.sosy_lab.java_smt.api.BooleanFormulaManager;

import java.util.Map;
import java.util.Set;

import static com.dat3m.dartagnan.encoding.ExpressionEncoder.ConversionMode.CAST;

public class ExecutionStatus extends AbstractEvent implements RegWriter, EventUser {

private Register register;
Expand Down Expand Up @@ -59,22 +52,6 @@ public String defaultString() {
return register + " = not_exec(" + event + ")";
}

@Override
public BooleanFormula encodeExec(EncodingContext context) {
final BooleanFormulaManager bmgr = context.getBooleanFormulaManager();
final ExpressionEncoder exprEncoder = context.getExpressionEncoder();

//TODO: We have "result == not exec(event)", because we use 0/false for executed events.
// The reason is that ExecutionStatus follows the behavior of Store-Conditionals on hardware.
// However, this is very counterintuitive and I think we should return 1/true on success and instead
// change the compilation of Store-Conditional to invert the value.
final Expression notExec = exprEncoder.wrap(bmgr.not(context.execution(event)));
return bmgr.and(
super.encodeExec(context),
context.getExpressionEncoder().assignEqual(context.result(this), notExec, CAST)
);
}

@Override
public Event getCopy() {
return new ExecutionStatus(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.dat3m.dartagnan.program.event.core;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.expression.Expression;
import com.dat3m.dartagnan.expression.ExpressionVisitor;
import com.dat3m.dartagnan.program.Register;
Expand All @@ -9,7 +8,6 @@
import com.dat3m.dartagnan.program.event.RegReader;
import com.dat3m.dartagnan.program.event.RegWriter;
import com.google.common.base.Preconditions;
import org.sosy_lab.java_smt.api.BooleanFormula;

import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -59,14 +57,6 @@ public String defaultString() {
return String.format("%s = %s", register, expr);
}

@Override
public BooleanFormula encodeExec(EncodingContext ctx) {
return ctx.getBooleanFormulaManager().and(
super.encodeExec(ctx),
ctx.getExpressionEncoder().assignEqualAt(ctx.result(this), this, expr, this)
);
}

@Override
public void transformExpressions(ExpressionVisitor<? extends Expression> exprTransformer) {
this.expr = expr.accept(exprTransformer);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.dat3m.dartagnan.program.event.core;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.expression.Expression;
import com.dat3m.dartagnan.program.event.Event;
import com.dat3m.dartagnan.program.event.EventVisitor;
import com.dat3m.dartagnan.program.event.Tag;
import org.sosy_lab.java_smt.api.BooleanFormula;

public class RMWStoreExclusive extends Store {

Expand Down Expand Up @@ -44,11 +42,6 @@ public String defaultString() {
return String.format("%1$-" + Event.PRINT_PAD_EXTRA + "s", "excl " + super.defaultString()) + "# opt" + tag;
}

@Override
public BooleanFormula encodeExec(EncodingContext ctx) {
return ctx.getBooleanFormulaManager().implication(ctx.execution(this), ctx.controlFlow(this));
}

@Override
public RMWStoreExclusive getCopy(){
return new RMWStoreExclusive(this);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package com.dat3m.dartagnan.program.event.core.threading;

import com.dat3m.dartagnan.encoding.EncodingContext;
import com.dat3m.dartagnan.expression.Expression;
import com.dat3m.dartagnan.program.Register;
import com.dat3m.dartagnan.program.event.AbstractEvent;
import com.dat3m.dartagnan.program.event.Event;
import com.dat3m.dartagnan.program.event.EventUser;
import com.dat3m.dartagnan.program.event.RegWriter;
import com.dat3m.dartagnan.program.event.*;
import com.google.common.base.Preconditions;
import org.sosy_lab.java_smt.api.BooleanFormula;

import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -55,17 +49,6 @@ public String defaultString() {
return String.format("%s = Argument(%s) from %s", register, argIndex, creator);
}

@Override
public BooleanFormula encodeExec(EncodingContext context) {
final Expression equalValue = context.getExpressionFactory()
.makeEQ(context.result(this), creator.getArguments().get(argIndex));
return context.getBooleanFormulaManager().and(
super.encodeExec(context),
context.getExpressionEncoder().encodeBooleanAt(equalValue, creator).formula()
);
}


@Override
public ThreadArgument getCopy() {
return new ThreadArgument(this);
Expand All @@ -80,4 +63,9 @@ public Set<Event> getReferencedEvents() {
public void updateReferences(Map<Event, Event> updateMapping) {
creator = (ThreadCreate) EventUser.moveUserReference(this, creator, updateMapping);
}

@Override
public <T> T accept(EventVisitor<T> visitor) {
return visitor.visitThreadArgument(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@

public class ThreadStart extends AbstractEvent implements EventUser {

// May be NULL, if this thread is not spawned.
// May be NULL if this thread is not spawned.
private ThreadCreate creator;
//TODO: It is probably better to make the ThreadCreate conditional rather than
// allow ThreadStart to fail spuriously.
private boolean mayFailSpuriously;

public ThreadStart(ThreadCreate creator) {
this.creator = creator;

mayFailSpuriously = (creator != null);
if (creator != null) {
creator.registerUser(this);
}
Expand All @@ -27,20 +23,18 @@ public ThreadStart(ThreadCreate creator) {
protected ThreadStart(ThreadStart other) {
super(other);
this.creator = other.creator;
this.mayFailSpuriously = other.mayFailSpuriously;

creator.registerUser(this);
if (creator != null) {
creator.registerUser(this);
}
}

public boolean mayFailSpuriously() { return mayFailSpuriously; }
public void setMayFailSpuriously(boolean value) { this.mayFailSpuriously = value;}

public boolean isSpawned() { return creator != null; }
public ThreadCreate getCreator() { return creator; }

@Override
public String defaultString() {
if ( isSpawned()) {
if (isSpawned()) {
return String.format("ThreadStart by %s::%s", creator.getThread(), creator);
} else {
return "ThreadStart";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.dat3m.dartagnan.exception.MalformedProgramException;
import com.dat3m.dartagnan.program.Function;
import com.dat3m.dartagnan.program.ScopeHierarchy;
import com.dat3m.dartagnan.program.event.Event;
import com.dat3m.dartagnan.program.event.core.*;
import com.dat3m.dartagnan.program.event.core.annotations.CodeAnnotation;
Expand Down Expand Up @@ -54,5 +55,28 @@ public void run(Function function) {
}
throw new MalformedProgramException("Found non-core events.\n" + msg);
}

validateCoreEvents(function);
}

private void validateCoreEvents(Function function) {
StringBuilder msg = new StringBuilder();

for (ControlBarrier cb : function.getEvents(ControlBarrier.class)) {
// Check: Control barriers execution scopes match thread hierarchy
ScopeHierarchy hierarchy = cb.getThread().getScopeHierarchy();
if (hierarchy == null) {
msg.append(String.format("\t%2s: %-30s is not inside hierarchical thread %n", cb.getGlobalId(), cb));
} else {
final int id = hierarchy.getScopeId(cb.getExecScope());
if (id < 0) {
msg.append(String.format("\t%2s: %-30s execution scope does not match thread hierarchy %n", cb.getGlobalId(), cb));
}
}
}

if (!msg.isEmpty()) {
throw new MalformedProgramException("Found errors in program.\n" + msg);
}
}
}
Loading
Loading