Skip to content

Commit 018d7d8

Browse files
authored
[IR] LLVM cmpxchg Rework (hernanponcedeleon#976)
1 parent 3d84f6b commit 018d7d8

14 files changed

Lines changed: 162 additions & 200 deletions

File tree

dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/VisitorLlvm.java

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838

3939
import static com.dat3m.dartagnan.expression.utils.ExpressionHelper.isAggregateLike;
4040
import static com.dat3m.dartagnan.program.event.EventFactory.*;
41-
import static com.dat3m.dartagnan.program.event.EventFactory.Llvm.newCompareExchange;
4241
import static com.google.common.base.Preconditions.checkState;
4342
import static com.google.common.base.Verify.verify;
4443

@@ -810,19 +809,11 @@ public Expression visitCmpXchgInst(CmpXchgInstContext ctx) {
810809
final Expression comparator = visitTypeValue(ctx.typeValue(1));
811810
final Expression substitute = visitTypeValue(ctx.typeValue(2));
812811
check(comparator.getType().equals(substitute.getType()), "Type mismatch for comparator and new in %s.", ctx);
813-
final Register value = function.newRegister(comparator.getType());
814-
final Register asExpected = function.newRegister(types.getBooleanType());
815-
final boolean weak = ctx.weak != null;
812+
final boolean strong = ctx.weak == null;
816813
final String mo = parseMemoryOrder(ctx.atomicOrdering(0));
817-
block.events.add(newCompareExchange(value, asExpected, address, comparator, substitute, mo, weak));
818814
final Register register = currentRegisterName == null ? null :
819815
getOrNewCurrentRegister(types.getAggregateType(List.of(comparator.getType(), getIntegerType(1))));
820-
if (register != null) {
821-
final Expression cast = expressions.makeIntegerCast(asExpected, getIntegerType(1), false);
822-
final Type type = types.getAggregateType(List.of(value.getType(), cast.getType()));
823-
final Expression result = expressions.makeConstruct(type, List.of(value, cast));
824-
block.events.add(newLocal(register, result));
825-
}
816+
block.events.add(Llvm.newCompareExchange(register, address, comparator, substitute, mo, strong));
826817
return register;
827818
}
828819

dartagnan/src/main/java/com/dat3m/dartagnan/program/Function.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.dat3m.dartagnan.program.event.RegWriter;
1111
import com.dat3m.dartagnan.program.event.core.CondJump;
1212
import com.dat3m.dartagnan.program.event.core.Label;
13-
import com.dat3m.dartagnan.program.event.lang.llvm.LlvmCmpXchg;
1413
import com.dat3m.dartagnan.program.processing.Intrinsics;
1514
import com.dat3m.dartagnan.utils.UniqueIdGenerator;
1615
import com.google.common.base.Preconditions;
@@ -222,7 +221,7 @@ public void validate() {
222221
});
223222
}
224223

225-
if (ev instanceof RegWriter writer && !(writer instanceof LlvmCmpXchg) && !registers.contains(writer.getResultRegister())) {
224+
if (ev instanceof RegWriter writer && !registers.contains(writer.getResultRegister())) {
226225
final String error = String.format("Event %s of function %s writes to external register %s of function %s",
227226
writer, this, writer.getResultRegister(), writer.getResultRegister().getFunction()
228227
);

dartagnan/src/main/java/com/dat3m/dartagnan/program/IRHelper.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.dat3m.dartagnan.program.event.core.Init;
1212
import com.dat3m.dartagnan.program.event.functions.AbortIf;
1313
import com.dat3m.dartagnan.program.event.functions.Return;
14-
import com.dat3m.dartagnan.program.event.lang.llvm.LlvmCmpXchg;
1514
import com.google.common.base.Preconditions;
1615
import com.google.common.base.Verify;
1716

@@ -126,10 +125,7 @@ public Expression visitRegister(Register reg) {
126125
if (event instanceof RegReader reader) {
127126
reader.transformExpressions(regSubstitutor);
128127
}
129-
if (event instanceof LlvmCmpXchg xchg) {
130-
xchg.setStructRegister(0, (Register)xchg.getStructRegister(0).accept(regSubstitutor));
131-
xchg.setStructRegister(1, (Register)xchg.getStructRegister(1).accept(regSubstitutor));
132-
} else if (event instanceof RegWriter regWriter) {
128+
if (event instanceof RegWriter regWriter) {
133129
regWriter.setResultRegister((Register) regWriter.getResultRegister().accept(regSubstitutor));
134130
}
135131
};

dartagnan/src/main/java/com/dat3m/dartagnan/program/event/EventFactory.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -485,12 +485,9 @@ public static LlvmXchg newExchange(Register register, Expression address, Expres
485485
return new LlvmXchg(register, address, value, mo);
486486
}
487487

488-
public static LlvmCmpXchg newCompareExchange(Register oldValueRegister, Register cmpRegister, Expression address, Expression expectedAddr, Expression desiredValue, String mo, boolean isStrong) {
489-
return new LlvmCmpXchg(oldValueRegister, cmpRegister, address, expectedAddr, desiredValue, mo, isStrong);
490-
}
491-
492-
public static LlvmCmpXchg newCompareExchange(Register oldValueRegister, Register cmpRegister, Expression address, Expression expectedAddr, Expression desiredValue, String mo) {
493-
return newCompareExchange(oldValueRegister, cmpRegister, address, expectedAddr, desiredValue, mo, false);
488+
public static LlvmCmpXchg newCompareExchange(Register oldValueAndSuccess, Expression address,
489+
Expression expected, Expression newValue, String mo, boolean strong) {
490+
return new LlvmCmpXchg(oldValueAndSuccess, address, expected, newValue, mo, strong);
494491
}
495492

496493
public static LlvmRMW newRMW(Register register, Expression address, Expression value, IntBinaryOp op, String mo) {

dartagnan/src/main/java/com/dat3m/dartagnan/program/event/lang/llvm/LlvmCmpXchg.java

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,32 @@
11
package com.dat3m.dartagnan.program.event.lang.llvm;
22

33
import com.dat3m.dartagnan.expression.Expression;
4-
import com.dat3m.dartagnan.expression.type.BooleanType;
4+
import com.dat3m.dartagnan.expression.type.AggregateType;
55
import com.dat3m.dartagnan.program.Register;
66
import com.dat3m.dartagnan.program.event.EventVisitor;
77
import com.dat3m.dartagnan.program.event.common.RMWCmpXchgBase;
88
import com.google.common.base.Preconditions;
99

10-
// FIXME: This instruction writes to two registers, which we cannot express right now.
1110
public class LlvmCmpXchg extends RMWCmpXchgBase {
1211

13-
private Register cmpRegister;
14-
15-
public LlvmCmpXchg(Register oldValueRegister, Register cmpRegister, Expression address,
16-
Expression expectedValue, Expression value, String mo, boolean isStrong) {
17-
super(oldValueRegister, address, expectedValue, value, isStrong, mo);
12+
public LlvmCmpXchg(Register oldValueAndSuccessRegister, Expression address, Expression expectedValue,
13+
Expression value, String mo, boolean isStrong) {
14+
super(oldValueAndSuccessRegister, address, expectedValue, value, isStrong, mo);
1815
Preconditions.checkArgument(!mo.isEmpty(), "LLVM events cannot have empty memory order");
19-
Preconditions.checkArgument(cmpRegister.getType() instanceof BooleanType,
20-
"Non-boolean result register of LlvmCmpXchg.");
21-
this.cmpRegister = cmpRegister;
16+
Preconditions.checkArgument(oldValueAndSuccessRegister.getType() instanceof AggregateType t
17+
&& t.getFields().size() == 2,
18+
"Non-aggregate result register of LlvmCmpXchg.");
2219
}
2320

2421
private LlvmCmpXchg(LlvmCmpXchg other) {
2522
super(other);
26-
this.cmpRegister = other.cmpRegister;
27-
}
28-
29-
// The llvm instructions actually returns a structure.
30-
// In most cases the structure is not used as a whole,
31-
// but rather by accessing its members. Thus, there is
32-
// no need to support this method.
33-
// NOTE: we use the inherited "resultRegister" to store the old value
34-
@Override
35-
public Register getResultRegister() {
36-
throw new UnsupportedOperationException("getResultRegister() not supported for " + this);
37-
}
38-
39-
public Register getStructRegister(int idx) {
40-
return switch (idx) {
41-
case 0 -> resultRegister;
42-
case 1 -> cmpRegister;
43-
default ->
44-
throw new UnsupportedOperationException("Cannot access structure with id " + idx + " in " + getClass().getName());
45-
};
46-
}
47-
48-
public void setStructRegister(int idx, Register newRegister) {
49-
switch (idx) {
50-
case 0 -> resultRegister = newRegister;
51-
case 1 -> cmpRegister = newRegister;
52-
default ->
53-
throw new UnsupportedOperationException("Cannot access structure with id " + idx + " in " + getClass().getName());
54-
}
5523
}
5624

5725
@Override
5826
public String defaultString() {
5927
final String strongSuffix = isStrong ? "strong" : "weak";
60-
return String.format("(%s, %s) = llvm_cmpxchg_%s(%s, %s, %s, %s)",
61-
resultRegister, cmpRegister, strongSuffix, address, expectedValue, storeValue, mo);
28+
return String.format("%s = llvm_cmpxchg_%s(%s, %s, %s, %s)",
29+
resultRegister, strongSuffix, address, expectedValue, storeValue, mo);
6230
}
6331

6432
@Override

0 commit comments

Comments
 (0)