本文整理汇总了C++中Code::resetReachability方法的典型用法代码示例。如果您正苦于以下问题:C++ Code::resetReachability方法的具体用法?C++ Code::resetReachability怎么用?C++ Code::resetReachability使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Code
的用法示例。
在下文中一共展示了Code::resetReachability方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: prepareForGeneration
void prepareForGeneration(Code& code)
{
TimingScope timingScope("Air::prepareForGeneration");
// We don't expect the incoming code to have predecessors computed.
code.resetReachability();
if (shouldValidateIR())
validate(code);
// If we're doing super verbose dumping, the phase scope of any phase will already do a dump.
if (shouldDumpIR() && !shouldDumpIRAtEachPhase()) {
dataLog("Initial air:\n");
dataLog(code);
}
// This is where we run our optimizations and transformations.
// FIXME: Add Air optimizations.
// https://bugs.webkit.org/show_bug.cgi?id=150456
eliminateDeadCode(code);
// Register allocation for all the Tmps that do not have a corresponding machine register.
// After this phase, every Tmp has a reg.
//
// For debugging, you can use spillEverything() to put everything to the stack between each Inst.
if (Options::airSpillsEverything())
spillEverything(code);
else
iteratedRegisterCoalescing(code);
// Prior to this point the prologue and epilogue is implicit. This makes it explicit. It also
// does things like identify which callee-saves we're using and saves them.
handleCalleeSaves(code);
// This turns all Stack and CallArg Args into Addr args that use the frame pointer. It does
// this by first-fit allocating stack slots. It should be pretty darn close to optimal, so we
// shouldn't have to worry about this very much.
allocateStack(code);
// If we coalesced moves then we can unbreak critical edges. This is the main reason for this
// phase.
simplifyCFG(code);
// This sorts the basic blocks in Code to achieve an ordering that maximizes the likelihood that a high
// frequency successor is also the fall-through target.
optimizeBlockOrder(code);
// Attempt to remove false dependencies between instructions created by partial register changes.
// This must be executed as late as possible as it depends on the instructions order and register use.
fixPartialRegisterStalls(code);
// This is needed to satisfy a requirement of B3::StackmapValue.
reportUsedRegisters(code);
if (shouldValidateIR())
validate(code);
// Do a final dump of Air. Note that we have to do this even if we are doing per-phase dumping,
// since the final generation is not a phase.
if (shouldDumpIR()) {
dataLog("Air after ", code.lastPhaseName(), ", before generation:\n");
dataLog(code);
}
}
示例2: simplifyCFG
//.........这里部分代码省略.........
for (BasicBlock* block : code) {
for (BasicBlock* successor : block->successorBlocks())
RELEASE_ASSERT(successor->containsPredecessor(block));
}
}
// We don't care about blocks that don't have successors.
if (!block->numSuccessors())
continue;
// First check if any of the successors of this block can be forwarded over.
for (BasicBlock*& successor : block->successorBlocks()) {
if (successor != block
&& successor->size() == 1
&& successor->last().opcode == Jump) {
BasicBlock* newSuccessor = successor->successorBlock(0);
if (newSuccessor != successor) {
if (verbose) {
dataLog(
"Replacing ", pointerDump(block), "->", pointerDump(successor),
" with ", pointerDump(block), "->", pointerDump(newSuccessor), "\n");
}
// Note that we do not do replacePredecessor() because the block we're
// skipping will still have newSuccessor as its successor.
newSuccessor->addPredecessor(block);
successor = newSuccessor;
changed = true;
}
}
}
// Now check if the block's terminal can be replaced with a jump.
if (block->numSuccessors() > 1) {
// The terminal must not have weird effects.
if (!block->last().hasArgEffects()
&& !block->last().hasNonArgNonControlEffects()) {
// All of the successors must be the same.
bool allSame = true;
BasicBlock* firstSuccessor = block->successorBlock(0);
for (unsigned i = 1; i < block->numSuccessors(); ++i) {
if (block->successorBlock(i) != firstSuccessor) {
allSame = false;
break;
}
}
if (allSame) {
if (verbose)
dataLog("Changing ", pointerDump(block), "'s terminal to a Jump.\n");
block->last() = Inst(Jump, block->last().origin);
block->successors().resize(1);
block->successors()[0].frequency() = FrequencyClass::Normal;
changed = true;
}
}
}
// Finally handle jumps to a block with one predecessor.
if (block->numSuccessors() == 1) {
BasicBlock* successor = block->successorBlock(0);
if (successor != block && successor->numPredecessors() == 1) {
RELEASE_ASSERT(successor->predecessor(0) == block);
// We can merge the two blocks because the predecessor only jumps to the successor
// and the successor is only reachable from the predecessor.
// Remove the terminal.
Value* origin = block->insts().takeLast().origin;
// Append the full contents of the successor to the predecessor.
block->insts().reserveCapacity(block->size() + successor->size());
for (Inst& inst : *successor)
block->appendInst(WTFMove(inst));
// Make sure that our successors are the successor's successors.
block->successors() = WTFMove(successor->successors());
// Make sure that the successor has nothing left in it except an oops.
successor->resize(1);
successor->last() = Inst(Oops, origin);
successor->successors().clear();
// Ensure that the predecessors of block's new successors know what's up.
for (BasicBlock* newSuccessor : block->successorBlocks())
newSuccessor->replacePredecessor(successor, block);
if (verbose)
dataLog("Merged ", pointerDump(block), "->", pointerDump(successor), "\n");
changed = true;
}
}
}
if (!changed)
break;
result = true;
code.resetReachability();
}
return result;
}