Skip to content

Commit d259071

Browse files
authored
Merge pull request swiftlang#28114 from ravikandhadai/constexpr-aggregate-types
2 parents 17de190 + 48bc63b commit d259071

File tree

4 files changed

+121
-53
lines changed

4 files changed

+121
-53
lines changed

include/swift/SIL/SILConstants.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class SILValue;
2828
class SILBuilder;
2929
class SerializedSILLoader;
3030

31+
struct AggregateSymbolicValue;
3132
struct SymbolicArrayStorage;
3233
struct DerivedAddressValue;
3334
struct EnumWithPayloadSymbolicValue;
@@ -307,8 +308,8 @@ class SymbolicValue {
307308
const char *string;
308309

309310
/// When this SymbolicValue is of "Aggregate" kind, this pointer stores
310-
/// information about the array elements and count.
311-
const SymbolicValue *aggregate;
311+
/// information about the aggregate elements, its type and count.
312+
const AggregateSymbolicValue *aggregate;
312313

313314
/// When this SymbolicValue is of "Enum" kind, this pointer stores
314315
/// information about the enum case type.
@@ -365,9 +366,6 @@ class SymbolicValue {
365366

366367
/// This is the number of bytes for an RK_String representation.
367368
unsigned stringNumBytes;
368-
369-
/// This is the number of elements for an RK_Aggregate representation.
370-
unsigned aggregateNumElements;
371369
} auxInfo;
372370

373371
public:
@@ -488,11 +486,15 @@ class SymbolicValue {
488486
StringRef getStringValue() const;
489487

490488
/// This returns an aggregate value with the specified elements in it. This
491-
/// copies the elements into the specified Allocator.
492-
static SymbolicValue getAggregate(ArrayRef<SymbolicValue> elements,
489+
/// copies the member values into the specified Allocator.
490+
static SymbolicValue getAggregate(ArrayRef<SymbolicValue> members,
491+
Type aggregateType,
493492
SymbolicValueAllocator &allocator);
494493

495-
ArrayRef<SymbolicValue> getAggregateValue() const;
494+
ArrayRef<SymbolicValue> getAggregateMembers() const;
495+
496+
/// Return the type of this aggregate symbolic value.
497+
Type getAggregateType() const;
496498

497499
/// This returns a constant Symbolic value for the enum case in `decl`, which
498500
/// must not have an associated value.
@@ -617,7 +619,12 @@ struct SymbolicValueMemoryObject {
617619
Type getType() const { return type; }
618620

619621
SymbolicValue getValue() const { return value; }
620-
void setValue(SymbolicValue newValue) { value = newValue; }
622+
void setValue(SymbolicValue newValue) {
623+
assert((newValue.getKind() != SymbolicValue::Aggregate ||
624+
newValue.getAggregateType()->isEqual(type)) &&
625+
"Memory object type does not match the type of the symbolic value");
626+
value = newValue;
627+
}
621628

622629
/// Create a new memory object whose overall type is as specified.
623630
static SymbolicValueMemoryObject *create(Type type, SymbolicValue value,

lib/SIL/SILConstants.cpp

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void SymbolicValue::print(llvm::raw_ostream &os, unsigned indent) const {
6666
os << "string: \"" << getStringValue() << "\"\n";
6767
return;
6868
case RK_Aggregate: {
69-
ArrayRef<SymbolicValue> elements = getAggregateValue();
69+
ArrayRef<SymbolicValue> elements = getAggregateMembers();
7070
switch (elements.size()) {
7171
case 0:
7272
os << "agg: 0 elements []\n";
@@ -211,12 +211,12 @@ SymbolicValue::cloneInto(SymbolicValueAllocator &allocator) const {
211211
case RK_String:
212212
return SymbolicValue::getString(getStringValue(), allocator);
213213
case RK_Aggregate: {
214-
auto elts = getAggregateValue();
214+
auto elts = getAggregateMembers();
215215
SmallVector<SymbolicValue, 4> results;
216216
results.reserve(elts.size());
217217
for (auto elt : elts)
218218
results.push_back(elt.cloneInto(allocator));
219-
return getAggregate(results, allocator);
219+
return getAggregate(results, getAggregateType(), allocator);
220220
}
221221
case RK_EnumWithPayload: {
222222
return getEnumWithPayload(
@@ -350,24 +350,71 @@ StringRef SymbolicValue::getStringValue() const {
350350
// Aggregates
351351
//===----------------------------------------------------------------------===//
352352

353-
/// This returns a constant Symbolic value with the specified elements in it.
354-
/// This assumes that the elements lifetime has been managed for this.
355-
SymbolicValue SymbolicValue::getAggregate(ArrayRef<SymbolicValue> elements,
356-
SymbolicValueAllocator &allocator) {
357-
// Copy the elements into the bump pointer.
358-
auto *resultElts = allocator.allocate<SymbolicValue>(elements.size());
359-
std::uninitialized_copy(elements.begin(), elements.end(), resultElts);
353+
namespace swift {
354+
355+
/// Representation of a constant aggregate namely a struct or a tuple.
356+
struct AggregateSymbolicValue final
357+
: private llvm::TrailingObjects<AggregateSymbolicValue, SymbolicValue> {
358+
friend class llvm::TrailingObjects<AggregateSymbolicValue, SymbolicValue>;
359+
360+
const Type aggregateType;
361+
362+
const unsigned numElements;
363+
364+
static AggregateSymbolicValue *create(ArrayRef<SymbolicValue> members,
365+
Type aggregateType,
366+
SymbolicValueAllocator &allocator) {
367+
auto byteSize =
368+
AggregateSymbolicValue::totalSizeToAlloc<SymbolicValue>(members.size());
369+
auto rawMem = allocator.allocate(byteSize, alignof(AggregateSymbolicValue));
370+
371+
// Placement initialize the object.
372+
auto *aggregate =
373+
::new (rawMem) AggregateSymbolicValue(aggregateType, members.size());
374+
std::uninitialized_copy(members.begin(), members.end(),
375+
aggregate->getTrailingObjects<SymbolicValue>());
376+
return aggregate;
377+
}
378+
379+
/// Return the type of the aggregate.
380+
Type getAggregateType() const { return aggregateType; }
360381

382+
/// Return the symbolic values of members.
383+
ArrayRef<SymbolicValue> getMemberValues() const {
384+
return {getTrailingObjects<SymbolicValue>(), numElements};
385+
}
386+
387+
// This is used by the llvm::TrailingObjects base class.
388+
size_t numTrailingObjects(OverloadToken<SymbolicValue>) const {
389+
return numElements;
390+
}
391+
392+
private:
393+
AggregateSymbolicValue() = delete;
394+
AggregateSymbolicValue(const AggregateSymbolicValue &) = delete;
395+
AggregateSymbolicValue(Type aggregateType, unsigned numElements)
396+
: aggregateType(aggregateType), numElements(numElements) {}
397+
};
398+
} // namespace swift
399+
400+
SymbolicValue SymbolicValue::getAggregate(ArrayRef<SymbolicValue> members,
401+
Type aggregateType,
402+
SymbolicValueAllocator &allocator) {
361403
SymbolicValue result;
362404
result.representationKind = RK_Aggregate;
363-
result.value.aggregate = resultElts;
364-
result.auxInfo.aggregateNumElements = elements.size();
405+
result.value.aggregate =
406+
AggregateSymbolicValue::create(members, aggregateType, allocator);
365407
return result;
366408
}
367409

368-
ArrayRef<SymbolicValue> SymbolicValue::getAggregateValue() const {
410+
ArrayRef<SymbolicValue> SymbolicValue::getAggregateMembers() const {
369411
assert(getKind() == Aggregate);
370-
return ArrayRef<SymbolicValue>(value.aggregate, auxInfo.aggregateNumElements);
412+
return value.aggregate->getMemberValues();
413+
}
414+
415+
Type SymbolicValue::getAggregateType() const {
416+
assert(getKind() == Aggregate);
417+
return value.aggregate->getAggregateType();
371418
}
372419

373420
//===----------------------------------------------------------------------===//
@@ -770,7 +817,7 @@ SymbolicValue SymbolicValue::lookThroughSingleElementAggregates() const {
770817
while (1) {
771818
if (result.getKind() != Aggregate)
772819
return result;
773-
auto elts = result.getAggregateValue();
820+
auto elts = result.getAggregateMembers();
774821
if (elts.size() != 1)
775822
return result;
776823
result = elts[0];
@@ -1009,7 +1056,7 @@ static SymbolicValue getIndexedElement(SymbolicValue aggregate,
10091056
elt = aggregate.getStoredElements(arrayEltTy)[elementNo];
10101057
eltType = arrayEltTy;
10111058
} else {
1012-
elt = aggregate.getAggregateValue()[elementNo];
1059+
elt = aggregate.getAggregateMembers()[elementNo];
10131060
if (auto *decl = type->getStructOrBoundGenericStruct()) {
10141061
eltType = decl->getStoredProperties()[elementNo]->getType();
10151062
} else if (auto tuple = type->getAs<TupleType>()) {
@@ -1063,7 +1110,7 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
10631110

10641111
SmallVector<SymbolicValue, 4> newElts(numMembers,
10651112
SymbolicValue::getUninitMemory());
1066-
aggregate = SymbolicValue::getAggregate(newElts, allocator);
1113+
aggregate = SymbolicValue::getAggregate(newElts, type, allocator);
10671114
}
10681115

10691116
assert((aggregate.getKind() == SymbolicValue::Aggregate ||
@@ -1080,7 +1127,7 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
10801127
oldElts = aggregate.getStoredElements(arrayEltTy);
10811128
eltType = arrayEltTy;
10821129
} else {
1083-
oldElts = aggregate.getAggregateValue();
1130+
oldElts = aggregate.getAggregateMembers();
10841131
if (auto *decl = type->getStructOrBoundGenericStruct()) {
10851132
eltType = decl->getStoredProperties()[elementNo]->getType();
10861133
} else if (auto tuple = type->getAs<TupleType>()) {
@@ -1097,8 +1144,12 @@ static SymbolicValue setIndexedElement(SymbolicValue aggregate,
10971144
setIndexedElement(newElts[elementNo], accessPath.drop_front(), newElement,
10981145
eltType, allocator);
10991146

1100-
if (aggregate.getKind() == SymbolicValue::Aggregate)
1101-
return SymbolicValue::getAggregate(newElts, allocator);
1147+
if (aggregate.getKind() == SymbolicValue::Aggregate) {
1148+
Type aggregateType = aggregate.getAggregateType();
1149+
assert(aggregateType->isEqual(type) &&
1150+
"input type does not match the type of the aggregate");
1151+
return SymbolicValue::getAggregate(newElts, aggregateType, allocator);
1152+
}
11021153

11031154
return aggregate = SymbolicValue::getSymbolicArrayStorage(
11041155
newElts, eltType->getCanonicalType(), allocator);

lib/SILOptimizer/Mandatory/OSLogOptimization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ static bool checkOSLogMessageIsConstant(SingleValueInstruction *osLogMessage,
722722
// The first (and only) property of OSLogMessage is the OSLogInterpolation
723723
// instance.
724724
SymbolicValue osLogInterpolationValue =
725-
osLogMessageValueOpt->getAggregateValue()[0];
725+
osLogMessageValueOpt->getAggregateMembers()[0];
726726
if (!osLogInterpolationValue.isConstant()) {
727727
diagnose(astContext, sourceLoc, diag::oslog_non_constant_interpolation);
728728
return true;
@@ -743,7 +743,7 @@ static bool checkOSLogMessageIsConstant(SingleValueInstruction *osLogMessage,
743743

744744
auto propertyDecls = interpolationStruct->getStoredProperties();
745745
ArrayRef<SymbolicValue> propertyValues =
746-
osLogInterpolationValue.getAggregateValue();
746+
osLogInterpolationValue.getAggregateMembers();
747747
auto propValueI = propertyValues.begin();
748748
bool errorDetected = false;
749749

0 commit comments

Comments
 (0)