DFGBlockWorklist.h [plain text]
#ifndef DFGBlockWorklist_h
#define DFGBlockWorklist_h
#if ENABLE(DFG_JIT)
#include "DFGBasicBlock.h"
#include "DFGBlockSet.h"
#include <wtf/Vector.h>
namespace JSC { namespace DFG {
struct BasicBlock;
class BlockWorklist {
public:
BlockWorklist();
~BlockWorklist();
bool push(BasicBlock*);
bool notEmpty() const { return !m_stack.isEmpty(); }
BasicBlock* pop();
private:
BlockSet m_seen;
Vector<BasicBlock*, 16> m_stack;
};
template<typename T>
struct BlockWith {
BlockWith()
: block(nullptr)
{
}
BlockWith(BasicBlock* block, const T& data)
: block(block)
, data(data)
{
}
explicit operator bool() const { return block; }
BasicBlock* block;
T data;
};
template<typename T>
class ExtendedBlockWorklist {
public:
ExtendedBlockWorklist() { }
void forcePush(const BlockWith<T>& entry)
{
m_stack.append(entry);
}
void forcePush(BasicBlock* block, const T& data)
{
forcePush(BlockWith<T>(block, data));
}
bool push(const BlockWith<T>& entry)
{
if (!m_seen.add(entry.block))
return false;
forcePush(entry);
return true;
}
bool push(BasicBlock* block, const T& data)
{
return push(BlockWith<T>(block, data));
}
bool notEmpty() const { return !m_stack.isEmpty(); }
BlockWith<T> pop()
{
if (m_stack.isEmpty())
return BlockWith<T>();
return m_stack.takeLast();
}
private:
BlockSet m_seen;
Vector<BlockWith<T>> m_stack;
};
enum VisitOrder {
PreOrder,
PostOrder
};
struct BlockWithOrder {
BlockWithOrder()
: block(nullptr)
, order(PreOrder)
{
}
BlockWithOrder(BasicBlock* block, VisitOrder order)
: block(block)
, order(order)
{
}
explicit operator bool() const { return block; }
BasicBlock* block;
VisitOrder order;
};
class PostOrderBlockWorklist {
public:
PostOrderBlockWorklist();
~PostOrderBlockWorklist();
bool pushPre(BasicBlock*);
void pushPost(BasicBlock*);
bool push(BasicBlock* block, VisitOrder order = PreOrder)
{
switch (order) {
case PreOrder:
return pushPre(block);
case PostOrder:
pushPost(block);
return true;
}
RELEASE_ASSERT_NOT_REACHED();
return false;
}
bool push(const BlockWithOrder& data)
{
return push(data.block, data.order);
}
bool notEmpty() const { return m_worklist.notEmpty(); }
BlockWithOrder pop();
private:
ExtendedBlockWorklist<VisitOrder> m_worklist;
};
} }
#endif // ENABLE(DFG_JIT)
#endif // DFGBlockWorklist_h