зеркало из https://github.com/dotnet/llilc.git
Merge pull request #450 from JosephTremoulet/NoPropPreds
Allow blocks to have zero stack-propagating preds
This commit is contained in:
Коммит
4259af9c73
|
@ -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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче