void swift:: collectDefaultImplementationForProtocolMembers(ProtocolDecl *PD, llvm::SmallDenseMap<ValueDecl*, ValueDecl*> &DefaultMap) { Type BaseTy = PD->getDeclaredInterfaceType(); DeclContext *DC = PD->getInnermostDeclContext(); auto HandleMembers = [&](DeclRange Members) { for (Decl *D : Members) { auto *VD = dyn_cast<ValueDecl>(D); // Skip non-value decl. if (!VD) continue; // Skip decls with empty names, e.g. setter/getters for properties. if (VD->getBaseName().empty()) continue; ResolvedMemberResult Result = resolveValueMember(*DC, BaseTy, VD->getFullName()); assert(Result); for (auto *Default : Result.getMemberDecls(InterestedMemberKind::All)) { if (PD == Default->getDeclContext()->getExtendedProtocolDecl()) { DefaultMap.insert({Default, VD}); } } } }; // Collect the default implementations for the members in this given protocol. HandleMembers(PD->getMembers()); // Collect the default implementations for the members in the inherited // protocols. for (auto *IP : PD->getInheritedProtocols()) HandleMembers(IP->getMembers()); }
void AllocOptimize:: computeAvailableValuesFrom(SILBasicBlock::iterator StartingFrom, SILBasicBlock *BB, llvm::SmallBitVector &RequiredElts, SmallVectorImpl<std::pair<SILValue, unsigned>> &Result, llvm::SmallDenseMap<SILBasicBlock*, llvm::SmallBitVector, 32> &VisitedBlocks, llvm::SmallBitVector &ConflictingValues) { assert(!RequiredElts.none() && "Scanning with a goal of finding nothing?"); // If there is a potential modification in the current block, scan the block // to see if the store or escape is before or after the load. If it is // before, check to see if it produces the value we are looking for. if (HasLocalDefinition.count(BB)) { for (SILBasicBlock::iterator BBI = StartingFrom; BBI != BB->begin();) { SILInstruction *TheInst = &*std::prev(BBI); // If this instruction is unrelated to the element, ignore it. if (!NonLoadUses.count(TheInst)) { --BBI; continue; } // Given an interesting instruction, incorporate it into the set of // results, and filter down the list of demanded subelements that we still // need. updateAvailableValues(TheInst, RequiredElts, Result, ConflictingValues); // If this satisfied all of the demanded values, we're done. if (RequiredElts.none()) return; // Otherwise, keep scanning the block. If the instruction we were looking // at just got exploded, don't skip the next instruction. if (&*std::prev(BBI) == TheInst) --BBI; } } // Otherwise, we need to scan up the CFG looking for available values. for (auto PI = BB->pred_begin(), E = BB->pred_end(); PI != E; ++PI) { SILBasicBlock *PredBB = *PI; // If the predecessor block has already been visited (potentially due to a // cycle in the CFG), don't revisit it. We can do this safely because we // are optimistically assuming that all incoming elements in a cycle will be // the same. If we ever detect a conflicting element, we record it and do // not look at the result. auto Entry = VisitedBlocks.insert({PredBB, RequiredElts}); if (!Entry.second) { // If we are revisiting a block and asking for different required elements // then anything that isn't agreeing is in conflict. const auto &PrevRequired = Entry.first->second; if (PrevRequired != RequiredElts) { ConflictingValues |= (PrevRequired ^ RequiredElts); RequiredElts &= ~ConflictingValues; if (RequiredElts.none()) return; } continue; } // Make sure to pass in the same set of required elements for each pred. llvm::SmallBitVector Elts = RequiredElts; computeAvailableValuesFrom(PredBB->end(), PredBB, Elts, Result, VisitedBlocks, ConflictingValues); // If we have any conflicting values, don't bother searching for them. RequiredElts &= ~ConflictingValues; if (RequiredElts.none()) return; } }