|
19 | 19 |
|
20 | 20 | using namespace swift;
|
21 | 21 |
|
| 22 | +// Max depth of a bound generic which can be processed by the generic |
| 23 | +// specializer. |
| 24 | +// E.g. the depth of Array<Array<Array<T>>> is 3. |
| 25 | +// No specializations will be produced, if any of generic parameters contains |
| 26 | +// a bound generic type with the depth higher than this threshold |
| 27 | +static const unsigned BoundGenericDepthThreshold = 50; |
| 28 | + |
| 29 | +static unsigned getBoundGenericDepth(Type t) { |
| 30 | + unsigned Depth = 0; |
| 31 | + if (auto BGT = t->getAs<BoundGenericType>()) { |
| 32 | + Depth++; |
| 33 | + auto GenericArgs = BGT->getGenericArgs(); |
| 34 | + unsigned MaxGenericArgDepth = 0; |
| 35 | + for (auto GenericArg : GenericArgs) { |
| 36 | + auto ArgDepth = getBoundGenericDepth(GenericArg); |
| 37 | + if (ArgDepth > MaxGenericArgDepth) |
| 38 | + MaxGenericArgDepth = ArgDepth; |
| 39 | + } |
| 40 | + Depth += MaxGenericArgDepth; |
| 41 | + } |
| 42 | + return Depth; |
| 43 | +} |
| 44 | + |
22 | 45 | // =============================================================================
|
23 | 46 | // ReabstractionInfo
|
24 | 47 | // =============================================================================
|
@@ -50,6 +73,19 @@ ReabstractionInfo::ReabstractionInfo(SILFunction *OrigF,
|
50 | 73 | DEBUG(llvm::dbgs() << " Cannot specialize with dynamic self.\n");
|
51 | 74 | return;
|
52 | 75 | }
|
| 76 | + |
| 77 | + // Check if the substitution contains any generic types that are too deep. |
| 78 | + // If this is the case, bail to avoid the explosion in the number of |
| 79 | + // generated specializations. |
| 80 | + for (auto Sub : ParamSubs) { |
| 81 | + auto Replacement = Sub.getReplacement(); |
| 82 | + if (Replacement.findIf([](Type ty) -> bool { |
| 83 | + return getBoundGenericDepth(ty) >= BoundGenericDepthThreshold; |
| 84 | + })) { |
| 85 | + return; |
| 86 | + } |
| 87 | + } |
| 88 | + |
53 | 89 | SILModule &M = OrigF->getModule();
|
54 | 90 | Module *SM = M.getSwiftModule();
|
55 | 91 |
|
|
0 commit comments