@@ -26,12 +26,13 @@ class SILValue;
26
26
class SILBuilder ;
27
27
class SerializedSILLoader ;
28
28
29
- struct APIntSymbolicValue ;
30
29
struct APFloatSymbolicValue ;
31
- struct EnumWithPayloadSymbolicValue ;
30
+ struct APIntSymbolicValue ;
32
31
struct ArraySymbolicValue ;
33
32
struct DerivedAddressValue ;
33
+ struct EnumWithPayloadSymbolicValue ;
34
34
struct SymbolicValueMemoryObject ;
35
+ struct UnknownSymbolicValue ;
35
36
36
37
// / When we fail to constant fold a value, this captures a reason why,
37
38
// / allowing the caller to produce a specific diagnostic. The "Unknown"
@@ -56,7 +57,6 @@ enum class UnknownReason {
56
57
Trap,
57
58
};
58
59
59
-
60
60
// / This is the symbolic value tracked for each SILValue in a scope. We
61
61
// / support multiple representational forms for the constant node in order to
62
62
// / avoid pointless memory bloat + copying. This is intended to be a
@@ -66,6 +66,7 @@ enum class UnknownReason {
66
66
// / symbolic values (e.g. to save memory). It provides a simpler public
67
67
// / interface though.
68
68
class SymbolicValue {
69
+ private:
69
70
enum RepresentationKind {
70
71
// / This value is an alloc stack that is has not (yet) been initialized
71
72
// / by flow-sensitive analysis.
@@ -133,11 +134,9 @@ class SymbolicValue {
133
134
};
134
135
135
136
union {
136
- // / When the value is Unknown, this contains the value that was the
137
+ // / When the value is Unknown, this contains information about the
137
138
// / unfoldable part of the computation.
138
- // /
139
- // / TODO: make this a more rich representation.
140
- SILNode *unknown;
139
+ UnknownSymbolicValue *unknown;
141
140
142
141
// / This is always a SILType with an object category. This is the value
143
142
// / of the underlying instance type, not the MetatypeType.
@@ -217,7 +216,6 @@ class SymbolicValue {
217
216
} aux;
218
217
219
218
public:
220
-
221
219
// / This enum is used to indicate the sort of value held by a SymbolicValue
222
220
// / independent of its concrete representation. This is the public
223
221
// / interface to SymbolicValue.
@@ -270,25 +268,21 @@ class SymbolicValue {
270
268
return kind != Unknown && kind != UninitMemory;
271
269
}
272
270
273
- static SymbolicValue getUnknown (SILNode *node, UnknownReason reason) {
274
- assert (node && " node must be present" );
275
- SymbolicValue result;
276
- result.representationKind = RK_Unknown;
277
- result.value .unknown = node;
278
- result.aux .unknown_reason = reason;
279
- return result;
280
- }
271
+ static SymbolicValue getUnknown (SILNode *node, UnknownReason reason,
272
+ llvm::ArrayRef<SourceLoc> callStack,
273
+ llvm::BumpPtrAllocator &allocator);
281
274
282
- bool isUnknown () const {
283
- return getKind () == Unknown;
284
- }
275
+ // / Return true if this represents an unknown result.
276
+ bool isUnknown () const { return getKind () == Unknown; }
285
277
286
- // / Return information about an unknown result, including the SIL node that
287
- // / is a problem, and the reason it is an issue.
288
- std::pair<SILNode *, UnknownReason> getUnknownValue () const {
289
- assert (representationKind == RK_Unknown);
290
- return { value.unknown , aux.unknown_reason };
291
- }
278
+ // / Return the call stack for an unknown result.
279
+ ArrayRef<SourceLoc> getUnknownCallStack () const ;
280
+
281
+ // / Return the node that triggered an unknown result.
282
+ SILNode *getUnknownNode () const ;
283
+
284
+ // / Return the reason an unknown result was generated.
285
+ UnknownReason getUnknownReason () const ;
292
286
293
287
static SymbolicValue getUninitMemory () {
294
288
SymbolicValue result;
@@ -381,7 +375,6 @@ class SymbolicValue {
381
375
382
376
SymbolicValue getEnumPayloadValue () const ;
383
377
384
-
385
378
// / Return a symbolic value that represents the address of a memory object.
386
379
static SymbolicValue getAddress (SymbolicValueMemoryObject *memoryObject) {
387
380
SymbolicValue result;
@@ -405,11 +398,12 @@ class SymbolicValue {
405
398
SymbolicValueMemoryObject *getAddressValueMemoryObject () const ;
406
399
407
400
// / Produce an array of elements.
408
-
401
+
409
402
static SymbolicValue getArray (ArrayRef<SymbolicValue> elements,
410
403
CanType elementType,
411
404
llvm::BumpPtrAllocator &allocator);
412
- static SymbolicValue getArrayAddress (SymbolicValueMemoryObject *memoryObject){
405
+ static SymbolicValue
406
+ getArrayAddress (SymbolicValueMemoryObject *memoryObject) {
413
407
SymbolicValue result;
414
408
result.representationKind = RK_ArrayAddress;
415
409
result.value .directAddress = memoryObject;
@@ -439,7 +433,7 @@ class SymbolicValue {
439
433
void dump () const ;
440
434
};
441
435
442
- static_assert (sizeof (SymbolicValue) == 2 * sizeof (void *),
436
+ static_assert (sizeof (SymbolicValue) == 2 * sizeof (void *),
443
437
" SymbolicValue should stay small and POD" );
444
438
445
439
inline llvm::raw_ostream &operator <<(llvm::raw_ostream &os, SymbolicValue val) {
@@ -465,12 +459,11 @@ struct SymbolicValueMemoryObject {
465
459
SymbolicValue value;
466
460
467
461
SymbolicValueMemoryObject (Type type, SymbolicValue value)
468
- : type(type), value(value) {}
469
- SymbolicValueMemoryObject (const SymbolicValueMemoryObject&) = delete ;
470
- void operator =(const SymbolicValueMemoryObject&) = delete ;
462
+ : type(type), value(value) {}
463
+ SymbolicValueMemoryObject (const SymbolicValueMemoryObject &) = delete ;
464
+ void operator =(const SymbolicValueMemoryObject &) = delete ;
471
465
};
472
466
473
-
474
467
// / SWIFT_ENABLE_TENSORFLOW
475
468
// / A graph operation attribute, used by GraphOperationInst.
476
469
// / Attributes have a name and a constant value.
0 commit comments