本文整理汇总了C++中JumpDest类的典型用法代码示例。如果您正苦于以下问题:C++ JumpDest类的具体用法?C++ JumpDest怎么用?C++ JumpDest使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了JumpDest类的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: createJumpDest
void StmtEmitter::visitDoStmt(DoStmt *S) {
// We don't need to do anything fancy if we don't have a label.
// Otherwise, assume we might break or continue.
bool hasLabel = (bool) S->getLabelInfo();
JumpDest endDest = JumpDest::invalid();
if (hasLabel) {
// Create the end dest first so that the loop dest comes in-between.
endDest = createJumpDest(S->getBody());
// Create a new basic block and jump into it.
JumpDest loopDest = createJumpDest(S->getBody());
SGF.B.emitBlock(loopDest.getBlock(), S);
// Set the destinations for 'break' and 'continue'.
SGF.BreakContinueDestStack.push_back({S, endDest, loopDest});
}
// Emit the body.
visit(S->getBody());
if (hasLabel) {
SGF.BreakContinueDestStack.pop_back();
emitOrDeleteBlock(SGF, endDest, CleanupLocation(S));
}
}
示例2: JumpDest
void StmtEmitter::visitGuardStmt(GuardStmt *S) {
// Create a block for the body and emit code into it before processing any of
// the patterns, because none of the bound variables will be in scope in the
// 'body' context.
JumpDest bodyBB =
JumpDest(createBasicBlock(), SGF.getCleanupsDepth(), CleanupLocation(S));
{
// Move the insertion point to the 'body' block temporarily and emit it.
// Note that we don't push break/continue locations since they aren't valid
// in this statement.
SavedInsertionPoint savedIP(SGF, bodyBB.getBlock());
SGF.emitProfilerIncrement(S->getBody());
SGF.emitStmt(S->getBody());
// The body block must end in a noreturn call, return, break etc. It
// isn't valid to fall off into the normal flow. To model this, we emit
// an unreachable instruction and then have SIL diagnostic check this.
if (SGF.B.hasValidInsertionPoint())
SGF.B.createUnreachable(S);
}
// Emit the condition bindings, branching to the bodyBB if they fail. Since
// we didn't push a scope, the bound variables are live after this statement.
SGF.emitStmtCondition(S->getCond(), bodyBB, S);
}
示例3: emitBranchAndCleanups
/// emitBranchAndCleanups - Emit a branch to the given jump destination,
/// threading out through any cleanups we might need to run. This does not
/// pop the cleanup stack.
void CleanupManager::emitBranchAndCleanups(JumpDest Dest,
SILLocation BranchLoc,
ArrayRef<SILValue> Args) {
SILGenBuilder &B = Gen.getBuilder();
assert(B.hasValidInsertionPoint() && "Emitting branch in invalid spot");
emitCleanups(Dest.getDepth(), Dest.getCleanupLocation(), /*popCleanups=*/false);
B.createBranch(BranchLoc, Dest.getBlock(), Args);
}
示例4: 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;
}
示例5: condBufferScope
void StmtEmitter::visitWhileStmt(WhileStmt *S) {
LexicalScope condBufferScope(SGF, S);
// Create a new basic block and jump into it.
JumpDest loopDest = createJumpDest(S->getBody());
SGF.B.emitBlock(loopDest.getBlock(), S);
// Create a break target (at this level in the cleanup stack) in case it is
// needed.
JumpDest breakDest = createJumpDest(S->getBody());
// Set the destinations for any 'break' and 'continue' statements inside the
// body.
SGF.BreakContinueDestStack.push_back({S, breakDest, loopDest});
// Evaluate the condition, the body, and a branch back to LoopBB when the
// condition is true. On failure, jump to BreakBB.
{
// Enter a scope for any bound pattern variables.
Scope conditionScope(SGF.Cleanups, S);
auto NumTrueTaken = SGF.loadProfilerCount(S->getBody());
auto NumFalseTaken = SGF.loadProfilerCount(S);
SGF.emitStmtCondition(S->getCond(), breakDest, S, NumTrueTaken, NumFalseTaken);
// In the success path, emit the body of the while.
SGF.emitProfilerIncrement(S->getBody());
SGF.emitStmt(S->getBody());
// Finish the "true part" by cleaning up any temporaries and jumping to the
// continuation block.
if (SGF.B.hasValidInsertionPoint()) {
RegularLocation L(S->getBody());
L.pointToEnd();
SGF.Cleanups.emitBranchAndCleanups(loopDest, L);
}
}
SGF.BreakContinueDestStack.pop_back();
// Handle break block. If it was used, we link it up with the cleanup chain,
// otherwise we just remove it.
SILBasicBlock *breakBB = breakDest.getBlock();
if (breakBB->pred_empty()) {
SGF.eraseBasicBlock(breakBB);
} else {
SGF.B.emitBlock(breakBB);
}
}
示例6: isObviouslyBranchWithoutCleanups
/// isObviouslyBranchWithoutCleanups - Return true if a branch to the
/// specified destination obviously has no cleanups to run. 'false' is always
/// a conservatively correct answer for this method.
bool CodeGenFunction::isObviouslyBranchWithoutCleanups(JumpDest Dest) const {
assert(Dest.getScopeDepth().encloses(EHStack.stable_begin())
&& "stale jump destination");
// Calculate the innermost active normal cleanup.
EHScopeStack::stable_iterator TopCleanup =
EHStack.getInnermostActiveNormalCleanup();
// If we're not in an active normal cleanup scope, or if the
// destination scope is within the innermost active normal cleanup
// scope, we don't need to worry about fixups.
if (TopCleanup == EHStack.stable_end() ||
TopCleanup.encloses(Dest.getScopeDepth())) // works for invalid
return true;
// Otherwise, we might need some cleanups.
return false;
}
示例7: EmitBranchThroughCleanup
/// Terminate the current block by emitting a branch which might leave
/// the current cleanup-protected scope. The target scope may not yet
/// be known, in which case this will require a fixup.
///
/// As a side-effect, this method clears the insertion point.
void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
assert(Dest.getScopeDepth().encloses(EHStack.stable_begin())
&& "stale jump destination");
if (!HaveInsertPoint())
return;
// Create the branch.
llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
// Calculate the innermost active normal cleanup.
EHScopeStack::stable_iterator
TopCleanup = EHStack.getInnermostActiveNormalCleanup();
// If we're not in an active normal cleanup scope, or if the
// destination scope is within the innermost active normal cleanup
// scope, we don't need to worry about fixups.
if (TopCleanup == EHStack.stable_end() ||
TopCleanup.encloses(Dest.getScopeDepth())) { // works for invalid
Builder.ClearInsertionPoint();
return;
}
// If we can't resolve the destination cleanup scope, just add this
// to the current cleanup scope as a branch fixup.
if (!Dest.getScopeDepth().isValid()) {
BranchFixup &Fixup = EHStack.addBranchFixup();
Fixup.Destination = Dest.getBlock();
Fixup.DestinationIndex = Dest.getDestIndex();
Fixup.InitialBranch = BI;
Fixup.OptimisticBranchBlock = nullptr;
Builder.ClearInsertionPoint();
return;
}
// Otherwise, thread through all the normal cleanups in scope.
// Store the index at the start.
llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex());
new llvm::StoreInst(Index, getNormalCleanupDestSlot(), BI);
// Adjust BI to point to the first cleanup block.
{
EHCleanupScope &Scope =
cast<EHCleanupScope>(*EHStack.find(TopCleanup));
BI->setSuccessor(0, CreateNormalEntry(*this, Scope));
}
// Add this destination to all the scopes involved.
EHScopeStack::stable_iterator I = TopCleanup;
EHScopeStack::stable_iterator E = Dest.getScopeDepth();
if (E.strictlyEncloses(I)) {
while (true) {
EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(I));
assert(Scope.isNormalCleanup());
I = Scope.getEnclosingNormalCleanup();
// If this is the last cleanup we're propagating through, tell it
// that there's a resolved jump moving through it.
if (!E.strictlyEncloses(I)) {
Scope.addBranchAfter(Index, Dest.getBlock());
break;
}
// Otherwise, tell the scope that there's a jump propoagating
// through it. If this isn't new information, all the rest of
// the work has been done before.
if (!Scope.addBranchThrough(Dest.getBlock()))
break;
}
}
Builder.ClearInsertionPoint();
}
示例8: OuterForScope
void StmtEmitter::visitForEachStmt(ForEachStmt *S) {
// Emit the 'iterator' variable that we'll be using for iteration.
LexicalScope OuterForScope(SGF.Cleanups, SGF, CleanupLocation(S));
SGF.visitPatternBindingDecl(S->getIterator());
// If we ever reach an unreachable point, stop emitting statements.
// This will need revision if we ever add goto.
if (!SGF.B.hasValidInsertionPoint()) return;
// If generator's optional result is address-only, create a stack allocation
// to hold the results. This will be initialized on every entry into the loop
// header and consumed by the loop body. On loop exit, the terminating value
// will be in the buffer.
auto optTy = S->getIteratorNext()->getType()->getCanonicalType();
auto &optTL = SGF.getTypeLowering(optTy);
SILValue nextBufOrValue;
if (optTL.isAddressOnly())
nextBufOrValue = SGF.emitTemporaryAllocation(S, optTL.getLoweredType());
// Create a new basic block and jump into it.
JumpDest loopDest = createJumpDest(S->getBody());
SGF.B.emitBlock(loopDest.getBlock(), S);
// Set the destinations for 'break' and 'continue'.
JumpDest endDest = createJumpDest(S->getBody());
SGF.BreakContinueDestStack.push_back({ S, endDest, loopDest });
// Advance the generator. Use a scope to ensure that any temporary stack
// allocations in the subexpression are immediately released.
if (optTL.isAddressOnly()) {
Scope InnerForScope(SGF.Cleanups, CleanupLocation(S->getIteratorNext()));
auto nextInit = SGF.useBufferAsTemporary(nextBufOrValue, optTL);
SGF.emitExprInto(S->getIteratorNext(), nextInit.get());
nextInit->getManagedAddress().forward(SGF);
} else {
Scope InnerForScope(SGF.Cleanups, CleanupLocation(S->getIteratorNext()));
nextBufOrValue =
SGF.emitRValueAsSingleValue(S->getIteratorNext()).forward(SGF);
}
// Continue if the value is present.
Condition Cond = SGF.emitCondition(
SGF.emitDoesOptionalHaveValue(S, nextBufOrValue), S,
/*hasFalseCode=*/false, /*invertValue=*/false);
if (Cond.hasTrue()) {
Cond.enterTrue(SGF);
SGF.emitProfilerIncrement(S->getBody());
// Emit the loop body.
// The declared variable(s) for the current element are destroyed
// at the end of each loop iteration.
{
Scope InnerForScope(SGF.Cleanups, CleanupLocation(S->getBody()));
// Emit the initialization for the pattern. If any of the bound patterns
// fail (because this is a 'for case' pattern with a refutable pattern,
// the code should jump to the continue block.
InitializationPtr initLoopVars
= SGF.emitPatternBindingInitialization(S->getPattern(), loopDest);
ManagedValue val;
// If we had a loadable "next" generator value, we know it is present.
// Get the value out of the optional, and wrap it up with a cleanup so
// that any exits out of this scope properly clean it up.
if (optTL.isLoadable()) {
val = SGF.emitManagedRValueWithCleanup(nextBufOrValue);
} else {
val = SGF.emitManagedBufferWithCleanup(nextBufOrValue);
}
val = SGF.emitUncheckedGetOptionalValueFrom(S, val, optTL,
SGFContext(initLoopVars.get()));
if (!val.isInContext())
RValue(SGF, S, optTy.getAnyOptionalObjectType(), val)
.forwardInto(SGF, S, initLoopVars.get());
// Now that the pattern has been initialized, check any where condition.
// If it fails, loop around as if 'continue' happened.
if (auto *Where = S->getWhere()) {
auto cond = SGF.emitCondition(Where, /*hasFalse*/false, /*invert*/true);
// If self is null, branch to the epilog.
cond.enterTrue(SGF);
SGF.Cleanups.emitBranchAndCleanups(loopDest, Where, { });
cond.exitTrue(SGF);
cond.complete(SGF);
}
visit(S->getBody());
}
// Loop back to the header.
if (SGF.B.hasValidInsertionPoint()) {
// Associate the loop body's closing brace with this branch.
RegularLocation L(S->getBody());
L.pointToEnd();
SGF.B.createBranch(L, loopDest.getBlock());
}
Cond.exitTrue(SGF);
}
//.........这里部分代码省略.........
示例9: condBufferScope
void StmtEmitter::visitIfStmt(IfStmt *S) {
Scope condBufferScope(SGF.Cleanups, S);
// Create a continuation block. We need it if there is a labeled break out
// of the if statement or if there is an if/then/else.
JumpDest contDest = createJumpDest(S->getThenStmt());
auto contBB = contDest.getBlock();
// Set the destinations for any 'break' and 'continue' statements inside the
// body. Note that "continue" is not valid out of a labeled 'if'.
SGF.BreakContinueDestStack.push_back(
{ S, contDest, JumpDest(CleanupLocation(S)) });
// Set up the block for the false case. If there is an 'else' block, we make
// a new one, otherwise it is our continue block.
JumpDest falseDest = contDest;
if (S->getElseStmt())
falseDest = createJumpDest(S);
// Emit the condition, along with the "then" part of the if properly guarded
// by the condition and a jump to ContBB. If the condition fails, jump to
// the CondFalseBB.
{
// Enter a scope for any bound pattern variables.
LexicalScope trueScope(SGF.Cleanups, SGF, S);
SGF.emitStmtCondition(S->getCond(), falseDest, S);
// In the success path, emit the 'then' part if the if.
SGF.emitProfilerIncrement(S->getThenStmt());
SGF.emitStmt(S->getThenStmt());
// Finish the "true part" by cleaning up any temporaries and jumping to the
// continuation block.
if (SGF.B.hasValidInsertionPoint()) {
RegularLocation L(S->getThenStmt());
L.pointToEnd();
SGF.Cleanups.emitBranchAndCleanups(contDest, L);
}
}
// If there is 'else' logic, then emit it.
if (S->getElseStmt()) {
SGF.B.emitBlock(falseDest.getBlock());
visit(S->getElseStmt());
if (SGF.B.hasValidInsertionPoint()) {
RegularLocation L(S->getElseStmt());
L.pointToEnd();
SGF.B.createBranch(L, contBB);
}
}
// If the continuation block was used, emit it now, otherwise remove it.
if (contBB->pred_empty()) {
SGF.eraseBasicBlock(contBB);
} else {
RegularLocation L(S->getThenStmt());
L.pointToEnd();
SGF.B.emitBlock(contBB, L);
}
SGF.BreakContinueDestStack.pop_back();
}
示例10: OuterForScope
void StmtEmitter::visitForEachStmt(ForEachStmt *S) {
// Emit the 'iterator' variable that we'll be using for iteration.
LexicalScope OuterForScope(SGF, CleanupLocation(S));
SGF.visitPatternBindingDecl(S->getIterator());
// If we ever reach an unreachable point, stop emitting statements.
// This will need revision if we ever add goto.
if (!SGF.B.hasValidInsertionPoint()) return;
// If generator's optional result is address-only, create a stack allocation
// to hold the results. This will be initialized on every entry into the loop
// header and consumed by the loop body. On loop exit, the terminating value
// will be in the buffer.
auto optTy = S->getIteratorNext()->getType()->getCanonicalType();
auto &optTL = SGF.getTypeLowering(optTy);
SILValue addrOnlyBuf;
ManagedValue nextBufOrValue;
if (optTL.isAddressOnly() && SGF.silConv.useLoweredAddresses())
addrOnlyBuf = SGF.emitTemporaryAllocation(S, optTL.getLoweredType());
// Create a new basic block and jump into it.
JumpDest loopDest = createJumpDest(S->getBody());
SGF.B.emitBlock(loopDest.getBlock(), S);
// Set the destinations for 'break' and 'continue'.
JumpDest endDest = createJumpDest(S->getBody());
SGF.BreakContinueDestStack.push_back({ S, endDest, loopDest });
// Then emit the loop destination block.
//
// Advance the generator. Use a scope to ensure that any temporary stack
// allocations in the subexpression are immediately released.
if (optTL.isAddressOnly() && SGF.silConv.useLoweredAddresses()) {
// Create the initialization outside of the innerForScope so that the
// innerForScope doesn't clean it up.
auto nextInit = SGF.useBufferAsTemporary(addrOnlyBuf, optTL);
{
Scope innerForScope(SGF.Cleanups, CleanupLocation(S->getIteratorNext()));
SGF.emitExprInto(S->getIteratorNext(), nextInit.get());
}
nextBufOrValue = nextInit->getManagedAddress();
} else {
Scope innerForScope(SGF.Cleanups, CleanupLocation(S->getIteratorNext()));
nextBufOrValue = innerForScope.popPreservingValue(
SGF.emitRValueAsSingleValue(S->getIteratorNext()));
}
SILBasicBlock *failExitingBlock = createBasicBlock();
SwitchEnumBuilder switchEnumBuilder(SGF.B, S, nextBufOrValue);
switchEnumBuilder.addOptionalSomeCase(
createBasicBlock(), loopDest.getBlock(),
[&](ManagedValue inputValue, SwitchCaseFullExpr &&scope) {
SGF.emitProfilerIncrement(S->getBody());
// Emit the loop body.
// The declared variable(s) for the current element are destroyed
// at the end of each loop iteration.
{
Scope innerForScope(SGF.Cleanups, CleanupLocation(S->getBody()));
// Emit the initialization for the pattern. If any of the bound
// patterns
// fail (because this is a 'for case' pattern with a refutable
// pattern,
// the code should jump to the continue block.
InitializationPtr initLoopVars =
SGF.emitPatternBindingInitialization(S->getPattern(), loopDest);
// If we had a loadable "next" generator value, we know it is present.
// Get the value out of the optional, and wrap it up with a cleanup so
// that any exits out of this scope properly clean it up.
//
// *NOTE* If we do not have an address only value, then inputValue is
// *already properly unwrapped.
if (optTL.isAddressOnly() && SGF.silConv.useLoweredAddresses()) {
inputValue = SGF.emitUncheckedGetOptionalValueFrom(
S, inputValue, optTL, SGFContext(initLoopVars.get()));
}
if (!inputValue.isInContext())
RValue(SGF, S, optTy.getOptionalObjectType(), inputValue)
.forwardInto(SGF, S, initLoopVars.get());
// Now that the pattern has been initialized, check any where
// condition.
// If it fails, loop around as if 'continue' happened.
if (auto *Where = S->getWhere()) {
auto cond =
SGF.emitCondition(Where, /*hasFalse*/ false, /*invert*/ true);
// If self is null, branch to the epilog.
cond.enterTrue(SGF);
SGF.Cleanups.emitBranchAndCleanups(loopDest, Where, {});
cond.exitTrue(SGF);
cond.complete(SGF);
}
visit(S->getBody());
}
//.........这里部分代码省略.........