本文整理汇总了C++中BasicBlock::appendNode方法的典型用法代码示例。如果您正苦于以下问题:C++ BasicBlock::appendNode方法的具体用法?C++ BasicBlock::appendNode怎么用?C++ BasicBlock::appendNode使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BasicBlock
的用法示例。
在下文中一共展示了BasicBlock::appendNode方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: createPreHeader
BasicBlock* createPreHeader(Graph& graph, BlockInsertionSet& insertionSet, BasicBlock* block)
{
// Don't bother to preserve execution frequencies for now.
BasicBlock* preHeader = insertionSet.insertBefore(block, PNaN);
preHeader->appendNode(
graph, SpecNone, Jump, block->firstOrigin(), OpInfo(block));
for (unsigned predecessorIndex = 0; predecessorIndex < block->predecessors.size(); predecessorIndex++) {
BasicBlock* predecessor = block->predecessors[predecessorIndex];
if (graph.m_dominators.dominates(block, predecessor))
continue;
block->predecessors[predecessorIndex--] = block->predecessors.last();
block->predecessors.removeLast();
for (unsigned successorIndex = predecessor->numSuccessors(); successorIndex--;) {
BasicBlock*& successor = predecessor->successor(successorIndex);
if (successor != block)
continue;
successor = preHeader;
preHeader->predecessors.append(predecessor);
}
}
block->predecessors.append(preHeader);
return preHeader;
}
示例2: breakCriticalEdge
void breakCriticalEdge(BasicBlock* predecessor, BasicBlock** successor)
{
BasicBlock* pad = m_insertionSet.insertBefore(*successor);
pad->appendNode(
m_graph, SpecNone, Jump, (*successor)->at(0)->origin, OpInfo(*successor));
pad->predecessors.append(predecessor);
(*successor)->replacePredecessor(predecessor, pad);
*successor = pad;
}
示例3: run
bool run()
{
for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
// An edge A->B is critical if A has multiple successor and B has multiple
// predecessors. Thus we fail early if we don't have multiple successors.
if (block->numSuccessors() <= 1)
continue;
// Break critical edges by inserting a "Jump" pad block in place of each
// unique A->B critical edge.
HashMap<BasicBlock*, BasicBlock*> successorPads;
for (unsigned i = block->numSuccessors(); i--;) {
BasicBlock** successor = &block->successor(i);
if ((*successor)->predecessors.size() <= 1)
continue;
BasicBlock* pad = nullptr;
auto iter = successorPads.find(*successor);
if (iter == successorPads.end()) {
pad = m_insertionSet.insertBefore(*successor, (*successor)->executionCount);
pad->appendNode(
m_graph, SpecNone, Jump, (*successor)->at(0)->origin, OpInfo(*successor));
pad->predecessors.append(block);
(*successor)->replacePredecessor(block, pad);
successorPads.set(*successor, pad);
} else
pad = iter->value;
*successor = pad;
}
}
return m_insertionSet.execute();
}
示例4: createPreHeader
BasicBlock* createPreHeader(Graph& graph, BlockInsertionSet& insertionSet, BasicBlock* block)
{
BasicBlock* preHeader = insertionSet.insertBefore(block);
preHeader->appendNode(
graph, SpecNone, Jump, block->at(0)->codeOrigin, OpInfo(block));
for (unsigned predecessorIndex = 0; predecessorIndex < block->predecessors.size(); predecessorIndex++) {
BasicBlock* predecessor = block->predecessors[predecessorIndex];
if (graph.m_dominators.dominates(block, predecessor))
continue;
block->predecessors[predecessorIndex--] = block->predecessors.last();
block->predecessors.removeLast();
for (unsigned successorIndex = predecessor->numSuccessors(); successorIndex--;) {
BasicBlock*& successor = predecessor->successor(successorIndex);
if (successor != block)
continue;
successor = preHeader;
preHeader->predecessors.append(predecessor);
}
}
block->predecessors.append(preHeader);
return preHeader;
}
示例5: run
bool run()
{
RELEASE_ASSERT(m_graph.m_plan.mode == FTLForOSREntryMode);
RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
unsigned bytecodeIndex = m_graph.m_plan.osrEntryBytecodeIndex;
RELEASE_ASSERT(bytecodeIndex);
RELEASE_ASSERT(bytecodeIndex != UINT_MAX);
// Needed by createPreHeader().
m_graph.ensureDominators();
CodeBlock* baseline = m_graph.m_profiledBlock;
BasicBlock* target = 0;
for (unsigned blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
unsigned nodeIndex = 0;
Node* firstNode = block->at(0);
while (firstNode->isSemanticallySkippable())
firstNode = block->at(++nodeIndex);
if (firstNode->op() == LoopHint
&& firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) {
target = block;
break;
}
}
if (!target) {
// This is a terrible outcome. It shouldn't often happen but it might
// happen and so we should defend against it. If it happens, then this
// compilation is a failure.
return false;
}
BlockInsertionSet insertionSet(m_graph);
// We say that the execution count of the entry block is 1, because we know for sure
// that this must be the case. Under our definition of executionCount, "1" means "once
// per invocation". We could have said NaN here, since that would ask any clients of
// executionCount to use best judgement - but that seems unnecessary since we know for
// sure what the executionCount should be in this case.
BasicBlock* newRoot = insertionSet.insert(0, 1);
// We'd really like to use an unset origin, but ThreadedCPS won't allow that.
NodeOrigin origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), false);
Vector<Node*> locals(baseline->m_numCalleeLocals);
for (int local = 0; local < baseline->m_numCalleeLocals; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
locals[local] = newRoot->appendNode(
m_graph, variable->prediction(), ExtractOSREntryLocal, origin,
OpInfo(variable->local().offset()));
newRoot->appendNode(
m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()),
Edge(locals[local]));
}
// Now use the origin of the target, since it's not OK to exit, and we will probably hoist
// type checks to here.
origin = target->at(0)->origin;
for (int argument = 0; argument < baseline->numParameters(); ++argument) {
Node* oldNode = target->variablesAtHead.argument(argument);
if (!oldNode) {
// Just for sanity, always have a SetArgument even if it's not needed.
oldNode = m_graph.m_arguments[argument];
}
Node* node = newRoot->appendNode(
m_graph, SpecNone, SetArgument, origin,
OpInfo(oldNode->variableAccessData()));
m_graph.m_arguments[argument] = node;
}
for (int local = 0; local < baseline->m_numCalleeLocals; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
Node* node = locals[local];
newRoot->appendNode(
m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node));
}
newRoot->appendNode(
m_graph, SpecNone, Jump, origin,
OpInfo(createPreHeader(m_graph, insertionSet, target)));
insertionSet.execute();
m_graph.resetReachability();
m_graph.killUnreachableBlocks();
return true;
}
示例6: run
bool run()
{
const bool extremeLogging = false;
bool outerChanged = false;
bool innerChanged;
do {
innerChanged = false;
for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
ASSERT(block->isReachable);
switch (block->last()->op()) {
case Jump: {
// Successor with one predecessor -> merge.
if (block->successor(0)->predecessors.size() == 1) {
ASSERT(block->successor(0)->predecessors[0] == block);
if (extremeLogging)
m_graph.dump();
m_graph.dethread();
mergeBlocks(block, block->successor(0), noBlocks());
innerChanged = outerChanged = true;
break;
}
// FIXME: Block only has a jump -> remove. This is tricky though because of
// liveness. What we really want is to slam in a phantom at the end of the
// block, after the terminal. But we can't right now. :-(
// Idea: what if I slam the ghosties into my successor? Nope, that's
// suboptimal, because if my successor has multiple predecessors then we'll
// be keeping alive things on other predecessor edges unnecessarily.
// What we really need is the notion of end-of-block ghosties!
break;
}
case Branch: {
// Branch on constant -> jettison the not-taken block and merge.
if (isKnownDirection(block->cfaBranchDirection)) {
bool condition = branchCondition(block->cfaBranchDirection);
BasicBlock* targetBlock = block->successorForCondition(condition);
BasicBlock* jettisonedBlock = block->successorForCondition(!condition);
if (targetBlock->predecessors.size() == 1) {
if (extremeLogging)
m_graph.dump();
m_graph.dethread();
mergeBlocks(block, targetBlock, oneBlock(jettisonedBlock));
} else {
if (extremeLogging)
m_graph.dump();
m_graph.dethread();
ASSERT(block->last()->isTerminal());
CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin;
block->last()->convertToPhantom();
ASSERT(block->last()->refCount() == 1);
jettisonBlock(block, jettisonedBlock, boundaryCodeOrigin);
block->appendNode(
m_graph, SpecNone, Jump, boundaryCodeOrigin,
OpInfo(targetBlock));
}
innerChanged = outerChanged = true;
break;
}
if (block->successor(0) == block->successor(1)) {
convertToJump(block, block->successor(0));
innerChanged = outerChanged = true;
break;
}
// Branch to same destination -> jump.
// FIXME: this will currently not be hit because of the lack of jump-only
// block simplification.
break;
}
case Switch: {
SwitchData* data = block->last()->switchData();
// Prune out cases that end up jumping to default.
for (unsigned i = 0; i < data->cases.size(); ++i) {
if (data->cases[i].target == data->fallThrough)
data->cases[i--] = data->cases.takeLast();
}
// If there are no cases other than default then this turns
// into a jump.
if (data->cases.isEmpty()) {
convertToJump(block, data->fallThrough);
innerChanged = outerChanged = true;
break;
}
// Switch on constant -> jettison all other targets and merge.
//.........这里部分代码省略.........
示例7: run
bool run()
{
const bool extremeLogging = false;
bool outerChanged = false;
bool innerChanged;
do {
innerChanged = false;
for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
ASSERT(block->isReachable);
switch (block->last()->op()) {
case Jump: {
// Successor with one predecessor -> merge.
if (m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors.size() == 1) {
ASSERT(m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors[0]
== blockIndex);
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("CFGSimplify: Jump merge on Block #%u to Block #%u.\n",
blockIndex, m_graph.successor(block, 0));
#endif
if (extremeLogging)
m_graph.dump();
m_graph.dethread();
mergeBlocks(blockIndex, m_graph.successor(block, 0), NoBlock);
innerChanged = outerChanged = true;
break;
} else {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("Not jump merging on Block #%u to Block #%u because predecessors = ",
blockIndex, m_graph.successor(block, 0));
for (unsigned i = 0; i < m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors.size(); ++i) {
if (i)
dataLogF(", ");
dataLogF("#%u", m_graph.m_blocks[m_graph.successor(block, 0)]->m_predecessors[i]);
}
dataLogF(".\n");
#endif
}
// FIXME: Block only has a jump -> remove. This is tricky though because of
// liveness. What we really want is to slam in a phantom at the end of the
// block, after the terminal. But we can't right now. :-(
// Idea: what if I slam the ghosties into my successor? Nope, that's
// suboptimal, because if my successor has multiple predecessors then we'll
// be keeping alive things on other predecessor edges unnecessarily.
// What we really need is the notion of end-of-block ghosties!
break;
}
case Branch: {
// Branch on constant -> jettison the not-taken block and merge.
if (isKnownDirection(block->cfaBranchDirection)) {
bool condition = branchCondition(block->cfaBranchDirection);
BasicBlock* targetBlock = m_graph.m_blocks[
m_graph.successorForCondition(block, condition)].get();
if (targetBlock->m_predecessors.size() == 1) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("CFGSimplify: Known condition (%s) branch merge on Block #%u to Block #%u, jettisoning Block #%u.\n",
condition ? "true" : "false",
blockIndex, m_graph.successorForCondition(block, condition),
m_graph.successorForCondition(block, !condition));
#endif
if (extremeLogging)
m_graph.dump();
m_graph.dethread();
mergeBlocks(
blockIndex,
m_graph.successorForCondition(block, condition),
m_graph.successorForCondition(block, !condition));
} else {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("CFGSimplify: Known condition (%s) branch->jump conversion on Block #%u to Block #%u, jettisoning Block #%u.\n",
condition ? "true" : "false",
blockIndex, m_graph.successorForCondition(block, condition),
m_graph.successorForCondition(block, !condition));
#endif
if (extremeLogging)
m_graph.dump();
m_graph.dethread();
BlockIndex takenBlockIndex = m_graph.successorForCondition(block, condition);
BlockIndex notTakenBlockIndex = m_graph.successorForCondition(block, !condition);
ASSERT(block->last()->isTerminal());
CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin;
block->last()->convertToPhantom();
ASSERT(block->last()->refCount() == 1);
jettisonBlock(blockIndex, notTakenBlockIndex, boundaryCodeOrigin);
block->appendNode(
m_graph, SpecNone, Jump, boundaryCodeOrigin,
OpInfo(takenBlockIndex));
}
innerChanged = outerChanged = true;
break;
//.........这里部分代码省略.........
示例8: run
bool run()
{
RELEASE_ASSERT(m_graph.m_plan.mode == FTLForOSREntryMode);
RELEASE_ASSERT(m_graph.m_form == ThreadedCPS);
unsigned bytecodeIndex = m_graph.m_plan.osrEntryBytecodeIndex;
RELEASE_ASSERT(bytecodeIndex);
RELEASE_ASSERT(bytecodeIndex != UINT_MAX);
// Needed by createPreHeader().
m_graph.m_dominators.computeIfNecessary(m_graph);
CodeBlock* baseline = m_graph.m_profiledBlock;
BasicBlock* target = 0;
for (unsigned blockIndex = m_graph.numBlocks(); blockIndex--;) {
BasicBlock* block = m_graph.block(blockIndex);
if (!block)
continue;
unsigned nodeIndex = 0;
Node* firstNode = block->at(0);
while (firstNode->isSemanticallySkippable())
firstNode = block->at(++nodeIndex);
if (firstNode->op() == LoopHint
&& firstNode->origin.semantic == CodeOrigin(bytecodeIndex)) {
target = block;
break;
}
}
if (!target) {
// This is a terrible outcome. It shouldn't often happen but it might
// happen and so we should defend against it. If it happens, then this
// compilation is a failure.
return false;
}
BlockInsertionSet insertionSet(m_graph);
BasicBlock* newRoot = insertionSet.insert(0, QNaN);
NodeOrigin origin = target->at(0)->origin;
Vector<Node*> locals(baseline->m_numCalleeRegisters);
for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
locals[local] = newRoot->appendNode(
m_graph, variable->prediction(), ExtractOSREntryLocal, origin,
OpInfo(variable->local().offset()));
newRoot->appendNode(
m_graph, SpecNone, MovHint, origin, OpInfo(variable->local().offset()),
Edge(locals[local]));
}
for (int argument = 0; argument < baseline->numParameters(); ++argument) {
Node* oldNode = target->variablesAtHead.argument(argument);
if (!oldNode) {
// Just for sanity, always have a SetArgument even if it's not needed.
oldNode = m_graph.m_arguments[argument];
}
Node* node = newRoot->appendNode(
m_graph, SpecNone, SetArgument, origin,
OpInfo(oldNode->variableAccessData()));
m_graph.m_arguments[argument] = node;
}
for (int local = 0; local < baseline->m_numCalleeRegisters; ++local) {
Node* previousHead = target->variablesAtHead.local(local);
if (!previousHead)
continue;
VariableAccessData* variable = previousHead->variableAccessData();
Node* node = locals[local];
newRoot->appendNode(
m_graph, SpecNone, SetLocal, origin, OpInfo(variable), Edge(node));
}
newRoot->appendNode(
m_graph, SpecNone, Jump, origin,
OpInfo(createPreHeader(m_graph, insertionSet, target)));
insertionSet.execute();
m_graph.resetReachability();
m_graph.killUnreachableBlocks();
return true;
}