mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1040738 part 1 - Add MNodeIterator to iterate over resume points and definitions. r=sunfish
This commit is contained in:
parent
d652aca550
commit
9a005d215d
@ -730,8 +730,8 @@ class MIRGraph
|
||||
|
||||
class MDefinitionIterator
|
||||
{
|
||||
|
||||
friend class MBasicBlock;
|
||||
friend class MNodeIterator;
|
||||
|
||||
private:
|
||||
MBasicBlock *block_;
|
||||
@ -784,6 +784,94 @@ class MDefinitionIterator
|
||||
MDefinition *operator ->() {
|
||||
return getIns();
|
||||
}
|
||||
};
|
||||
|
||||
// Iterates on all resume points, phis, and instructions of a MBasicBlock.
|
||||
// Resume points are visited as long as the instruction which holds it is not
|
||||
// discarded.
|
||||
class MNodeIterator
|
||||
{
|
||||
private:
|
||||
// Last instruction which holds a resume point. To handle the entry point
|
||||
// resume point, it is set to the last instruction, assuming that the last
|
||||
// instruction is not discarded before we visit it.
|
||||
MInstruction *last_;
|
||||
|
||||
// Definition iterator which is one step ahead when visiting resume points.
|
||||
// This is in order to avoid incrementing the iterator while it is settled
|
||||
// on a discarded instruction.
|
||||
MDefinitionIterator defIter_;
|
||||
|
||||
MBasicBlock *block() const {
|
||||
return defIter_.block_;
|
||||
}
|
||||
|
||||
bool atResumePoint() const {
|
||||
return last_ && !last_->isDiscarded();
|
||||
}
|
||||
|
||||
MNode *getNode() {
|
||||
if (!atResumePoint())
|
||||
return *defIter_;
|
||||
|
||||
// We use the last instruction as a sentinelle to iterate over the entry
|
||||
// resume point of the basic block, before even starting to iterate on
|
||||
// the instruction list. Otherwise, the last_ corresponds to the
|
||||
// previous instruction.
|
||||
if (last_ != block()->lastIns())
|
||||
return last_->resumePoint();
|
||||
return block()->entryResumePoint();
|
||||
}
|
||||
|
||||
void next() {
|
||||
if (!atResumePoint()) {
|
||||
if (defIter_->isInstruction() && defIter_->toInstruction()->resumePoint()) {
|
||||
// In theory, we could but in practice this does not happen.
|
||||
MOZ_ASSERT(*defIter_ != block()->lastIns());
|
||||
last_ = defIter_->toInstruction();
|
||||
}
|
||||
|
||||
defIter_++;
|
||||
} else {
|
||||
last_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool more() const {
|
||||
return defIter_ || atResumePoint();
|
||||
}
|
||||
|
||||
public:
|
||||
explicit MNodeIterator(MBasicBlock *block)
|
||||
: last_(block->entryResumePoint() ? block->lastIns() : nullptr),
|
||||
defIter_(block)
|
||||
{
|
||||
MOZ_ASSERT(bool(block->entryResumePoint()) == atResumePoint());
|
||||
|
||||
// We use the last instruction to check for the entry resume point,
|
||||
// assert that no control instruction has any resume point. If so, then
|
||||
// we need to handle this case in this iterator.
|
||||
MOZ_ASSERT(!block->lastIns()->resumePoint());
|
||||
}
|
||||
|
||||
MNodeIterator operator ++(int) {
|
||||
MNodeIterator old(*this);
|
||||
if (more())
|
||||
next();
|
||||
return old;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return more();
|
||||
}
|
||||
|
||||
MNode *operator *() {
|
||||
return getNode();
|
||||
}
|
||||
|
||||
MNode *operator ->() {
|
||||
return getNode();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user