Merge pull request #450 from JosephTremoulet/NoPropPreds

Allow blocks to have zero stack-propagating preds
This commit is contained in:
Joseph Tremoulet 2015-04-16 20:24:58 -04:00
Родитель 6cce44d449 97e648796f
Коммит 4259af9c73
3 изменённых файлов: 31 добавлений и 4 удалений

Просмотреть файл

@ -2714,6 +2714,13 @@ public:
/// propagate operand stack. /// propagate operand stack.
bool fgNodeHasMultiplePredsPropagatingStack(FlowGraphNode *Node); bool fgNodeHasMultiplePredsPropagatingStack(FlowGraphNode *Node);
/// Check whether this node has any predecessors that propagate operand stack.
///
/// \param Node Flow graph node.
/// \returns true iff this flow graph node has any predecessors that propagate
/// operand stack.
bool fgNodeHasNoPredsPropagatingStack(FlowGraphNode *Node);
virtual IRNode * virtual IRNode *
getStaticFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken) = 0; getStaticFieldAddress(CORINFO_RESOLVED_TOKEN *ResolvedToken) = 0;
virtual void initBlk(IRNode *NumBytes, IRNode *ValuePerByte, virtual void initBlk(IRNode *NumBytes, IRNode *ValuePerByte,

Просмотреть файл

@ -8011,7 +8011,8 @@ void ReaderBase::msilToIR(void) {
// Check that CurrentNode is the only predecessor of Successor that // Check that CurrentNode is the only predecessor of Successor that
// propagates stack. // propagates stack.
ASSERTNR(!fgNodeHasMultiplePredsPropagatingStack(Successor)); ASSERTNR(!fgNodeHasMultiplePredsPropagatingStack(Successor));
ASSERTNR(fgNodePropagatesOperandStack(CurrentNode)); ASSERTNR(fgNodePropagatesOperandStack(CurrentNode) ||
fgNodeHasNoPredsPropagatingStack(Successor));
// The two checks above ensure that it's safe to insert Successor after // The two checks above ensure that it's safe to insert Successor after
// CurrentNode even if that breaks MSIL offset order. // CurrentNode even if that breaks MSIL offset order.
@ -8086,6 +8087,20 @@ bool ReaderBase::fgNodeHasMultiplePredsPropagatingStack(FlowGraphNode *Node) {
return false; return false;
} }
bool ReaderBase::fgNodeHasNoPredsPropagatingStack(FlowGraphNode *Node) {
for (FlowGraphEdgeList *NodePredecessorList =
fgNodeGetPredecessorListActual(Node);
NodePredecessorList != nullptr;
NodePredecessorList =
fgEdgeListGetNextPredecessorActual(NodePredecessorList)) {
FlowGraphNode *PredecessorNode = fgEdgeListGetSource(NodePredecessorList);
if (fgNodePropagatesOperandStack(PredecessorNode)) {
return false;
}
}
return true;
}
// Checks to see if a given offset is the start of an instruction. If // Checks to see if a given offset is the start of an instruction. If
// the offset is not the start of an instruction the whole program // the offset is not the start of an instruction the whole program
// must be discarded as it's global flow may not be able to be // must be discarded as it's global flow may not be able to be

Просмотреть файл

@ -5415,15 +5415,20 @@ void GenIR::maintainOperandStack(FlowGraphNode *CurrentBlock) {
FlowGraphNode *SuccessorBlock = fgEdgeListGetSink(SuccessorList); FlowGraphNode *SuccessorBlock = fgEdgeListGetSink(SuccessorList);
if (!fgNodeHasMultiplePredsPropagatingStack(SuccessorBlock)) { if (!fgNodeHasMultiplePredsPropagatingStack(SuccessorBlock)) {
// The current node is the only relevant predecessor of this Successor.
ASSERTNR(fgNodePropagatesOperandStack(CurrentBlock));
// We need to create a stack for the Successor and copy the items from the // We need to create a stack for the Successor and copy the items from the
// current stack. // current stack.
if (!fgNodePropagatesOperandStack(SuccessorBlock)) { if (!fgNodePropagatesOperandStack(SuccessorBlock)) {
// This successor block doesn't need a stack. This is a common case for // This successor block doesn't need a stack. This is a common case for
// implicit exception throw blocks or conditional helper calls. // implicit exception throw blocks or conditional helper calls.
} else { } else {
// The current node is the only relevant predecessor of this Successor.
if (fgNodePropagatesOperandStack(CurrentBlock)) {
fgNodeSetOperandStack(SuccessorBlock, ReaderOperandStack->copy()); fgNodeSetOperandStack(SuccessorBlock, ReaderOperandStack->copy());
} else {
// The successor block starts with empty stack.
assert(fgNodeHasNoPredsPropagatingStack(SuccessorBlock));
fgNodeSetOperandStack(SuccessorBlock, createStack());
}
} }
} else { } else {
ReaderStack *SuccessorStack = fgNodeGetOperandStack(SuccessorBlock); ReaderStack *SuccessorStack = fgNodeGetOperandStack(SuccessorBlock);