diff --git a/include/swift/SILOptimizer/Utils/SILSSAUpdater.h b/include/swift/SILOptimizer/Utils/SILSSAUpdater.h index f222f2309cc79..6cac152cd8ce4 100644 --- a/include/swift/SILOptimizer/Utils/SILSSAUpdater.h +++ b/include/swift/SILOptimizer/Utils/SILSSAUpdater.h @@ -18,9 +18,14 @@ #include "swift/SIL/SILValue.h" namespace llvm { - template class SSAUpdaterTraits; - template class SmallVectorImpl; -} + +template +class SSAUpdaterTraits; + +template +class SmallVectorImpl; + +} // namespace llvm namespace swift { @@ -31,7 +36,7 @@ class SILUndef; /// Independent utility that canonicalizes BB arguments by reusing structurally /// equivalent arguments and replacing the original arguments with casts. -SILValue replaceBBArgWithCast(SILPhiArgument *Arg); +SILValue replaceBBArgWithCast(SILPhiArgument *arg); /// This class updates SSA for a set of SIL instructions defined in multiple /// blocks. @@ -40,16 +45,16 @@ class SILSSAUpdater { // A map of basic block to available phi value. using AvailableValsTy = llvm::DenseMap; - std::unique_ptr AV; + std::unique_ptr blockToAvailableValueMap; - SILType ValType; + SILType type; // The SSAUpdaterTraits specialization uses this sentinel to mark 'new' phi // nodes (all the incoming edge arguments have this sentinel set). - std::unique_ptr PHISentinel; + std::unique_ptr phiSentinel; // If not null updated with inserted 'phi' nodes (SILArgument). - SmallVectorImpl *InsertedPHIs; + SmallVectorImpl *insertedPhis; // Not copyable. void operator=(const SILSSAUpdater &) = delete; @@ -57,21 +62,21 @@ class SILSSAUpdater { public: explicit SILSSAUpdater( - SmallVectorImpl *InsertedPHIs = nullptr); + SmallVectorImpl *insertedPhis = nullptr); ~SILSSAUpdater(); - void setInsertedPhis(SmallVectorImpl *insertedPhis) { - InsertedPHIs = insertedPhis; + void setInsertedPhis(SmallVectorImpl *inputInsertedPhis) { + insertedPhis = inputInsertedPhis; } /// Initialize for a use of a value of type. - void Initialize(SILType T); + void initialize(SILType type); - bool HasValueForBlock(SILBasicBlock *BB) const; - void AddAvailableValue(SILBasicBlock *BB, SILValue V); + bool hasValueForBlock(SILBasicBlock *block) const; + void addAvailableValue(SILBasicBlock *block, SILValue value); /// Construct SSA for a value that is live at the *end* of a basic block. - SILValue GetValueAtEndOfBlock(SILBasicBlock *BB); + SILValue getValueAtEndOfBlock(SILBasicBlock *block); /// Construct SSA for a value that is live in the middle of a block. /// This handles the case where the use is before a definition of the value. @@ -85,15 +90,15 @@ class SILSSAUpdater { /// /// In this case we need to insert a 'PHI' node at the beginning of BB2 /// merging val_1 and val_2. - SILValue GetValueInMiddleOfBlock(SILBasicBlock *BB); + SILValue getValueInMiddleOfBlock(SILBasicBlock *block); - void RewriteUse(Operand &Op); + void rewriteUse(Operand &operand); - void *allocate(unsigned Size, unsigned Align) const; - static void deallocateSentinel(SILUndef *U); -private: + void *allocate(unsigned size, unsigned align) const; + static void deallocateSentinel(SILUndef *undef); - SILValue GetValueAtEndOfBlockInternal(SILBasicBlock *BB); +private: + SILValue getValueAtEndOfBlockInternal(SILBasicBlock *block); }; /// Utility to wrap 'Operand's to deal with invalidation of @@ -112,15 +117,15 @@ class SILSSAUpdater { /// identify the use allowing us to reconstruct the use after the branch has /// been changed. class UseWrapper { - Operand *U; - SILBasicBlock *Parent; + Operand *wrappedUse; + SILBasicBlock *parent; enum { kRegularUse, kBranchUse, kCondBranchUseTrue, kCondBranchUseFalse - } Type; - unsigned Idx; + } type; + unsigned index; public: @@ -131,7 +136,7 @@ class UseWrapper { /// (ValueUseIterator) become invalid as they point to freed operands. /// Instead we store the branch's parent and the idx so that we can /// reconstruct the use. - UseWrapper(Operand *Use); + UseWrapper(Operand *use); Operand *getOperand(); diff --git a/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp b/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp index b734d134cf29e..76a30bfaca3d2 100644 --- a/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp +++ b/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp @@ -519,13 +519,13 @@ class RegionCloner : public SILCloner { return; // Update SSA form. - SSAUp.Initialize(V->getType()); - SSAUp.AddAvailableValue(OrigBB, V); + SSAUp.initialize(V->getType()); + SSAUp.addAvailableValue(OrigBB, V); SILValue NewVal = getMappedValue(V); - SSAUp.AddAvailableValue(getOpBasicBlock(OrigBB), NewVal); + SSAUp.addAvailableValue(getOpBasicBlock(OrigBB), NewVal); for (auto U : UseList) { Operand *Use = U; - SSAUp.RewriteUse(*Use); + SSAUp.rewriteUse(*Use); } } diff --git a/lib/SILOptimizer/LoopTransforms/LICM.cpp b/lib/SILOptimizer/LoopTransforms/LICM.cpp index 79e5bd6d96b8e..e4be5ac35f5fa 100644 --- a/lib/SILOptimizer/LoopTransforms/LICM.cpp +++ b/lib/SILOptimizer/LoopTransforms/LICM.cpp @@ -1062,8 +1062,8 @@ void LoopTreeOptimization::hoistLoadsAndStores(SILValue addr, SILLoop *loop, Ins LLVM_DEBUG(llvm::dbgs() << "Creating preload " << *initialLoad); SILSSAUpdater ssaUpdater; - ssaUpdater.Initialize(initialLoad->getType()); - ssaUpdater.AddAvailableValue(preheader, initialLoad); + ssaUpdater.initialize(initialLoad->getType()); + ssaUpdater.addAvailableValue(preheader, initialLoad); // Set all stored values as available values in the ssaUpdater. // If there are multiple stores in a block, only the last one counts. @@ -1078,7 +1078,7 @@ void LoopTreeOptimization::hoistLoadsAndStores(SILValue addr, SILLoop *loop, Ins if (isLoadFromAddr(dyn_cast(SI->getSrc()), addr)) return; - ssaUpdater.AddAvailableValue(SI->getParent(), SI->getSrc()); + ssaUpdater.addAvailableValue(SI->getParent(), SI->getSrc()); } } @@ -1099,7 +1099,7 @@ void LoopTreeOptimization::hoistLoadsAndStores(SILValue addr, SILLoop *loop, Ins // If we didn't see a store in this block yet, get the current value from // the ssaUpdater. if (!currentVal) - currentVal = ssaUpdater.GetValueInMiddleOfBlock(block); + currentVal = ssaUpdater.getValueInMiddleOfBlock(block); SILValue projectedValue = projectLoadValue(LI->getOperand(), addr, currentVal, LI); LLVM_DEBUG(llvm::dbgs() << "Replacing stored load " << *LI << " with " @@ -1117,8 +1117,8 @@ void LoopTreeOptimization::hoistLoadsAndStores(SILValue addr, SILLoop *loop, Ins "should have split critical edges"); SILBuilder B(succ->begin()); auto *SI = B.createStore(loc.getValue(), - ssaUpdater.GetValueInMiddleOfBlock(succ), - addr, StoreOwnershipQualifier::Unqualified); + ssaUpdater.getValueInMiddleOfBlock(succ), addr, + StoreOwnershipQualifier::Unqualified); (void)SI; LLVM_DEBUG(llvm::dbgs() << "Creating loop-exit store " << *SI); } diff --git a/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp b/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp index ea9521f061b2f..fff3b201dc415 100644 --- a/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp +++ b/lib/SILOptimizer/LoopTransforms/LoopRotate.cpp @@ -131,9 +131,9 @@ static void updateSSAForUseOfValue( assert(Res->getType() == MappedValue->getType() && "The types must match"); insertedPhis.clear(); - updater.Initialize(Res->getType()); - updater.AddAvailableValue(Header, Res); - updater.AddAvailableValue(EntryCheckBlock, MappedValue); + updater.initialize(Res->getType()); + updater.addAvailableValue(Header, Res); + updater.addAvailableValue(EntryCheckBlock, MappedValue); // Because of the way that phi nodes are represented we have to collect all // uses before we update SSA. Modifying one phi node can invalidate another @@ -155,7 +155,7 @@ static void updateSSAForUseOfValue( assert(user->getParent() != EntryCheckBlock && "The entry check block should dominate the header"); - updater.RewriteUse(*use); + updater.rewriteUse(*use); } // Canonicalize inserted phis to avoid extra BB Args. for (SILPhiArgument *arg : insertedPhis) { diff --git a/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp b/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp index 752e74ecc7001..967bfdbf4d468 100644 --- a/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp +++ b/lib/SILOptimizer/LoopTransforms/LoopUnroll.cpp @@ -334,13 +334,13 @@ updateSSA(SILModule &M, SILLoop *Loop, if (!Loop->contains(Use->getUser()->getParent())) UseList.push_back(UseWrapper(Use)); // Update SSA of use with the available values. - SSAUp.Initialize(OrigValue->getType()); - SSAUp.AddAvailableValue(OrigValue->getParentBlock(), OrigValue); + SSAUp.initialize(OrigValue->getType()); + SSAUp.addAvailableValue(OrigValue->getParentBlock(), OrigValue); for (auto NewValue : MapEntry.second) - SSAUp.AddAvailableValue(NewValue->getParentBlock(), NewValue); + SSAUp.addAvailableValue(NewValue->getParentBlock(), NewValue); for (auto U : UseList) { Operand *Use = U; - SSAUp.RewriteUse(*Use); + SSAUp.rewriteUse(*Use); } } } diff --git a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp index 093cb4482e6b1..ff14e4a0f05ea 100644 --- a/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp +++ b/lib/SILOptimizer/Mandatory/ClosureLifetimeFixup.cpp @@ -244,7 +244,7 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn, // lifetime respecting loops. SmallVector insertedPhis; SILSSAUpdater updater(&insertedPhis); - updater.Initialize(optionalEscapingClosureTy); + updater.initialize(optionalEscapingClosureTy); // Create an Optional<() -> ()>.none in the entry block of the function and // add it as an available value to the SSAUpdater. @@ -256,7 +256,7 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn, SILBuilderWithScope b(fn.getEntryBlock()->begin()); return b.createOptionalNone(loc, optionalEscapingClosureTy); }(); - updater.AddAvailableValue(fn.getEntryBlock(), entryBlockOptionalNone); + updater.addAvailableValue(fn.getEntryBlock(), entryBlockOptionalNone); // Create a copy of the convert_escape_to_no_escape and add it as an available // value to the SSA updater. @@ -270,7 +270,7 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn, cvt->setLifetimeGuaranteed(); cvt->setOperand(innerCVI); SILBuilderWithScope b(std::next(cvt->getIterator())); - updater.AddAvailableValue( + updater.addAvailableValue( cvt->getParent(), b.createOptionalSome(loc, innerCVI, optionalEscapingClosureTy)); return innerCVI; @@ -284,13 +284,13 @@ static void extendLifetimeToEndOfFunction(SILFunction &fn, { // Before the copy value, insert an extra destroy_value to handle // loops. Since we used our enum value this is safe. - SILValue v = updater.GetValueInMiddleOfBlock(cvi->getParent()); + SILValue v = updater.getValueInMiddleOfBlock(cvi->getParent()); SILBuilderWithScope(cvi).createDestroyValue(loc, v); } for (auto *block : exitingBlocks) { auto *safeDestructionPt = getDeinitSafeClosureDestructionPoint(block); - SILValue v = updater.GetValueAtEndOfBlock(block); + SILValue v = updater.getValueAtEndOfBlock(block); SILBuilderWithScope(safeDestructionPt).createDestroyValue(loc, v); } @@ -849,7 +849,7 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb, SmallVector insertedPhis; SILSSAUpdater updater(&insertedPhis); - updater.Initialize(optionalEscapingClosureTy); + updater.initialize(optionalEscapingClosureTy); // Create the Optional.none as the beginning available value. SILValue entryBlockOptionalNone; @@ -857,7 +857,7 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb, SILBuilderWithScope b(fn.getEntryBlock()->begin()); entryBlockOptionalNone = b.createOptionalNone(autoGenLoc, optionalEscapingClosureTy); - updater.AddAvailableValue(fn.getEntryBlock(), entryBlockOptionalNone); + updater.addAvailableValue(fn.getEntryBlock(), entryBlockOptionalNone); } assert(entryBlockOptionalNone); @@ -872,7 +872,7 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb, // operand consumed at +1, so we don't need a copy) to it. auto *result = b.createOptionalSome(autoGenLoc, sentinelClosure, optionalEscapingClosureTy); - updater.AddAvailableValue(result->getParent(), result); + updater.addAvailableValue(result->getParent(), result); return result; }(); @@ -881,14 +881,14 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb, if (singleDestroy) { SILBuilderWithScope b(std::next(singleDestroy->getIterator())); auto *result = b.createOptionalNone(autoGenLoc, optionalEscapingClosureTy); - updater.AddAvailableValue(result->getParent(), result); + updater.addAvailableValue(result->getParent(), result); } // Now that we have all of our available values, insert a destroy_value before // the initial Optional.some value using the SSA updater to ensure that we // handle loops correctly. { - SILValue v = updater.GetValueInMiddleOfBlock(initialValue->getParent()); + SILValue v = updater.getValueInMiddleOfBlock(initialValue->getParent()); SILBuilderWithScope(initialValue).createDestroyValue(autoGenLoc, v); } @@ -896,7 +896,7 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb, // lifetime end points. This ensures we do not expand our lifetime too much. if (singleDestroy) { SILBuilderWithScope b(std::next(singleDestroy->getIterator())); - SILValue v = updater.GetValueInMiddleOfBlock(singleDestroy->getParent()); + SILValue v = updater.getValueInMiddleOfBlock(singleDestroy->getParent()); SILValue isEscaping = b.createIsEscapingClosure(loc, v, IsEscapingClosureInst::ObjCEscaping); b.createCondFail(loc, isEscaping, "non-escaping closure has escaped"); @@ -911,7 +911,7 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb, for (auto *block : exitingBlocks) { auto *safeDestructionPt = getDeinitSafeClosureDestructionPoint(block); - SILValue v = updater.GetValueAtEndOfBlock(block); + SILValue v = updater.getValueAtEndOfBlock(block); SILBuilderWithScope(safeDestructionPt).createDestroyValue(autoGenLoc, v); } } diff --git a/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp index 5d4d4f889cb6c..1b7a6c384fc80 100644 --- a/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp +++ b/lib/SILOptimizer/Mandatory/PredictableMemOpt.cpp @@ -686,7 +686,7 @@ AvailableValueAggregator::aggregateFullyAvailableValue(SILType loadTy, // have multiple insertion points if we are storing exactly the same value // implying that we can just copy firstVal at each insertion point. SILSSAUpdater updater(&insertedPhiNodes); - updater.Initialize(loadTy); + updater.initialize(loadTy); Optional singularValue; for (auto *insertPt : insertPts) { @@ -707,7 +707,7 @@ AvailableValueAggregator::aggregateFullyAvailableValue(SILType loadTy, } // And then put the value into the SSA updater. - updater.AddAvailableValue(insertPt->getParent(), eltVal); + updater.addAvailableValue(insertPt->getParent(), eltVal); } // If we only are tracking a singular value, we do not need to construct @@ -727,7 +727,7 @@ AvailableValueAggregator::aggregateFullyAvailableValue(SILType loadTy, } // Finally, grab the value from the SSA updater. - SILValue result = updater.GetValueInMiddleOfBlock(B.getInsertionBB()); + SILValue result = updater.getValueInMiddleOfBlock(B.getInsertionBB()); assert(result.getOwnershipKind().isCompatibleWith(ValueOwnershipKind::Owned)); if (isTake() || !B.hasOwnership()) { return result; @@ -863,7 +863,7 @@ SILValue AvailableValueAggregator::handlePrimitiveValue(SILType loadTy, // never have the same value along all paths unless we have a trivial value // meaning the SSA updater given a non-trivial value must /always/ be used. SILSSAUpdater updater(&insertedPhiNodes); - updater.Initialize(loadTy); + updater.initialize(loadTy); Optional singularValue; for (auto *i : insertPts) { @@ -881,7 +881,7 @@ SILValue AvailableValueAggregator::handlePrimitiveValue(SILType loadTy, singularValue = SILValue(); } - updater.AddAvailableValue(i->getParent(), eltVal); + updater.addAvailableValue(i->getParent(), eltVal); } SILBasicBlock *insertBlock = B.getInsertionBB(); @@ -902,7 +902,7 @@ SILValue AvailableValueAggregator::handlePrimitiveValue(SILType loadTy, } // Finally, grab the value from the SSA updater. - SILValue eltVal = updater.GetValueInMiddleOfBlock(insertBlock); + SILValue eltVal = updater.getValueInMiddleOfBlock(insertBlock); assert(!B.hasOwnership() || eltVal.getOwnershipKind().isCompatibleWith(ValueOwnershipKind::Owned)); assert(eltVal->getType() == loadTy && "Subelement types mismatch"); diff --git a/lib/SILOptimizer/Transforms/DeadObjectElimination.cpp b/lib/SILOptimizer/Transforms/DeadObjectElimination.cpp index fff5fafdde1f7..a040d1166d176 100644 --- a/lib/SILOptimizer/Transforms/DeadObjectElimination.cpp +++ b/lib/SILOptimizer/Transforms/DeadObjectElimination.cpp @@ -535,10 +535,10 @@ static void insertReleases(ArrayRef Stores, assert(!Stores.empty()); SILValue StVal = Stores.front()->getSrc(); - SSAUp.Initialize(StVal->getType()); + SSAUp.initialize(StVal->getType()); for (auto *Store : Stores) - SSAUp.AddAvailableValue(Store->getParent(), Store->getSrc()); + SSAUp.addAvailableValue(Store->getParent(), Store->getSrc()); SILLocation Loc = Stores[0]->getLoc(); for (auto *RelPoint : ReleasePoints) { @@ -547,7 +547,7 @@ static void insertReleases(ArrayRef Stores, // the right thing for local uses. We have already ensured a single store // per block, and all release points occur after all stores. Therefore we // can simply ask SSAUpdater for the reaching store. - SILValue RelVal = SSAUp.GetValueAtEndOfBlock(RelPoint->getParent()); + SILValue RelVal = SSAUp.getValueAtEndOfBlock(RelPoint->getParent()); if (StVal->getType().isReferenceCounted(RelPoint->getModule())) B.createStrongRelease(Loc, RelVal, B.getDefaultAtomicity()); else diff --git a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp index 06968a86b32a5..373d62d92c976 100644 --- a/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp +++ b/lib/SILOptimizer/Transforms/RedundantLoadElimination.cpp @@ -1337,14 +1337,14 @@ SILValue RLEContext::computePredecessorLocationValue(SILBasicBlock *BB, // Finally, collect all the values for the SILArgument, materialize it using // the SSAUpdater. - Updater.Initialize( + Updater.initialize( L.getType(&BB->getModule(), TypeExpansionContext(*BB->getParent())) .getObjectType()); for (auto V : Values) { - Updater.AddAvailableValue(V.first, V.second); + Updater.addAvailableValue(V.first, V.second); } - return Updater.GetValueInMiddleOfBlock(BB); + return Updater.getValueInMiddleOfBlock(BB); } bool RLEContext::collectLocationValues(SILBasicBlock *BB, LSLocation &L, diff --git a/lib/SILOptimizer/Utils/BasicBlockOptUtils.cpp b/lib/SILOptimizer/Utils/BasicBlockOptUtils.cpp index a70372768b507..6b5a52240da00 100644 --- a/lib/SILOptimizer/Utils/BasicBlockOptUtils.cpp +++ b/lib/SILOptimizer/Utils/BasicBlockOptUtils.cpp @@ -107,9 +107,9 @@ void BasicBlockCloner::updateSSAAfterCloning() { for (auto *use : inst->getUses()) useList.push_back(UseWrapper(use)); - ssaUpdater.Initialize(inst->getType()); - ssaUpdater.AddAvailableValue(origBB, inst); - ssaUpdater.AddAvailableValue(getNewBB(), newResult); + ssaUpdater.initialize(inst->getType()); + ssaUpdater.addAvailableValue(origBB, inst); + ssaUpdater.addAvailableValue(getNewBB(), newResult); if (useList.empty()) continue; @@ -124,7 +124,7 @@ void BasicBlockCloner::updateSSAAfterCloning() { if (user->getParent() == origBB) continue; - ssaUpdater.RewriteUse(*use); + ssaUpdater.rewriteUse(*use); } } } diff --git a/lib/SILOptimizer/Utils/SILSSAUpdater.cpp b/lib/SILOptimizer/Utils/SILSSAUpdater.cpp index ba37d210559d3..92dec29e38461 100644 --- a/lib/SILOptimizer/Utils/SILSSAUpdater.cpp +++ b/lib/SILOptimizer/Utils/SILSSAUpdater.cpp @@ -25,71 +25,75 @@ using namespace swift; -void *SILSSAUpdater::allocate(unsigned Size, unsigned Align) const { - return AlignedAlloc(Size, Align); +void *SILSSAUpdater::allocate(unsigned size, unsigned align) const { + return AlignedAlloc(size, align); } -void SILSSAUpdater::deallocateSentinel(SILUndef *D) { - AlignedFree(D); +void SILSSAUpdater::deallocateSentinel(SILUndef *undef) { + AlignedFree(undef); } -SILSSAUpdater::SILSSAUpdater(SmallVectorImpl *PHIs) - : AV(nullptr), PHISentinel(nullptr, deallocateSentinel), - InsertedPHIs(PHIs) {} +SILSSAUpdater::SILSSAUpdater(SmallVectorImpl *phis) + : blockToAvailableValueMap(nullptr), + phiSentinel(nullptr, deallocateSentinel), insertedPhis(phis) {} SILSSAUpdater::~SILSSAUpdater() = default; -void SILSSAUpdater::Initialize(SILType Ty) { - ValType = Ty; +void SILSSAUpdater::initialize(SILType inputType) { + type = inputType; - PHISentinel = std::unique_ptr( - SILUndef::getSentinelValue(Ty, this), SILSSAUpdater::deallocateSentinel); + phiSentinel = std::unique_ptr( + SILUndef::getSentinelValue(inputType, this), + SILSSAUpdater::deallocateSentinel); - if (!AV) - AV.reset(new AvailableValsTy()); + if (!blockToAvailableValueMap) + blockToAvailableValueMap.reset(new AvailableValsTy()); else - AV->clear(); + blockToAvailableValueMap->clear(); } -bool SILSSAUpdater::HasValueForBlock(SILBasicBlock *BB) const { - return AV->count(BB); +bool SILSSAUpdater::hasValueForBlock(SILBasicBlock *block) const { + return blockToAvailableValueMap->count(block); } /// Indicate that a rewritten value is available in the specified block with the /// specified value. -void SILSSAUpdater::AddAvailableValue(SILBasicBlock *BB, SILValue V) { - (*AV)[BB] = V; +void SILSSAUpdater::addAvailableValue(SILBasicBlock *block, SILValue value) { + (*blockToAvailableValueMap)[block] = value; } /// Construct SSA form, materializing a value that is live at the end of the /// specified block. -SILValue SILSSAUpdater::GetValueAtEndOfBlock(SILBasicBlock *BB) { - return GetValueAtEndOfBlockInternal(BB); +SILValue SILSSAUpdater::getValueAtEndOfBlock(SILBasicBlock *block) { + return getValueAtEndOfBlockInternal(block); } /// Are all available values identicalTo each other. -static bool areIdentical(llvm::DenseMap &Avails) { - if (auto *First = dyn_cast(Avails.begin()->second)) { - for (auto Avail : Avails) { - auto *Inst = dyn_cast(Avail.second); - if (!Inst) +static bool +areIdentical(llvm::DenseMap &availableValues) { + if (auto *firstInst = + dyn_cast(availableValues.begin()->second)) { + for (auto value : availableValues) { + auto *svi = dyn_cast(value.second); + if (!svi) return false; - if (!Inst->isIdenticalTo(First)) + if (!svi->isIdenticalTo(firstInst)) return false; } return true; } - auto *MVIR = dyn_cast(Avails.begin()->second); - if (!MVIR) + auto *mvir = + dyn_cast(availableValues.begin()->second); + if (!mvir) return false; - for (auto Avail : Avails) { - auto *Result = dyn_cast(Avail.second); - if (!Result) + for (auto value : availableValues) { + auto *result = dyn_cast(value.second); + if (!result) return false; - if (!Result->getParent()->isIdenticalTo(MVIR->getParent()) || - Result->getIndex() != MVIR->getIndex()) { + if (!result->getParent()->isIdenticalTo(mvir->getParent()) || + result->getIndex() != mvir->getIndex()) { return false; } } @@ -98,65 +102,61 @@ static bool areIdentical(llvm::DenseMap &Avails) { /// This should be called in top-down order of each def that needs its uses /// rewrited. The order that we visit uses for a given def is irrelevant. -void SILSSAUpdater::RewriteUse(Operand &Op) { +void SILSSAUpdater::rewriteUse(Operand &use) { // Replicate function_refs to their uses. SILGen can't build phi nodes for // them and it would not make much sense anyways. - if (auto *FR = dyn_cast(Op.get())) { - assert(areIdentical(*AV) && + if (auto *fri = dyn_cast(use.get())) { + assert(areIdentical(*blockToAvailableValueMap) && "The function_refs need to have the same value"); - SILInstruction *User = Op.getUser(); - auto *NewFR = cast(FR->clone(User)); - Op.set(NewFR); + SILInstruction *user = use.getUser(); + use.set(cast(fri->clone(user))); return; - } else if (auto *FR = dyn_cast(Op.get())) { - assert(areIdentical(*AV) && + } else if (auto *pdfri = + dyn_cast(use.get())) { + assert(areIdentical(*blockToAvailableValueMap) && "The function_refs need to have the same value"); - SILInstruction *User = Op.getUser(); - auto *NewFR = cast(FR->clone(User)); - Op.set(NewFR); + SILInstruction *user = use.getUser(); + use.set(cast(pdfri->clone(user))); return; - } else if (auto *FR = dyn_cast(Op.get())) { - assert(areIdentical(*AV) && + } else if (auto *dfri = dyn_cast(use.get())) { + assert(areIdentical(*blockToAvailableValueMap) && "The function_refs need to have the same value"); - SILInstruction *User = Op.getUser(); - auto *NewFR = cast(FR->clone(User)); - Op.set(NewFR); + SILInstruction *user = use.getUser(); + use.set(cast(dfri->clone(user))); return; - } else if (auto *IL = dyn_cast(Op.get())) - if (areIdentical(*AV)) { + } else if (auto *ili = dyn_cast(use.get())) + if (areIdentical(*blockToAvailableValueMap)) { // Some llvm intrinsics don't like phi nodes as their constant inputs (e.g // ctlz). - SILInstruction *User = Op.getUser(); - auto *NewIL = cast(IL->clone(User)); - Op.set(NewIL); + SILInstruction *user = use.getUser(); + use.set(cast(ili->clone(user))); return; } // Again we need to be careful here, because ssa construction (with the // existing representation) can change the operand from under us. - UseWrapper UW(&Op); + UseWrapper useWrapper(&use); - SILInstruction *User = Op.getUser(); - SILValue NewVal = GetValueInMiddleOfBlock(User->getParent()); - assert(NewVal && "Need a valid value"); - ((Operand *)UW)->set((SILValue)NewVal); + SILInstruction *user = use.getUser(); + SILValue newVal = getValueInMiddleOfBlock(user->getParent()); + assert(newVal && "Need a valid value"); + static_cast(useWrapper)->set(newVal); } - /// Get the edge values from the terminator to the destination basic block. -static OperandValueArrayRef getEdgeValuesForTerminator(TermInst *TI, - SILBasicBlock *ToBB) { - if (auto *BrInst = dyn_cast(TI)) { - assert(BrInst->getDestBB() == ToBB && +static OperandValueArrayRef getEdgeValuesForTerminator(TermInst *ti, + SILBasicBlock *toBlock) { + if (auto *br = dyn_cast(ti)) { + assert(br->getDestBB() == toBlock && "Incoming edge block and phi block mismatch"); - return BrInst->getArgs(); + return br->getArgs(); } - if (auto *CondBrInst = dyn_cast(TI)) { - bool IsTrueEdge = CondBrInst->getTrueBB() == ToBB; - assert(((IsTrueEdge && CondBrInst->getTrueBB() == ToBB) || - CondBrInst->getFalseBB() == ToBB) && + if (auto *cbi = dyn_cast(ti)) { + bool isTrueEdge = cbi->getTrueBB() == toBlock; + assert(((isTrueEdge && cbi->getTrueBB() == toBlock) || + cbi->getFalseBB() == toBlock) && "Incoming edge block and phi block mismatch"); - return IsTrueEdge ? CondBrInst->getTrueArgs() : CondBrInst->getFalseArgs(); + return isTrueEdge ? cbi->getTrueArgs() : cbi->getFalseArgs(); } // We need a predecessor who is capable of holding outgoing branch @@ -167,211 +167,219 @@ static OperandValueArrayRef getEdgeValuesForTerminator(TermInst *TI, /// Check that the argument has the same incoming edge values as the value /// map. static bool -isEquivalentPHI(SILPhiArgument *PHI, - llvm::SmallDenseMap &ValueMap) { - SILBasicBlock *PhiBB = PHI->getParent(); - size_t Idx = PHI->getIndex(); - for (auto *PredBB : PhiBB->getPredecessorBlocks()) { - auto DesiredVal = ValueMap[PredBB]; - OperandValueArrayRef EdgeValues = - getEdgeValuesForTerminator(PredBB->getTerminator(), PhiBB); - if (EdgeValues[Idx] != DesiredVal) +isEquivalentPHI(SILPhiArgument *phi, + llvm::SmallDenseMap &valueMap) { + SILBasicBlock *phiBlock = phi->getParent(); + size_t phiArgEdgeIndex = phi->getIndex(); + for (auto *predBlock : phiBlock->getPredecessorBlocks()) { + auto desiredVal = valueMap[predBlock]; + OperandValueArrayRef edgeValues = + getEdgeValuesForTerminator(predBlock->getTerminator(), phiBlock); + if (edgeValues[phiArgEdgeIndex] != desiredVal) return false; } return true; } -SILValue SILSSAUpdater::GetValueInMiddleOfBlock(SILBasicBlock *BB) { +SILValue SILSSAUpdater::getValueInMiddleOfBlock(SILBasicBlock *block) { // If this basic block does not define a value we can just use the value // live at the end of the block. - if (!HasValueForBlock(BB)) - return GetValueAtEndOfBlock(BB); + if (!hasValueForBlock(block)) + return getValueAtEndOfBlock(block); /// Otherwise, we have to build SSA for the value defined in this block and /// this block's predecessors. - SILValue SingularValue; - SmallVector, 4> PredVals; - bool FirstPred = true; + SILValue singularValue; + SmallVector, 4> predVals; + bool firstPred = true; // SSAUpdater can modify TerminatorInst and therefore invalidate the // predecessor iterator. Find all the predecessors before the SSA update. - SmallVector Preds; - for (auto *PredBB : BB->getPredecessorBlocks()) { - Preds.push_back(PredBB); + SmallVector preds; + for (auto *predBlock : block->getPredecessorBlocks()) { + preds.push_back(predBlock); } - for (auto *PredBB : Preds) { - SILValue PredVal = GetValueAtEndOfBlock(PredBB); - PredVals.push_back(std::make_pair(PredBB, PredVal)); - if (FirstPred) { - SingularValue = PredVal; - FirstPred = false; - } else if (SingularValue != PredVal) - SingularValue = SILValue(); + for (auto *predBlock : preds) { + SILValue predVal = getValueAtEndOfBlock(predBlock); + predVals.push_back(std::make_pair(predBlock, predVal)); + if (firstPred) { + singularValue = predVal; + firstPred = false; + } else if (singularValue != predVal) + singularValue = SILValue(); } // Return undef for blocks without predecessor. - if (PredVals.empty()) - return SILUndef::get(ValType, *BB->getParent()); + if (predVals.empty()) + return SILUndef::get(type, *block->getParent()); - if (SingularValue) - return SingularValue; + if (singularValue) + return singularValue; // Check if we already have an equivalent phi. - if (!BB->getArguments().empty()) { - llvm::SmallDenseMap ValueMap(PredVals.begin(), - PredVals.end()); - for (auto *Arg : BB->getSILPhiArguments()) - if (isEquivalentPHI(Arg, ValueMap)) - return Arg; - + if (!block->getArguments().empty()) { + llvm::SmallDenseMap valueMap(predVals.begin(), + predVals.end()); + for (auto *arg : block->getSILPhiArguments()) + if (isEquivalentPHI(arg, valueMap)) + return arg; } // Create a new phi node. - SILPhiArgument *PHI = - BB->createPhiArgument(ValType, ValueOwnershipKind::Owned); - for (auto &EV : PredVals) - addNewEdgeValueToBranch(EV.first->getTerminator(), BB, EV.second); + SILPhiArgument *phiArg = + block->createPhiArgument(type, ValueOwnershipKind::Owned); + for (auto &pair : predVals) + addNewEdgeValueToBranch(pair.first->getTerminator(), block, pair.second); - if (InsertedPHIs) - InsertedPHIs->push_back(PHI); + if (insertedPhis) + insertedPhis->push_back(phiArg); - return PHI; + return phiArg; } -/// SSAUpdaterTraits - Traits for the SSAUpdaterImpl -/// template, specialized for MachineSSAUpdater. namespace llvm { -template<> + +/// Traits for the SSAUpdaterImpl specialized for SIL and the SILSSAUpdater. +template <> class SSAUpdaterTraits { public: - typedef SILBasicBlock BlkT; - typedef SILValue ValT; - typedef SILPhiArgument PhiT; + using BlkT = SILBasicBlock; + using ValT = SILValue; + using PhiT = SILPhiArgument; - typedef SILBasicBlock::succ_iterator BlkSucc_iterator; - static BlkSucc_iterator BlkSucc_begin(BlkT *BB) { return BB->succ_begin(); } - static BlkSucc_iterator BlkSucc_end(BlkT *BB) { return BB->succ_end(); } + using BlkSucc_iterator = SILBasicBlock::succ_iterator; + static BlkSucc_iterator BlkSucc_begin(BlkT *block) { + return block->succ_begin(); + } + static BlkSucc_iterator BlkSucc_end(BlkT *block) { return block->succ_end(); } /// Iterator for PHI operands. class PHI_iterator { private: - SILBasicBlock::pred_iterator PredIt; - SILBasicBlock *BB; - size_t Idx; + SILBasicBlock::pred_iterator predBlockIter; + SILBasicBlock *phiBlock; + size_t phiArgEdgeIndex; public: - explicit PHI_iterator(SILPhiArgument *P) // begin iterator - : PredIt(P->getParent()->pred_begin()), - BB(P->getParent()), - Idx(P->getIndex()) {} - PHI_iterator(SILPhiArgument *P, bool) // end iterator - : PredIt(P->getParent()->pred_end()), - BB(P->getParent()), - Idx(P->getIndex()) {} - - PHI_iterator &operator++() { ++PredIt; return *this; } - bool operator==(const PHI_iterator& x) const { return PredIt == x.PredIt; } + explicit PHI_iterator(SILPhiArgument *phiArg) // begin iterator + : predBlockIter(phiArg->getParent()->pred_begin()), + phiBlock(phiArg->getParent()), phiArgEdgeIndex(phiArg->getIndex()) {} + PHI_iterator(SILPhiArgument *phiArg, bool) // end iterator + : predBlockIter(phiArg->getParent()->pred_end()), + phiBlock(phiArg->getParent()), phiArgEdgeIndex(phiArg->getIndex()) {} + + PHI_iterator &operator++() { + ++predBlockIter; + return *this; + } + + bool operator==(const PHI_iterator &x) const { + return predBlockIter == x.predBlockIter; + } + bool operator!=(const PHI_iterator& x) const { return !operator==(x); } - SILValue getValueForBlock(size_t Idx, SILBasicBlock *BB, TermInst *TI) { - OperandValueArrayRef Args = getEdgeValuesForTerminator(TI, BB); - assert(Idx < Args.size() && "Not enough values on incoming edge"); - return Args[Idx]; + SILValue getValueForBlock(size_t inputArgIndex, SILBasicBlock *block, + TermInst *ti) { + OperandValueArrayRef args = getEdgeValuesForTerminator(ti, block); + assert(inputArgIndex < args.size() && + "Not enough values on incoming edge"); + return args[inputArgIndex]; } SILValue getIncomingValue() { - return getValueForBlock(Idx, BB, (*PredIt)->getTerminator()); + return getValueForBlock(phiArgEdgeIndex, phiBlock, + (*predBlockIter)->getTerminator()); } - SILBasicBlock *getIncomingBlock() { - return *PredIt; - } + SILBasicBlock *getIncomingBlock() { return *predBlockIter; } }; - static inline PHI_iterator PHI_begin(PhiT *PHI) { return PHI_iterator(PHI); } - static inline PHI_iterator PHI_end(PhiT *PHI) { - return PHI_iterator(PHI, true); + static inline PHI_iterator PHI_begin(PhiT *phi) { return PHI_iterator(phi); } + static inline PHI_iterator PHI_end(PhiT *phi) { + return PHI_iterator(phi, true); } /// Put the predecessors of BB into the Preds vector. - static void FindPredecessorBlocks(SILBasicBlock *BB, - SmallVectorImpl *Preds){ - for (SILBasicBlock::pred_iterator PI = BB->pred_begin(), E = BB->pred_end(); - PI != E; ++PI) - Preds->push_back(*PI); + static void + FindPredecessorBlocks(SILBasicBlock *block, + SmallVectorImpl *predBlocks) { + llvm::copy(block->getPredecessorBlocks(), std::back_inserter(*predBlocks)); } - static SILValue GetUndefVal(SILBasicBlock *BB, - SILSSAUpdater *Updater) { - return SILUndef::get(Updater->ValType, *BB->getParent()); + static SILValue GetUndefVal(SILBasicBlock *block, SILSSAUpdater *ssaUpdater) { + return SILUndef::get(ssaUpdater->type, *block->getParent()); } /// Add an Argument to the basic block. - static SILValue CreateEmptyPHI(SILBasicBlock *BB, unsigned NumPreds, - SILSSAUpdater *Updater) { + static SILValue CreateEmptyPHI(SILBasicBlock *block, unsigned numPreds, + SILSSAUpdater *ssaUpdater) { // Add the argument to the block. - SILValue PHI( - BB->createPhiArgument(Updater->ValType, ValueOwnershipKind::Owned)); + SILValue phi( + block->createPhiArgument(ssaUpdater->type, ValueOwnershipKind::Owned)); // Mark all predecessor blocks with the sentinel undef value. - SmallVector Preds(BB->pred_begin(), BB->pred_end()); - for (auto *PredBB: Preds) { - TermInst *TI = PredBB->getTerminator(); - addNewEdgeValueToBranch(TI, BB, Updater->PHISentinel.get()); + SmallVector predBlockList( + block->getPredecessorBlocks()); + + for (auto *predBlock : predBlockList) { + TermInst *ti = predBlock->getTerminator(); + addNewEdgeValueToBranch(ti, block, ssaUpdater->phiSentinel.get()); } - return PHI; + + return phi; } - /// Add the specified value as an operand of the PHI for the specified - /// predecessor block. - static void AddPHIOperand(SILPhiArgument *PHI, SILValue Val, - SILBasicBlock *Pred) { - auto *PHIBB = PHI->getParent(); - size_t PhiIdx = PHI->getIndex(); - auto *TI = Pred->getTerminator(); - changeEdgeValue(TI, PHIBB, PhiIdx, Val); + /// Add \p value as an operand of the phi argument \p phi for the specified + /// predecessor block \p predBlock. + static void AddPHIOperand(SILPhiArgument *phi, SILValue value, + SILBasicBlock *predBlock) { + auto *phiBlock = phi->getParent(); + size_t phiArgIndex = phi->getIndex(); + auto *ti = predBlock->getTerminator(); + changeEdgeValue(ti, phiBlock, phiArgIndex, value); } - /// InstrIsPHI - Check if an instruction is a PHI. - /// - static SILPhiArgument *InstrIsPHI(ValueBase *I) { - auto *Res = dyn_cast(I); - return Res; + /// Check if an instruction is a PHI. + static SILPhiArgument *InstrIsPHI(ValueBase *valueBase) { + return dyn_cast(valueBase); } - /// ValueIsPHI - Check if the instruction that defines the specified register - /// is a PHI instruction. - static SILPhiArgument *ValueIsPHI(SILValue V, SILSSAUpdater *Updater) { - return InstrIsPHI(V); + /// Check if the instruction that defines the specified SILValue is a PHI + /// instruction. + static SILPhiArgument *ValueIsPHI(SILValue value, SILSSAUpdater *) { + return InstrIsPHI(value); } /// Like ValueIsPHI but also check if the PHI has no source /// operands, i.e., it was just added. - static SILPhiArgument *ValueIsNewPHI(SILValue Val, SILSSAUpdater *Updater) { - SILPhiArgument *PHI = ValueIsPHI(Val, Updater); - if (PHI) { - auto *PhiBB = PHI->getParent(); - size_t PhiIdx = PHI->getIndex(); - - // If all predecessor edges are 'not set' this is a new phi. - for (auto *PredBB : PhiBB->getPredecessorBlocks()) { - OperandValueArrayRef Edges = - getEdgeValuesForTerminator(PredBB->getTerminator(), PhiBB); - - assert(PhiIdx < Edges.size() && "Not enough edges!"); - - SILValue V = Edges[PhiIdx]; - // Check for the 'not set' sentinel. - if (V != Updater->PHISentinel.get()) - return nullptr; - } - return PHI; + static SILPhiArgument *ValueIsNewPHI(SILValue value, + SILSSAUpdater *ssaUpdater) { + SILPhiArgument *phiArg = ValueIsPHI(value, ssaUpdater); + if (!phiArg) { + return nullptr; } - return nullptr; + + auto *phiBlock = phiArg->getParent(); + size_t phiArgEdgeIndex = phiArg->getIndex(); + + // If all predecessor edges are 'not set' this is a new phi. + for (auto *predBlock : phiBlock->getPredecessorBlocks()) { + OperandValueArrayRef edgeValues = + getEdgeValuesForTerminator(predBlock->getTerminator(), phiBlock); + + assert(phiArgEdgeIndex < edgeValues.size() && "Not enough edges!"); + + SILValue edgeValue = edgeValues[phiArgEdgeIndex]; + // Check for the 'not set' sentinel. + if (edgeValue != ssaUpdater->phiSentinel.get()) + return nullptr; + } + return phiArg; } - static SILValue GetPHIValue(SILPhiArgument *PHI) { return PHI; } + static SILValue GetPHIValue(SILPhiArgument *phi) { return phi; } }; } // namespace llvm @@ -379,14 +387,15 @@ class SSAUpdaterTraits { /// Check to see if AvailableVals has an entry for the specified BB and if so, /// return it. If not, construct SSA form by first calculating the required /// placement of PHIs and then inserting new PHIs where needed. -SILValue SILSSAUpdater::GetValueAtEndOfBlockInternal(SILBasicBlock *BB){ - AvailableValsTy &AvailableVals = *AV; - auto AI = AvailableVals.find(BB); - if (AI != AvailableVals.end()) - return AI->second; - - llvm::SSAUpdaterImpl Impl(this, &AvailableVals, InsertedPHIs); - return Impl.GetValue(BB); +SILValue SILSSAUpdater::getValueAtEndOfBlockInternal(SILBasicBlock *block) { + AvailableValsTy &availableValues = *blockToAvailableValueMap; + auto iter = availableValues.find(block); + if (iter != availableValues.end()) + return iter->second; + + llvm::SSAUpdaterImpl impl(this, &availableValues, + insertedPhis); + return impl.GetValue(block); } /// Construct a use wrapper. For branches we store information so that we @@ -395,67 +404,70 @@ SILValue SILSSAUpdater::GetValueAtEndOfBlockInternal(SILBasicBlock *BB){ /// When a branch is modified existing pointers to the operand /// (ValueUseIterator) become invalid as they point to freed operands. Instead /// we store the branch's parent and the idx so that we can reconstruct the use. -UseWrapper::UseWrapper(Operand *Use) { - U = nullptr; - Type = kRegularUse; +UseWrapper::UseWrapper(Operand *inputUse) { + wrappedUse = nullptr; + type = kRegularUse; - SILInstruction *User = Use->getUser(); + SILInstruction *user = inputUse->getUser(); // Direct branch user. - if (auto *Br = dyn_cast(User)) { - auto Opds = User->getAllOperands(); - for (unsigned i = 0, e = Opds.size(); i != e; ++i) { - if (Use == &Opds[i]) { - Idx = i; - Type = kBranchUse; - Parent = Br->getParent(); + if (auto *br = dyn_cast(user)) { + for (auto pair : llvm::enumerate(user->getAllOperands())) { + if (inputUse == &pair.value()) { + index = pair.index(); + type = kBranchUse; + parent = br->getParent(); return; } } } // Conditional branch user. - if (auto *Br = dyn_cast(User)) { - auto Opds = User->getAllOperands(); - auto NumTrueArgs = Br->getTrueArgs().size(); - for (unsigned i = 0, e = Opds.size(); i != e; ++i) { - if (Use == &Opds[i]) { + if (auto *cbi = dyn_cast(user)) { + auto operands = user->getAllOperands(); + auto numTrueArgs = cbi->getTrueArgs().size(); + for (auto pair : llvm::enumerate(operands)) { + if (inputUse == &pair.value()) { + unsigned i = pair.index(); // We treat the condition as part of the true args. - if (i < NumTrueArgs + 1) { - Idx = i; - Type = kCondBranchUseTrue; + if (i < numTrueArgs + 1) { + index = i; + type = kCondBranchUseTrue; } else { - Idx = i - NumTrueArgs - 1; - Type = kCondBranchUseFalse; + index = i - numTrueArgs - 1; + type = kCondBranchUseFalse; } - Parent = Br->getParent(); + parent = cbi->getParent(); return; } } } - U = Use; + wrappedUse = inputUse; } /// Return the operand we wrap. Reconstructing branch operands. Operand *UseWrapper::getOperand() { - switch (Type) { + switch (type) { case kRegularUse: - return U; + return wrappedUse; case kBranchUse: { - auto *Br = cast(Parent->getTerminator()); - assert(Idx < Br->getNumArgs()); - return &Br->getAllOperands()[Idx]; + auto *br = cast(parent->getTerminator()); + assert(index < br->getNumArgs()); + return &br->getAllOperands()[index]; } case kCondBranchUseTrue: case kCondBranchUseFalse: { - auto *Br = cast(Parent->getTerminator()); - unsigned IdxToUse = - Type == kCondBranchUseTrue ? Idx : Br->getTrueArgs().size() + 1 + Idx; - assert(IdxToUse < Br->getAllOperands().size()); - return &Br->getAllOperands()[IdxToUse]; + auto *cbi = cast(parent->getTerminator()); + auto indexToUse = [&]() -> unsigned { + if (type == kCondBranchUseTrue) + return index; + return cbi->getTrueArgs().size() + 1 + index; + }(); + assert(indexToUse < cbi->getAllOperands().size()); + return &cbi->getAllOperands()[indexToUse]; } } @@ -470,12 +482,12 @@ Operand *UseWrapper::getOperand() { /// ArgValues are the values feeding the specified Argument from each /// predecessor. They must be listed in order of Arg->getParent()->getPreds(). static StructInst * -replaceBBArgWithStruct(SILPhiArgument *Arg, - SmallVectorImpl &ArgValues) { +replaceBBArgWithStruct(SILPhiArgument *phiArg, + SmallVectorImpl &argValues) { - SILBasicBlock *PhiBB = Arg->getParent(); - auto *FirstSI = dyn_cast(ArgValues[0]); - if (!FirstSI) + SILBasicBlock *phiBlock = phiArg->getParent(); + auto *firstSI = dyn_cast(argValues[0]); + if (!firstSI) return nullptr; // Collect the BBArg index of each struct oper. @@ -483,42 +495,45 @@ replaceBBArgWithStruct(SILPhiArgument *Arg, // struct(A, B) // br (B, A) // : ArgIdxForOper => {1, 0} - SmallVector ArgIdxForOper; - for (unsigned OperIdx : indices(FirstSI->getElements())) { - bool FoundMatchingArgIdx = false; - for (unsigned ArgIdx : indices(PhiBB->getArguments())) { - SmallVectorImpl::const_iterator AVIter = ArgValues.begin(); - bool TryNextArgIdx = false; - for (SILBasicBlock *PredBB : PhiBB->getPredecessorBlocks()) { + SmallVector argIdxForOper; + for (unsigned operIdx : indices(firstSI->getElements())) { + bool foundMatchingArgIdx = false; + for (unsigned argIdx : indices(phiBlock->getArguments())) { + auto avIter = argValues.begin(); + bool tryNextArgIdx = false; + for (SILBasicBlock *predBlock : phiBlock->getPredecessorBlocks()) { // All argument values must be StructInst. - auto *PredSI = dyn_cast(*AVIter++); - if (!PredSI) + auto *predSI = dyn_cast(*avIter++); + if (!predSI) return nullptr; - OperandValueArrayRef EdgeValues = - getEdgeValuesForTerminator(PredBB->getTerminator(), PhiBB); - if (EdgeValues[ArgIdx] != PredSI->getElements()[OperIdx]) { - TryNextArgIdx = true; + OperandValueArrayRef edgeValues = + getEdgeValuesForTerminator(predBlock->getTerminator(), phiBlock); + if (edgeValues[argIdx] != predSI->getElements()[operIdx]) { + tryNextArgIdx = true; break; } } - if (!TryNextArgIdx) { - assert(AVIter == ArgValues.end() && "# ArgValues does not match # BB preds"); - FoundMatchingArgIdx = true; - ArgIdxForOper.push_back(ArgIdx); + if (!tryNextArgIdx) { + assert(avIter == argValues.end() && + "# ArgValues does not match # BB preds"); + foundMatchingArgIdx = true; + argIdxForOper.push_back(argIdx); break; } } - if (!FoundMatchingArgIdx) + if (!foundMatchingArgIdx) return nullptr; } - SmallVector StructArgs; - for (auto ArgIdx : ArgIdxForOper) - StructArgs.push_back(PhiBB->getArgument(ArgIdx)); + SmallVector structArgs; + for (auto argIdx : argIdxForOper) + structArgs.push_back(phiBlock->getArgument(argIdx)); - SILBuilder Builder(PhiBB, PhiBB->begin()); - return Builder.createStruct(cast(ArgValues[0])->getLoc(), - Arg->getType(), StructArgs); + // TODO: We probably want to use a SILBuilderWithScope here. What should we + // use? + SILBuilder builder(phiBlock, phiBlock->begin()); + return builder.createStruct(cast(argValues[0])->getLoc(), + phiArg->getType(), structArgs); } /// Canonicalize BB arguments, replacing argument-of-casts with @@ -527,10 +542,10 @@ replaceBBArgWithStruct(SILPhiArgument *Arg, /// detection like induction variable analysis to succeed. /// /// If Arg is replaced, return the cast instruction. Otherwise return nullptr. -SILValue swift::replaceBBArgWithCast(SILPhiArgument *Arg) { - SmallVector ArgValues; - Arg->getIncomingPhiValues(ArgValues); - if (isa(ArgValues[0])) - return replaceBBArgWithStruct(Arg, ArgValues); +SILValue swift::replaceBBArgWithCast(SILPhiArgument *arg) { + SmallVector argValues; + arg->getIncomingPhiValues(argValues); + if (isa(argValues[0])) + return replaceBBArgWithStruct(arg, argValues); return nullptr; }