/// If \p Op has arc uses in the instruction range (Start, End], return the /// first such instruction. Otherwise return None. We assume that Start and End /// are both in the same basic block. Optional<SILBasicBlock::iterator> swift::valueHasARCUsesInReverseInstructionRange(SILValue Op, SILBasicBlock::iterator Start, SILBasicBlock::iterator End, AliasAnalysis *AA) { assert(Start->getParent() == End->getParent() && "Start and End should be in the same basic block"); assert(End != End->getParent()->end() && "End should be mapped to an actual instruction"); // If Start == End, then we have an empty range, return false. if (Start == End) return None; // Otherwise, until End == Start. while (Start != End) { // Check if Start can use Op in an ARC relevant way. If so, return true. if (mayUseValue(&*End, Op, AA)) return End; // Otherwise, decrement our iterator. --End; } // If all such instructions can not use Op, return false. return None; }
/// If \p Op has arc uses in the instruction range [Start, End), return the /// first such instruction. Otherwise return None. We assume that /// Start and End are both in the same basic block. Optional<SILBasicBlock::iterator> swift:: valueHasARCUsesInInstructionRange(SILValue Op, SILBasicBlock::iterator Start, SILBasicBlock::iterator End, AliasAnalysis *AA) { assert(Start->getParent() == End->getParent() && "Start and End should be in the same basic block"); // If Start == End, then we have an empty range, return false. if (Start == End) return None; // Otherwise, until Start != End. while (Start != End) { // Check if Start can use Op in an ARC relevant way. If so, return true. if (mayUseValue(&*Start, Op, AA)) return Start; // Otherwise, increment our iterator. ++Start; } // If all such instructions can not use Op, return false. return None; }
/// Perform outlining on the function and return any newly created outlined /// functions. bool tryOutline(SILOptFunctionBuilder &FuncBuilder, SILFunction *Fun, SmallVectorImpl<SILFunction *> &FunctionsAdded) { SmallPtrSet<SILBasicBlock *, 32> Visited; SmallVector<SILBasicBlock *, 128> Worklist; OutlinePatterns patterns(FuncBuilder); // Traverse the function. Worklist.push_back(&*Fun->begin()); while (!Worklist.empty()) { SILBasicBlock *CurBlock = Worklist.pop_back_val(); if (!Visited.insert(CurBlock).second) continue; SILBasicBlock::iterator CurInst = CurBlock->begin(); // Go over the instructions trying to match and replace patterns. while (CurInst != CurBlock->end()) { if (OutlinePattern *match = patterns.tryToMatch(CurInst)) { SILFunction *F; SILBasicBlock::iterator LastInst; std::tie(F, LastInst) = match->outline(Fun->getModule()); if (F) FunctionsAdded.push_back(F); CurInst = LastInst; assert(LastInst->getParent() == CurBlock); } else if (isa<TermInst>(CurInst)) { std::copy(CurBlock->succ_begin(), CurBlock->succ_end(), std::back_inserter(Worklist)); ++CurInst; } else { ++CurInst; } } } return false; }