本文整理汇总了C++中SILBasicBlock类的典型用法代码示例。如果您正苦于以下问题:C++ SILBasicBlock类的具体用法?C++ SILBasicBlock怎么用?C++ SILBasicBlock使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SILBasicBlock类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: getParent
bool SILArgument::getIncomingValues(llvm::SmallVectorImpl<SILValue> &OutArray) {
SILBasicBlock *Parent = getParent();
if (Parent->pred_empty())
return false;
unsigned Index = getIndex();
for (SILBasicBlock *Pred : getParent()->getPreds()) {
TermInst *TI = Pred->getTerminator();
if (auto *BI = dyn_cast<BranchInst>(TI)) {
OutArray.push_back(BI->getArg(Index));
continue;
}
if (auto *CBI = dyn_cast<CondBranchInst>(TI)) {
OutArray.push_back(CBI->getArgForDestBB(getParent(), this));
continue;
}
if (auto *CCBI = dyn_cast<CheckedCastBranchInst>(TI)) {
OutArray.push_back(CCBI->getOperand());
continue;
}
if (auto *SWEI = dyn_cast<SwitchEnumInst>(TI)) {
OutArray.push_back(SWEI->getOperand());
continue;
}
return false;
}
return true;
}
开发者ID:asdfeng,项目名称:swift,代码行数:35,代码来源:SILArgument.cpp
示例2: while
void ReleaseCodeMotionContext::convergeCodeMotionDataFlow() {
// Process each basic block with the gen and kill set. Every time the
// BBSetIn of a basic block changes, the optimization is rerun on its
// predecessors.
llvm::SmallVector<SILBasicBlock *, 16> WorkList;
llvm::SmallPtrSet<SILBasicBlock *, 8> HandledBBs;
// Push into reverse post order so that we can pop from the back and get
// post order.
for (SILBasicBlock *B : PO->getPostOrder()) {
WorkList.push_back(B);
HandledBBs.insert(B);
}
while (!WorkList.empty()) {
SILBasicBlock *BB = WorkList.pop_back_val();
HandledBBs.erase(BB);
if (processBBWithGenKillSet(BB)) {
for (auto X : BB->getPredecessorBlocks()) {
// We do not push basic block into the worklist if its already
// in the worklist.
if (HandledBBs.count(X))
continue;
WorkList.push_back(X);
}
}
}
}
开发者ID:yjmeng,项目名称:swift,代码行数:26,代码来源:ARCCodeMotion.cpp
示例3: assert
Condition SILGenFunction::emitCondition(SILValue V, SILLocation Loc,
bool hasFalseCode, bool invertValue,
ArrayRef<SILType> contArgs) {
assert(B.hasValidInsertionPoint() &&
"emitting condition at unreachable point");
SILBasicBlock *ContBB = createBasicBlock();
for (SILType argTy : contArgs) {
ContBB->createPHIArgument(argTy, ValueOwnershipKind::Owned);
}
SILBasicBlock *FalseBB, *FalseDestBB;
if (hasFalseCode) {
FalseBB = FalseDestBB = createBasicBlock();
} else {
FalseBB = nullptr;
FalseDestBB = ContBB;
}
SILBasicBlock *TrueBB = createBasicBlock();
if (invertValue)
B.createCondBranch(Loc, V, FalseDestBB, TrueBB);
else
B.createCondBranch(Loc, V, TrueBB, FalseDestBB);
return Condition(TrueBB, FalseBB, ContBB, Loc);
}
开发者ID:Daford,项目名称:swift,代码行数:29,代码来源:SILGenStmt.cpp
示例4: canNRVO
/// Return true if this copy can be eliminated through Named Return Value
/// Optimization (NRVO).
///
/// Simple NRVO cases are handled naturally via backwardPropagateCopy. However,
/// general NRVO is not handled via local propagation without global data
/// flow. Nonetheless, NRVO is a simple pattern that can be detected using a
/// different technique from propagation.
///
/// Example:
/// func nrvo<T : P>(z : Bool) -> T {
/// var rvo : T
/// if (z) {
/// rvo = T(10)
/// }
/// else {
/// rvo = T(1)
/// }
/// return rvo
/// }
///
/// Because of the control flow, backward propagation with a block will fail to
/// find the initializer for the copy at "return rvo". Instead, we directly
/// check for an NRVO pattern by observing a copy in a return block that is the
/// only use of the copy's dest, which must be an @out arg. If there are no
/// instructions between the copy and the return that may write to the copy's
/// source, we simply replace the source's local stack address with the @out
/// address.
///
/// The following SIL pattern will be detected:
///
/// sil @foo : [email protected](thin) <T> (@out T) -> () {
/// bb0(%0 : $*T):
/// %2 = alloc_stack $T
/// ... // arbitrary control flow, but no other uses of %0
/// bbN:
/// copy_addr [take] %2 to [initialization] %0 : $*T
/// ... // no writes
/// return
static bool canNRVO(CopyAddrInst *CopyInst) {
if (!isa<AllocStackInst>(CopyInst->getSrc()))
return false;
// The copy's dest must be an indirect SIL argument. Otherwise, it may not
// dominate all uses of the source. Worse, it may be aliased. This
// optimization will early-initialize the copy dest, so we can't allow aliases
// to be accessed between the initialization and the return.
auto OutArg = dyn_cast<SILArgument>(CopyInst->getDest());
if (!OutArg)
return false;
auto ArgConv = OutArg->getParameterInfo().getConvention();
if (ArgConv != ParameterConvention::Indirect_Out)
return false;
SILBasicBlock *BB = CopyInst->getParent();
if (!isa<ReturnInst>(BB->getTerminator()))
return false;
SILValue CopyDest = CopyInst->getDest();
if (!hasOneNonDebugUse(CopyDest))
return false;
auto SI = CopyInst->getIterator(), SE = BB->end();
for (++SI; SI != SE; ++SI) {
if (SI->mayWriteToMemory() && !isa<DeallocationInst>(SI))
return false;
}
return true;
}
开发者ID:adrfer,项目名称:swift,代码行数:69,代码来源:CopyForwarding.cpp
示例5: LLVM_DEBUG
SILValue
StackAllocationPromoter::getLiveOutValue(BlockSet &PhiBlocks,
SILBasicBlock *StartBB) {
LLVM_DEBUG(llvm::dbgs() << "*** Searching for a value definition.\n");
// Walk the Dom tree in search of a defining value:
for (DomTreeNode *Node = DT->getNode(StartBB); Node; Node = Node->getIDom()) {
SILBasicBlock *BB = Node->getBlock();
// If there is a store (that must come after the phi), use its value.
BlockToInstMap::iterator it = LastStoreInBlock.find(BB);
if (it != LastStoreInBlock.end())
if (auto *St = dyn_cast_or_null<StoreInst>(it->second)) {
LLVM_DEBUG(llvm::dbgs() << "*** Found Store def " << *St->getSrc());
return St->getSrc();
}
// If there is a Phi definition in this block:
if (PhiBlocks.count(BB)) {
// Return the dummy instruction that represents the new value that we will
// add to the basic block.
SILValue Phi = BB->getArgument(BB->getNumArguments() - 1);
LLVM_DEBUG(llvm::dbgs() << "*** Found a dummy Phi def " << *Phi);
return Phi;
}
// Move to the next dominating block.
LLVM_DEBUG(llvm::dbgs() << "*** Walking up the iDOM.\n");
}
LLVM_DEBUG(llvm::dbgs() << "*** Could not find a Def. Using Undef.\n");
return SILUndef::get(ASI->getElementType(), ASI->getModule());
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:31,代码来源:SILMem2Reg.cpp
示例6: OwnedToGuaranteedAddArgumentRelease
/// Set up epilogue work for the thunk arguments based in the given argument.
/// Default implementation simply passes it through.
void
FunctionSignatureTransform::
OwnedToGuaranteedAddArgumentRelease(ArgumentDescriptor &AD, SILBuilder &Builder,
SILFunction *F) {
// If we have any arguments that were consumed but are now guaranteed,
// insert a release_value.
if (!AD.OwnedToGuaranteed) {
return;
}
SILInstruction *Call = findOnlyApply(F);
if (isa<ApplyInst>(Call)) {
Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call)));
Builder.createReleaseValue(RegularLocation(SourceLoc()),
F->getArguments()[AD.Index],
Builder.getDefaultAtomicity());
} else {
SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB();
Builder.setInsertionPoint(&*NormalBB->begin());
Builder.createReleaseValue(RegularLocation(SourceLoc()),
F->getArguments()[AD.Index],
Builder.getDefaultAtomicity());
SILBasicBlock *ErrorBB = dyn_cast<TryApplyInst>(Call)->getErrorBB();
Builder.setInsertionPoint(&*ErrorBB->begin());
Builder.createReleaseValue(RegularLocation(SourceLoc()),
F->getArguments()[AD.Index],
Builder.getDefaultAtomicity());
}
}
开发者ID:herculesjr,项目名称:swift,代码行数:32,代码来源:FunctionSignatureOpts.cpp
示例7: computeForwardingValues
SILValue BBState::computeForwardingValues(RLEContext &Ctx, MemLocation &L,
SILInstruction *InsertPt,
bool UseForwardValOut) {
SILBasicBlock *ParentBB = InsertPt->getParent();
bool IsTerminator = (InsertPt == ParentBB->getTerminator());
// We do not have a SILValue for the current MemLocation, try to construct
// one.
//
// Collect the locations and their corresponding values into a map.
// First, collect current available locations and their corresponding values
// into a map.
MemLocationValueMap Values;
if (!Ctx.gatherValues(ParentBB, L, Values, UseForwardValOut))
return SILValue();
// If the InsertPt is the terminator instruction of the basic block, we
// *refresh* it as terminator instruction could be deleted as a result
// of adding new edge values to the terminator instruction.
if (IsTerminator)
InsertPt = ParentBB->getTerminator();
// Second, reduce the available values into a single SILValue we can use to
// forward.
SILValue TheForwardingValue;
TheForwardingValue = MemLocation::reduceWithValues(L, &ParentBB->getModule(),
Values, InsertPt);
/// Return the forwarding value.
return TheForwardingValue;
}
开发者ID:dshah22,项目名称:swift,代码行数:29,代码来源:RedundantLoadElimination.cpp
示例8: initializeAllConsumingUses
void State::initializeAllConsumingUses(
ArrayRef<BranchPropagatedUser> consumingUses,
SmallVectorImpl<BrPropUserAndBlockPair> &predsToAddToWorklist) {
for (BranchPropagatedUser user : consumingUses) {
SILBasicBlock *userBlock = user.getParent();
// First initialize our state for the consuming user.
//
// If we find another consuming instruction associated with userBlock this
// will emit a checker error.
initializeConsumingUse(user, userBlock);
// Then check if the given block has a use after free and emit an error if
// we find one.
checkForSameBlockUseAfterFree(user, userBlock);
// If this user is in the same block as the value, do not visit
// predecessors. We must be extra tolerant here since we allow for
// unreachable code.
if (userBlock == value->getParentBlock())
continue;
// Then for each predecessor of this block...
for (auto *pred : userBlock->getPredecessorBlocks()) {
// If this block is not a block that we have already put on the list, add
// it to the worklist.
predsToAddToWorklist.push_back({user, pred});
}
}
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:30,代码来源:LinearLifetimeChecker.cpp
示例9: while
void RLEContext::processBasicBlocksWithGenKillSet() {
// Process each basic block with the gen and kill set. Every time the
// ForwardSetOut of a basic block changes, the optimization is rerun on its
// successors.
llvm::SmallVector<SILBasicBlock *, 16> WorkList;
llvm::DenseSet<SILBasicBlock *> HandledBBs;
// Push into the worklist in post order so that we can pop from the back and
// get reverse post order.
for (SILBasicBlock *BB : PO->getPostOrder()) {
WorkList.push_back(BB);
HandledBBs.insert(BB);
}
while (!WorkList.empty()) {
SILBasicBlock *BB = WorkList.pop_back_val();
HandledBBs.erase(BB);
// Intersection.
BlockState &Forwarder = getBlockState(BB);
// Compute the ForwardSetIn at the beginning of the basic block.
Forwarder.mergePredecessorAvailSet(*this);
if (Forwarder.processBasicBlockWithGenKillSet()) {
for (auto &X : BB->getSuccessors()) {
// We do not push basic block into the worklist if its already
// in the worklist.
if (HandledBBs.find(X) != HandledBBs.end())
continue;
WorkList.push_back(X);
}
}
}
}
开发者ID:richlira,项目名称:swift,代码行数:33,代码来源:RedundantLoadElimination.cpp
示例10: emitErrorIsNonNilErrorCheck
/// Perform a foreign error check by testing whether the error was nil.
static void
emitErrorIsNonNilErrorCheck(SILGenFunction &gen, SILLocation loc,
ManagedValue errorSlot, bool suppressErrorCheck) {
// If we're suppressing the check, just don't check.
if (suppressErrorCheck) return;
SILValue optionalError = gen.B.emitLoadValueOperation(
loc, errorSlot.forward(gen), LoadOwnershipQualifier::Take);
ASTContext &ctx = gen.getASTContext();
// Switch on the optional error.
SILBasicBlock *errorBB = gen.createBasicBlock(FunctionSection::Postmatter);
errorBB->createArgument(optionalError->getType().unwrapAnyOptionalType());
SILBasicBlock *contBB = gen.createBasicBlock();
gen.B.createSwitchEnum(loc, optionalError, /*default*/ nullptr,
{ { ctx.getOptionalSomeDecl(), errorBB },
{ ctx.getOptionalNoneDecl(), contBB } });
// Emit the error block. Pass in none for the errorSlot since we have passed
// in the errorSlot as our BB argument so we can pass ownership correctly. In
// emitForeignErrorBlock, we will create the appropriate cleanup for the
// argument.
gen.emitForeignErrorBlock(loc, errorBB, None);
// Return the result.
gen.B.emitBlock(contBB);
return;
}
开发者ID:yasirmcs,项目名称:swift,代码行数:30,代码来源:SILGenForeignError.cpp
示例11: getParent
SILValue SILArgument::getIncomingValue(unsigned BBIndex) {
SILBasicBlock *Parent = getParent();
if (Parent->pred_empty())
return SILValue();
unsigned Index = getIndex();
// We could do an early check if the size of the pred list is <= BBIndex, but
// that would involve walking the linked list anyways, so we just iterate once
// over the loop.
// We use this funky loop since predecessors are stored in a linked list but
// we want array like semantics.
unsigned BBCount = 0;
for (SILBasicBlock *Pred : Parent->getPreds()) {
// If BBCount is not BBIndex, continue.
if (BBCount < BBIndex) {
BBCount++;
continue;
}
// This will return an empty SILValue if we found something we do not
// understand.
return getIncomingValueForPred(Parent, Pred, Index);
}
return SILValue();
}
开发者ID:ghostbar,项目名称:swift-lang.deb,代码行数:29,代码来源:SILArgument.cpp
示例12: checkSwitchEnumBlockArg
// Given a block argument address base, check if it is actually a box projected
// from a switch_enum. This is a valid pattern at any SIL stage resulting in a
// block-type phi. In later SIL stages, the optimizer may form address-type
// phis, causing this assert if called on those cases.
static void checkSwitchEnumBlockArg(SILPhiArgument *arg) {
assert(!arg->getType().isAddress());
SILBasicBlock *Pred = arg->getParent()->getSinglePredecessorBlock();
if (!Pred || !isa<SwitchEnumInst>(Pred->getTerminator())) {
arg->dump();
llvm_unreachable("unexpected box source.");
}
}
开发者ID:adamnemecek,项目名称:swift,代码行数:12,代码来源:MemAccessUtils.cpp
示例13: new
/// \brief Splits a basic block into two at the specified instruction.
///
/// Note that all the instructions BEFORE the specified iterator
/// stay as part of the original basic block. The old basic block is left
/// without a terminator.
SILBasicBlock *SILBasicBlock::split(iterator I) {
SILBasicBlock *New =
new (Parent->getModule()) SILBasicBlock(Parent, this, /*after*/true);
// Move all of the specified instructions from the original basic block into
// the new basic block.
New->InstList.splice(New->end(), InstList, I, end());
return New;
}
开发者ID:frsoares,项目名称:swift,代码行数:13,代码来源:SILBasicBlock.cpp
示例14: DeadArgumentTransformFunction
void FunctionSignatureTransform::DeadArgumentTransformFunction() {
SILBasicBlock *BB = &*F->begin();
for (const ArgumentDescriptor &AD : ArgumentDescList) {
if (!AD.IsEntirelyDead)
continue;
eraseUsesOfValue(BB->getArgument(AD.Index));
}
}
开发者ID:herculesjr,项目名称:swift,代码行数:8,代码来源:FunctionSignatureOpts.cpp
示例15:
/// getOrEraseBlock - If there are branches to the specified JumpDest,
/// return the block, otherwise return NULL. The JumpDest must be valid.
static SILBasicBlock *getOrEraseBlock(SILGenFunction &SGF, JumpDest &dest) {
SILBasicBlock *BB = dest.takeBlock();
if (BB->pred_empty()) {
// If the block is unused, we don't need it; just delete it.
SGF.eraseBasicBlock(BB);
return nullptr;
}
return BB;
}
开发者ID:vineetchoudhary,项目名称:swiftforwindows,代码行数:11,代码来源:SILGenStmt.cpp
示例16: DEBUG
bool ARCRegionState::processBlockBottomUp(
SILBasicBlock &BB, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
bool FreezeOwnedArgEpilogueReleases,
ConsumedArgToEpilogueReleaseMatcher &ConsumedArgToReleaseMap,
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap) {
DEBUG(llvm::dbgs() << ">>>> Bottom Up!\n");
bool NestingDetected = false;
BottomUpDataflowRCStateVisitor<ARCRegionState> DataflowVisitor(
RCIA, *this, FreezeOwnedArgEpilogueReleases, ConsumedArgToReleaseMap,
IncToDecStateMap);
// For each non-terminator instruction I in BB visited in reverse...
for (auto II = std::next(BB.rbegin()), IE = BB.rend(); II != IE;) {
SILInstruction &I = *II;
++II;
DEBUG(llvm::dbgs() << "VISITING:\n " << I);
auto Result = DataflowVisitor.visit(&I);
// If this instruction can have no further effects on another instructions,
// continue. This happens for instance if we have cleared all of the state
// we are tracking.
if (Result.Kind == RCStateTransitionDataflowResultKind::NoEffects)
continue;
// Make sure that we propagate out whether or not nesting was detected.
NestingDetected |= Result.NestingDetected;
// This SILValue may be null if we were unable to find a specific RCIdentity
// that the instruction "visits".
SILValue Op = Result.RCIdentity;
auto *InsertPt = &*std::next(SILBasicBlock::iterator(&I));
// For all other (reference counted value, ref count state) we are
// tracking...
for (auto &OtherState : getBottomupStates()) {
// If the other state's value is blotted, skip it.
if (!OtherState.hasValue())
continue;
// If this is the state associated with the instruction that we are
// currently visiting, bail.
if (Op && OtherState->first == Op)
continue;
OtherState->second.updateForSameLoopInst(&I, InsertPt, AA);
}
}
return NestingDetected;
}
开发者ID:carriercomm,项目名称:swift,代码行数:55,代码来源:ARCRegionState.cpp
示例17: new
/// \brief Splits a basic block into two at the specified instruction.
///
/// Note that all the instructions BEFORE the specified iterator
/// stay as part of the original basic block. The old basic block is left
/// without a terminator.
SILBasicBlock *SILBasicBlock::splitBasicBlock(iterator I) {
SILBasicBlock *New = new (Parent->getModule()) SILBasicBlock(Parent);
SILFunction::iterator Where = std::next(SILFunction::iterator(this));
SILFunction::iterator First = SILFunction::iterator(New);
if (Where != First)
Parent->getBlocks().splice(Where, Parent->getBlocks(), First);
// Move all of the specified instructions from the original basic block into
// the new basic block.
New->InstList.splice(New->end(), InstList, I, end());
return New;
}
开发者ID:dshah22,项目名称:swift,代码行数:16,代码来源:SILBasicBlock.cpp
示例18: LLVM_DEBUG
/// Optimize placement of initializer calls given a list of calls to the
/// same initializer. All original initialization points must be dominated by
/// the final initialization calls.
///
/// The current heuristic hoists all initialization points within a function to
/// a single dominating call in the outer loop preheader.
void SILGlobalOpt::placeInitializers(SILFunction *InitF,
ArrayRef<ApplyInst *> Calls) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: calls to "
<< Demangle::demangleSymbolAsString(InitF->getName())
<< " : " << Calls.size() << "\n");
// Map each initializer-containing function to its final initializer call.
llvm::DenseMap<SILFunction *, ApplyInst *> ParentFuncs;
for (auto *AI : Calls) {
assert(AI->getNumArguments() == 0 && "ill-formed global init call");
assert(cast<FunctionRefInst>(AI->getCallee())->getReferencedFunction()
== InitF && "wrong init call");
SILFunction *ParentF = AI->getFunction();
DominanceInfo *DT = DA->get(ParentF);
ApplyInst *HoistAI =
getHoistedApplyForInitializer(AI, DT, InitF, ParentF, ParentFuncs);
// If we were unable to find anything, just go onto the next apply.
if (!HoistAI) {
continue;
}
// Otherwise, move this call to the outermost loop preheader.
SILBasicBlock *BB = HoistAI->getParent();
typedef llvm::DomTreeNodeBase<SILBasicBlock> DomTreeNode;
DomTreeNode *Node = DT->getNode(BB);
while (Node) {
SILBasicBlock *DomParentBB = Node->getBlock();
if (isAvailabilityCheck(DomParentBB)) {
LLVM_DEBUG(llvm::dbgs() << " don't hoist above availability check "
"at bb"
<< DomParentBB->getDebugID() << "\n");
break;
}
BB = DomParentBB;
if (!isInLoop(BB))
break;
Node = Node->getIDom();
}
if (BB == HoistAI->getParent()) {
// BB is either unreachable or not in a loop.
LLVM_DEBUG(llvm::dbgs() << " skipping (not in a loop): " << *HoistAI
<< " in " << HoistAI->getFunction()->getName()
<< "\n");
continue;
}
LLVM_DEBUG(llvm::dbgs() << " hoisting: " << *HoistAI << " in "
<< HoistAI->getFunction()->getName() << "\n");
HoistAI->moveBefore(&*BB->begin());
placeFuncRef(HoistAI, DT);
HasChanged = true;
}
}
开发者ID:phausler,项目名称:swift,代码行数:60,代码来源:GlobalOpt.cpp
示例19: prepareExtraEpilog
static bool prepareExtraEpilog(SILGenFunction &SGF, JumpDest &dest,
SILLocation &loc, SILValue *arg) {
assert(!SGF.B.hasValidInsertionPoint());
// If we don't have a destination, we don't need to emit the epilog.
if (!dest.isValid())
return false;
// If the destination isn't used, we don't need to emit the epilog.
SILBasicBlock *epilogBB = dest.getBlock();
auto pi = epilogBB->pred_begin(), pe = epilogBB->pred_end();
if (pi == pe) {
dest = JumpDest::invalid();
SGF.eraseBasicBlock(epilogBB);
return false;
}
assert(epilogBB->getNumArguments() <= 1);
assert((epilogBB->getNumArguments() == 1) == (arg != nullptr));
if (arg) *arg = epilogBB->args_begin()[0];
bool reposition = true;
// If the destination has a single branch predecessor,
// consider emitting the epilog into it.
SILBasicBlock *predBB = *pi;
if (++pi == pe) {
if (auto branch = dyn_cast<BranchInst>(predBB->getTerminator())) {
assert(branch->getArgs().size() == epilogBB->getNumArguments());
// Save the location and operand information from the branch,
// then destroy it.
loc = branch->getLoc();
if (arg) *arg = branch->getArgs()[0];
predBB->erase(branch);
// Erase the rethrow block.
SGF.eraseBasicBlock(epilogBB);
epilogBB = predBB;
reposition = false;
}
}
// Reposition the block to the end of the postmatter section
// unless we're emitting into a single predecessor.
if (reposition) {
SGF.B.moveBlockTo(epilogBB, SGF.F.end());
}
SGF.B.setInsertionPoint(epilogBB);
return true;
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:53,代码来源:SILGenEpilog.cpp
示例20: replaceBBArgWithStruct
/// At least one value feeding the specified SILArgument is a Struct. Attempt to
/// replace the Argument with a new Struct in the same block.
///
/// When we handle more types of casts, this can become a template.
///
/// 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<SILValue> &ArgValues) {
SILBasicBlock *PhiBB = Arg->getParent();
auto *FirstSI = dyn_cast<StructInst>(ArgValues[0]);
if (!FirstSI)
return nullptr;
// Collect the BBArg index of each struct oper.
// e.g.
// struct(A, B)
// br (B, A)
// : ArgIdxForOper => {1, 0}
SmallVector<unsigned, 4> ArgIdxForOper;
for (unsigned OperIdx : indices(FirstSI->getElements())) {
bool FoundMatchingArgIdx = false;
for (unsigned ArgIdx : indices(PhiBB->getArguments())) {
SmallVectorImpl<SILValue>::const_iterator AVIter = ArgValues.begin();
bool TryNextArgIdx = false;
for (SILBasicBlock *PredBB : PhiBB->getPredecessorBlocks()) {
// All argument values must be StructInst.
auto *PredSI = dyn_cast<StructInst>(*AVIter++);
if (!PredSI)
return nullptr;
OperandValueArrayRef EdgeValues =
getEdgeValuesForTerminator(PredBB->getTerminator(), PhiBB);
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);
break;
}
}
if (!FoundMatchingArgIdx)
return nullptr;
}
SmallVector<SILValue, 4> StructArgs;
for (auto ArgIdx : ArgIdxForOper)
StructArgs.push_back(PhiBB->getArgument(ArgIdx));
SILBuilder Builder(PhiBB, PhiBB->begin());
return Builder.createStruct(cast<StructInst>(ArgValues[0])->getLoc(),
Arg->getType(), StructArgs);
}
开发者ID:uygar,项目名称:swift,代码行数:58,代码来源:SILSSAUpdater.cpp
注:本文中的SILBasicBlock类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论