本文整理汇总了C++中SrcKey::succOffsets方法的典型用法代码示例。如果您正苦于以下问题:C++ SrcKey::succOffsets方法的具体用法?C++ SrcKey::succOffsets怎么用?C++ SrcKey::succOffsets使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SrcKey
的用法示例。
在下文中一共展示了SrcKey::succOffsets方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: endsUnitAtSrcKey
/*
* Returns true iff `block' ends the IR unit after finishing execution
* of the bytecode instruction at `sk'.
*/
static bool endsUnitAtSrcKey(const Block* block, SrcKey sk) {
if (!block->isExitNoThrow()) return false;
const auto& inst = block->back();
const auto instSk = inst.marker().sk();
switch (inst.op()) {
// These instructions end a unit after executing the bytecode
// instruction they correspond to.
case InterpOneCF:
case JmpSSwitchDest:
case JmpSwitchDest:
case RaiseError:
return instSk == sk;;
// The RetCtrl is generally ending a bytecode instruction, with the
// exception being in an Await bytecode instruction, where we consider the
// end of the bytecode instruction to be the non-suspending path.
case RetCtrl:
case AsyncRetCtrl:
return inst.marker().sk().op() != Op::Await;
// A ReqBindJmp ends a unit and it jumps to the next instruction
// to execute.
case ReqBindJmp: {
auto destOffset = inst.extra<ReqBindJmp>()->dest.offset();
return sk.succOffsets().count(destOffset);
}
default:
return false;
}
}
示例2: endsUnitAtSrcKey
/*
* Returns true iff `block' ends the IR unit after finishing execution
* of the bytecode instruction at `sk'.
*/
static bool endsUnitAtSrcKey(const Block* block, SrcKey sk) {
if (!block->isExitNoThrow()) return false;
const auto& inst = block->back();
const auto instSk = inst.marker().sk();
switch (inst.op()) {
// These instructions end a unit after executing the bytecode
// instruction they correspond to.
case InterpOneCF:
case JmpSSwitchDest:
case JmpSwitchDest:
case RaiseError:
case ThrowOutOfBounds:
case ThrowInvalidArrayKey:
case ThrowInvalidOperation:
case ThrowArithmeticError:
case ThrowDivisionByZeroError:
case VerifyParamFailHard:
case VerifyRetFailHard:
case Unreachable:
case EndBlock:
case FatalMissingThis:
return instSk == sk;
// The RetCtrl is generally ending a bytecode instruction, with the
// exception being in an Await bytecode instruction, where we consider the
// end of the bytecode instruction to be the non-suspending path.
case RetCtrl:
case AsyncRetCtrl:
case AsyncRetFast:
case AsyncSwitchFast:
return inst.marker().sk().op() != Op::Await;
// A ReqBindJmp ends a unit and it jumps to the next instruction to
// execute.
case ReqBindJmp: {
auto destOffset = inst.extra<ReqBindJmp>()->target.offset();
return sk.succOffsets().count(destOffset);
}
default:
return false;
}
}
示例3: check
/*
* Checks if the given region is well-formed, which entails the
* following properties:
*
* 1) The region has at least one block.
*
* 2) Each block in the region has a different id.
*
* 3) All arcs involve blocks within the region.
*
* 4) For each arc, the bytecode offset of the dst block must
* possibly follow the execution of the src block.
*
* 5) Each block contains at most one successor corresponding to a
* given SrcKey.
*
* 6) The region doesn't contain any loops, unless JitLoops is
* enabled.
*
* 7) All blocks are reachable from the entry block.
*
* 8) For each block, there must be a path from the entry to it that
* includes only earlier blocks in the region.
*
* 9) The region is topologically sorted unless loops are enabled.
*
* 10) The block-retranslation chains cannot have cycles.
*
*/
bool check(const RegionDesc& region, std::string& error) {
auto bad = [&](const std::string& errorMsg) {
error = errorMsg;
return false;
};
// 1) The region has at least one block.
if (region.empty()) return bad("empty region");
RegionDesc::BlockIdSet blockSet;
for (auto b : region.blocks()) {
auto bid = b->id();
// 2) Each block in the region has a different id.
if (blockSet.count(bid)) {
return bad(folly::sformat("many blocks with id {}", bid));
}
blockSet.insert(bid);
}
for (auto b : region.blocks()) {
auto bid = b->id();
SrcKey lastSk = region.block(bid)->last();
OffsetSet validSuccOffsets = lastSk.succOffsets();
OffsetSet succOffsets;
for (auto succ : region.succs(bid)) {
SrcKey succSk = region.block(succ)->start();
Offset succOffset = succSk.offset();
// 3) All arcs involve blocks within the region.
if (blockSet.count(succ) == 0) {
return bad(folly::sformat("arc with dst not in the region: {} -> {}",
bid, succ));
}
// Checks 4) and 5) below don't make sense for arcs corresponding
// to inlined calls and returns, so skip them in such cases.
// This won't be possible once task #4076399 is done.
if (lastSk.func() != succSk.func()) continue;
// 4) For each arc, the bytecode offset of the dst block must
// possibly follow the execution of the src block.
if (validSuccOffsets.count(succOffset) == 0) {
return bad(folly::sformat("arc with impossible control flow: {} -> {}",
bid, succ));
}
// 5) Each block contains at most one successor corresponding to a
// given SrcKey.
if (succOffsets.count(succOffset) > 0) {
return bad(folly::sformat("block {} has multiple successors with SK {}",
bid, show(succSk)));
}
succOffsets.insert(succOffset);
}
for (auto pred : region.preds(bid)) {
if (blockSet.count(pred) == 0) {
return bad(folly::sformat("arc with src not in the region: {} -> {}",
pred, bid));
}
}
}
// 6) is checked by dfsCheck.
DFSChecker dfsCheck(region);
if (!dfsCheck.check(region.entry()->id())) {
return bad("region is cyclic");
}
// 7) All blocks are reachable from the entry (first) block.
//.........这里部分代码省略.........