本文整理汇总了C++中SILBasicBlock类的典型用法代码示例。如果您正苦于以下问题:C++ SILBasicBlock类的具体用法?C++ SILBasicBlock怎么用?C++ SILBasicBlock使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SILBasicBlock类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的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;
}
示例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);
}
}
}
}
示例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);
}
示例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;
}
示例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());
}
示例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());
}
}
示例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;
}
示例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});
}
}
}
示例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);
}
}
}
}
示例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;
}
示例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();
}
示例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.");
}
}
示例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;
}
示例14: DeadArgumentTransformFunction
void FunctionSignatureTransform::DeadArgumentTransformFunction() {
SILBasicBlock *BB = &*F->begin();
for (const ArgumentDescriptor &AD : ArgumentDescList) {
if (!AD.IsEntirelyDead)
continue;
eraseUsesOfValue(BB->getArgument(AD.Index));
}
}
示例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;
}