whitepaper: 366/178 — wave5 defect tables + PDF rebuild
This commit is contained in:
parent
835ae73b0f
commit
a4b0cf4edd
79 changed files with 3829 additions and 17 deletions
59
defects/swift/patch/swift-0002-requirement-machine-set.md
Normal file
59
defects/swift/patch/swift-0002-requirement-machine-set.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# swift-0001: isInMinimizationDomain — O(P) linear scan in O(R) rule loop
|
||||
|
||||
## Severity: HIGH
|
||||
|
||||
## Location
|
||||
- `lib/AST/RequirementMachine/RewriteSystem.cpp:484`
|
||||
- Called from loops in:
|
||||
- `lib/AST/RequirementMachine/HomotopyReduction.cpp:611,659,753`
|
||||
- `lib/AST/RequirementMachine/MinimalConformances.cpp:326`
|
||||
- `lib/AST/RequirementMachine/Diagnostics.cpp:349`
|
||||
- `lib/AST/RequirementMachine/PropertyUnification.cpp:133`
|
||||
|
||||
## Description
|
||||
`RewriteSystem::isInMinimizationDomain()` performs a linear `std::find` scan over
|
||||
`Protos` (an `ArrayRef<const ProtocolDecl *>`) on every call. This function is invoked
|
||||
inside loops over all rewrite `Rules` (size scales with protocol graph complexity).
|
||||
|
||||
**Complexity:** O(R × P) where R = rule count, P = protocol count in connected component.
|
||||
For a deeply hierarchical protocol graph with N protocols, both R and P are O(N),
|
||||
yielding O(N²) total cost during requirement signature minimization.
|
||||
|
||||
## Root Cause
|
||||
```cpp
|
||||
// RewriteSystem.cpp:478
|
||||
bool RewriteSystem::isInMinimizationDomain(const ProtocolDecl *proto) const {
|
||||
// ...
|
||||
if (std::find(Protos.begin(), Protos.end(), proto) != Protos.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
`Protos` is `ArrayRef<const ProtocolDecl *>` — a plain pointer array. `std::find` is O(P).
|
||||
Called inside every rule-scanning loop; no caching or set-based lookup.
|
||||
|
||||
## Fix
|
||||
Replace `ArrayRef<const ProtocolDecl *> Protos` with `llvm::DenseSet<const ProtocolDecl *> ProtoSet`
|
||||
populated once at construction, or cache a `llvm::SmallPtrSet` alongside the ArrayRef.
|
||||
Then `isInMinimizationDomain` becomes an O(1) hash set lookup.
|
||||
|
||||
```cpp
|
||||
// In RewriteSystem.h, add:
|
||||
llvm::SmallPtrSet<const ProtocolDecl *, 8> ProtoSet;
|
||||
|
||||
// In RewriteSystem::init or wherever Protos is set:
|
||||
ProtoSet.insert(Protos.begin(), Protos.end());
|
||||
|
||||
// In isInMinimizationDomain:
|
||||
bool RewriteSystem::isInMinimizationDomain(const ProtocolDecl *proto) const {
|
||||
if (proto == nullptr && Protos.empty())
|
||||
return true;
|
||||
return ProtoSet.count(proto) > 0;
|
||||
}
|
||||
```
|
||||
|
||||
## Impact
|
||||
Protocol-heavy Swift code (many protocols with complex inheritance) hits O(N²) during
|
||||
generic signature computation. Manifest as slow compilation on codebases with many protocols
|
||||
or deep protocol hierarchies (e.g., Combine/SwiftUI framework chains).
|
||||
Loading…
Add table
Add a link
Reference in a new issue