Skip to content

Commit 5f09ecb

Browse files
committed
add padding Index to ArrayType
1 parent ed948ed commit 5f09ecb

File tree

6 files changed

+60
-36
lines changed

6 files changed

+60
-36
lines changed

dartagnan/src/main/java/com/dat3m/dartagnan/expression/type/ArrayType.java

+10
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@ public class ArrayType implements Type {
66

77
private final Type elementType;
88
private final int numElements;
9+
private final int paddingStart;
910

1011
ArrayType(Type elementType, int numElements) {
12+
this(elementType, numElements, numElements + 1);
13+
}
14+
15+
ArrayType(Type elementType, int numElements, int paddingStart) {
1116
this.elementType = elementType;
1217
this.numElements = numElements;
18+
this.paddingStart = paddingStart;
19+
}
20+
21+
public int getPaddingStart() {
22+
return paddingStart;
1323
}
1424

1525
// NOTE: We use empty arrays to represent unknown size.

dartagnan/src/main/java/com/dat3m/dartagnan/expression/type/TypeFactory.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ public ArrayType getArrayType(Type element, int size) {
123123
return typeNormalizer.normalize(new ArrayType(element, size));
124124
}
125125

126+
public ArrayType getArrayType(Type element, int size, int paddingStart) {
127+
checkArgument(0 <= size, "Negative element count in array.");
128+
checkArgument(0 <= paddingStart, "Negative padding start index in array.");
129+
checkArgument(paddingStart <= size, "Padding start index %s is greater than array size %s", paddingStart, size);
130+
return typeNormalizer.normalize(new ArrayType(element, size, paddingStart));
131+
}
132+
126133
public IntegerType getArchType() {
127134
return pointerDifferenceType;
128135
}
@@ -268,7 +275,7 @@ public static boolean isStaticTypeOf(Type staticType, Type runtimeType) {
268275
}
269276
if (staticType instanceof ArrayType aStaticType && runtimeType instanceof ArrayType aRuntimeType) {
270277
int countStatic = aStaticType.getNumElements();
271-
int countRuntime = aRuntimeType.getNumElements();
278+
int countRuntime = Math.min(aRuntimeType.getPaddingStart(), aRuntimeType.getNumElements());
272279
if (countStatic != countRuntime && (countRuntime != -1 || countStatic <= 0)) {
273280
return false;
274281
}

dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/spirv/VisitorOpsMemory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ private Expression getOpVariableInitialValue(SpirvParser.OpVariableContext ctx,
169169
}
170170
Expression initExpr = builder.getExpression(ctx.initializer().getText());
171171
if (alignment.getValue(id) != null) {
172-
initExpr = HelperTypes.getAlignedValue(id, initExpr, type);
172+
initExpr = builder.getAlignedValue(id, initExpr, type);
173173
}
174174
return initExpr;
175175
}

dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/spirv/builders/ProgramBuilder.java

+32-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
import com.dat3m.dartagnan.expression.Expression;
66
import com.dat3m.dartagnan.expression.ExpressionFactory;
77
import com.dat3m.dartagnan.expression.Type;
8-
import com.dat3m.dartagnan.expression.type.FunctionType;
9-
import com.dat3m.dartagnan.expression.type.ScopedPointerType;
10-
import com.dat3m.dartagnan.expression.type.TypeFactory;
8+
import com.dat3m.dartagnan.expression.aggregates.ConstructExpr;
9+
import com.dat3m.dartagnan.expression.type.*;
1110
import com.dat3m.dartagnan.parsers.program.visitors.spirv.decorations.BuiltIn;
1211
import com.dat3m.dartagnan.program.Function;
1312
import com.dat3m.dartagnan.program.Program;
@@ -23,9 +22,11 @@
2322
import com.dat3m.dartagnan.program.processing.transformers.MemoryTransformer;
2423

2524
import java.util.HashMap;
25+
import java.util.List;
2626
import java.util.Map;
2727
import java.util.Set;
2828
import java.util.stream.Collectors;
29+
import java.util.stream.IntStream;
2930

3031
import static com.dat3m.dartagnan.parsers.program.visitors.spirv.decorations.DecorationType.BUILT_IN;
3132

@@ -51,6 +52,34 @@ public ProgramBuilder(ThreadGrid grid) {
5152
this.decorationsBuilder = new DecorationsBuilder(grid);
5253
}
5354

55+
public Expression getAlignedValue(String id, Expression base, Type type) {
56+
if (type instanceof AggregateType aggregateType && base instanceof ConstructExpr constructExpr) {
57+
List<Expression> elements = aggregateType.getFields().stream()
58+
.map(field -> {
59+
int index = aggregateType.getFields().indexOf(field);
60+
return getAlignedValue(id, constructExpr.getOperands().get(index), field.type());
61+
})
62+
.collect(Collectors.toList());
63+
return ExpressionFactory.getInstance().makeConstruct(type, elements);
64+
}
65+
if (type instanceof ArrayType arrayType && base instanceof ConstructExpr constructExpr) {
66+
int numOperands = constructExpr.getOperands().size();
67+
if (arrayType.getNumElements() < numOperands) {
68+
throw new ParsingException("Array initializer has too many elements for variable '%s'", id);
69+
}
70+
List<Expression> elements = IntStream.range(0, arrayType.getNumElements())
71+
.mapToObj(i -> i < numOperands
72+
? getAlignedValue(id, constructExpr.getOperands().get(i), arrayType.getElementType())
73+
: makeUndefinedValue(arrayType.getElementType()))
74+
.collect(Collectors.toList());
75+
return ExpressionFactory.getInstance().makeArray(arrayType.getElementType(), elements, true);
76+
}
77+
if (base.getType().equals(type)) {
78+
return base;
79+
}
80+
throw new ParsingException("Cannot align initializer for variable '" + id + "' of type " + type);
81+
}
82+
5483
public Program build() {
5584
validateBeforeBuild();
5685
controlFlowBuilder.build();

dartagnan/src/main/java/com/dat3m/dartagnan/parsers/program/visitors/spirv/helpers/HelperTypes.java

+6-30
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
import com.dat3m.dartagnan.expression.type.*;
1111

1212
import java.util.ArrayList;
13-
import java.util.Collections;
1413
import java.util.List;
15-
import java.util.stream.Collectors;
1614
import java.util.stream.IntStream;
1715

1816
import static com.dat3m.dartagnan.expression.integers.IntBinaryOp.ADD;
@@ -69,23 +67,6 @@ public static Expression getMemberAddress(String id, Expression base, Type type,
6967
return base;
7068
}
7169

72-
public static Expression getAlignedValue(String id, Expression base, Type type) {
73-
if (type instanceof AggregateType aggregateType && base instanceof ConstructExpr constructExpr) {
74-
List<Expression> elements = IntStream.range(0, aggregateType.getFields().size())
75-
.mapToObj(i -> {
76-
Type elType = aggregateType.getFields().get(i).type();
77-
Expression elBase = constructExpr.getOperands().get(i);
78-
return getAlignedValue(id, elBase, elType);
79-
})
80-
.collect(Collectors.toList());
81-
return expressions.makeConstruct(type, elements);
82-
}
83-
if (base.getType().equals(type)) {
84-
return base;
85-
}
86-
throw new ParsingException("Cannot align initializer for variable '" + id + "' of type " + type);
87-
}
88-
8970
public static Expression createResultExpression(String id, Type type, Expression op1, Expression op2, IntBinaryOp op) {
9071
if (type instanceof BooleanType || type instanceof IntegerType || type instanceof FloatType) {
9172
return expressions.makeBinary(op1, op, op2);
@@ -211,18 +192,13 @@ public static Type getAlignedType(Type type, int alignmentNum) {
211192
}
212193
if (type instanceof ArrayType arrayType) {
213194
Type elementType = arrayType.getElementType();
214-
int elementAlignmentNum;
215-
if (types.getMemorySizeInBytes(elementType) > alignmentNum) {
216-
elementType = getAlignedType(elementType, alignmentNum);
217-
elementAlignmentNum = types.getMemorySizeInBytes(elementType);
218-
} else {
219-
elementAlignmentNum = alignmentNum;
195+
int arraySizeInBytes = types.getMemorySizeInBytes(arrayType);
196+
if (arraySizeInBytes > alignmentNum) {
197+
return types.getArrayType(getAlignedType(elementType, alignmentNum), arrayType.getNumElements());
220198
}
221-
List<Type> elementTypes = Collections.nCopies(arrayType.getNumElements(), elementType);
222-
List<Integer> alignmentList = IntStream.range(0, arrayType.getNumElements())
223-
.mapToObj(i -> i * elementAlignmentNum)
224-
.collect(Collectors.toList());
225-
return types.getAggregateType(elementTypes, alignmentList);
199+
int paddedSize = alignmentNum / types.getMemorySizeInBytes(elementType);
200+
int paddingStart = arrayType.getNumElements();
201+
return types.getArrayType(elementType, paddedSize, paddingStart);
226202
}
227203
throw new ParsingException("Invalid type '%s' for alignment '%d'", type, alignmentNum);
228204
}

dartagnan/src/test/java/com/dat3m/dartagnan/parsers/program/visitors/spirv/VisitorOpsMemoryTest.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ public void testAlignedVariable() {
247247
assertEquals(256, ((IntegerType) v1.getInnerType()).getBitWidth());
248248
ScopedPointerVariable v2 = (ScopedPointerVariable) builder.getExpression("%v2");
249249
assertNotNull(v2);
250-
assertEquals(64, ((AggregateType) v2.getInnerType()).getFields().get(1).offset());
250+
assertEquals(64, TypeFactory.getInstance().getMemorySizeInBytes(v2.getInnerType()));
251+
assertEquals(4, ((ArrayType) v2.getInnerType()).getNumElements());
252+
assertEquals(3, ((ArrayType) v2.getInnerType()).getPaddingStart());
251253
}
252254

253255
@Test

0 commit comments

Comments
 (0)