Commit 4fe26dec authored by oliver@apple.com's avatar oliver@apple.com

fourthTier: NaturalLoops should be able to quickly answer questions like "what...

fourthTier: NaturalLoops should be able to quickly answer questions like "what loops own this basic block"
https://bugs.webkit.org/show_bug.cgi?id=118750

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

* dfg/DFGBasicBlock.h:
(BasicBlock):
* dfg/DFGNaturalLoops.cpp:
(JSC::DFG::NaturalLoops::compute):
(JSC::DFG::NaturalLoops::loopsOf):
* dfg/DFGNaturalLoops.h:
(DFG):
(JSC::DFG::NaturalLoop::NaturalLoop):
(NaturalLoop):
(JSC::DFG::NaturalLoop::index):
(JSC::DFG::NaturalLoop::isOuterMostLoop):
(JSC::DFG::NaturalLoop::addBlock):
(JSC::DFG::NaturalLoops::headerOf):
(JSC::DFG::NaturalLoops::innerMostLoopOf):
(NaturalLoops):
(JSC::DFG::NaturalLoops::innerMostOuterLoop):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):

Source/WTF:

Reviewed by Mark Hahnenberg.

Add a utility function for inserting an element into a vector that has bounded size,
and where the insertion causes things to drop off the end.

* wtf/StdLibExtras.h:
(WTF):
(WTF::insertIntoBoundedVector):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153277 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0f220549
2013-07-16 Filip Pizlo <fpizlo@apple.com>
fourthTier: NaturalLoops should be able to quickly answer questions like "what loops own this basic block"
https://bugs.webkit.org/show_bug.cgi?id=118750
Reviewed by Mark Hahnenberg.
* dfg/DFGBasicBlock.h:
(BasicBlock):
* dfg/DFGNaturalLoops.cpp:
(JSC::DFG::NaturalLoops::compute):
(JSC::DFG::NaturalLoops::loopsOf):
* dfg/DFGNaturalLoops.h:
(DFG):
(JSC::DFG::NaturalLoop::NaturalLoop):
(NaturalLoop):
(JSC::DFG::NaturalLoop::index):
(JSC::DFG::NaturalLoop::isOuterMostLoop):
(JSC::DFG::NaturalLoop::addBlock):
(JSC::DFG::NaturalLoops::headerOf):
(JSC::DFG::NaturalLoops::innerMostLoopOf):
(NaturalLoops):
(JSC::DFG::NaturalLoops::innerMostOuterLoop):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
2013-07-16 Filip Pizlo <fpizlo@apple.com>
fourthTier: don't GC when shutting down the VM
......
......@@ -127,6 +127,10 @@ struct BasicBlock : RefCounted<BasicBlock> {
Operands<AbstractValue> valuesAtHead;
Operands<AbstractValue> valuesAtTail;
// These fields are reserved for NaturalLoops.
static const unsigned numberOfInnerMostLoopIndices = 2;
unsigned innerMostLoopIndices[numberOfInnerMostLoopIndices];
struct SSAData {
Operands<FlushFormat> flushFormatAtHead;
Operands<FlushFormat> flushFormatAtTail;
......
......@@ -84,7 +84,7 @@ void NaturalLoops::compute(Graph& graph)
}
if (found)
continue;
NaturalLoop loop(successor);
NaturalLoop loop(successor, m_loops.size());
loop.addBlock(block);
m_loops.append(loop);
}
......@@ -131,6 +131,65 @@ void NaturalLoops::compute(Graph& graph)
}
}
}
// Figure out reverse mapping from blocks to loops.
for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
BasicBlock* block = graph.block(blockIndex);
if (!block)
continue;
for (unsigned i = BasicBlock::numberOfInnerMostLoopIndices; i--;)
block->innerMostLoopIndices[i] = UINT_MAX;
}
for (unsigned loopIndex = m_loops.size(); loopIndex--;) {
NaturalLoop& loop = m_loops[loopIndex];
for (unsigned blockIndexInLoop = loop.size(); blockIndexInLoop--;) {
BasicBlock* block = loop[blockIndexInLoop];
for (unsigned i = 0; i < BasicBlock::numberOfInnerMostLoopIndices; ++i) {
unsigned thisIndex = block->innerMostLoopIndices[i];
if (thisIndex == UINT_MAX || loop.size() < m_loops[thisIndex].size()) {
insertIntoBoundedVector(
block->innerMostLoopIndices, BasicBlock::numberOfInnerMostLoopIndices,
loopIndex, i);
break;
}
}
}
}
// Now each block knows its inner-most loop and its next-to-inner-most loop. Use
// this to figure out loop parenting.
for (unsigned i = m_loops.size(); i--;) {
NaturalLoop& loop = m_loops[i];
RELEASE_ASSERT(loop.header()->innerMostLoopIndices[0] == i);
loop.m_outerLoopIndex = loop.header()->innerMostLoopIndices[1];
}
if (validationEnabled()) {
// Do some self-verification that we've done some of this correctly.
for (BlockIndex blockIndex = graph.numBlocks(); blockIndex--;) {
BasicBlock* block = graph.block(blockIndex);
if (!block)
continue;
Vector<const NaturalLoop*> simpleLoopsOf;
for (unsigned i = m_loops.size(); i--;) {
if (m_loops[i].contains(block))
simpleLoopsOf.append(&m_loops[i]);
}
Vector<const NaturalLoop*> fancyLoopsOf = loopsOf(block);
std::sort(simpleLoopsOf.begin(), simpleLoopsOf.end());
std::sort(fancyLoopsOf.begin(), fancyLoopsOf.end());
RELEASE_ASSERT(simpleLoopsOf == fancyLoopsOf);
}
}
if (verbose)
dataLog("Results: ", *this, "\n");
......@@ -139,12 +198,8 @@ void NaturalLoops::compute(Graph& graph)
Vector<const NaturalLoop*> NaturalLoops::loopsOf(BasicBlock* block) const
{
Vector<const NaturalLoop*> result;
for (unsigned i = m_loops.size(); i--;) {
if (m_loops[i].contains(block))
result.append(&m_loops[i]);
}
for (const NaturalLoop* loop = innerMostLoopOf(block); loop; loop = innerMostOuterLoop(*loop))
result.append(loop);
return result;
}
......
......@@ -36,20 +36,23 @@
namespace JSC { namespace DFG {
class NaturalLoops;
class NaturalLoop {
public:
NaturalLoop()
: m_header(0)
, m_outerLoopIndex(UINT_MAX)
{
}
NaturalLoop(BasicBlock* header)
NaturalLoop(BasicBlock* header, unsigned index)
: m_header(header)
, m_outerLoopIndex(UINT_MAX)
, m_index(index)
{
}
void addBlock(BasicBlock* block) { m_body.append(block); }
BasicBlock* header() const { return m_header; }
unsigned size() const { return m_body.size(); }
......@@ -65,11 +68,22 @@ public:
ASSERT(block != header()); // Header should be contained.
return false;
}
// The index of this loop in NaturalLoops.
unsigned index() const { return m_index; }
bool isOuterMostLoop() const { return m_outerLoopIndex == UINT_MAX; }
void dump(PrintStream&) const;
private:
friend class NaturalLoops;
void addBlock(BasicBlock* block) { m_body.append(block); }
BasicBlock* m_header;
Vector<BasicBlock*, 4> m_body;
unsigned m_outerLoopIndex;
unsigned m_index;
};
class NaturalLoops : public Analysis<NaturalLoops> {
......@@ -94,13 +108,31 @@ public:
// loop it belongs to.
const NaturalLoop* headerOf(BasicBlock* block) const
{
for (unsigned i = m_loops.size(); i--;) {
if (m_loops[i].header() == block)
return &m_loops[i];
const NaturalLoop* loop = innerMostLoopOf(block);
if (loop->header() == block)
return loop;
if (!ASSERT_DISABLED) {
for (; loop; loop = innerMostOuterLoop(*loop))
ASSERT(loop->header() != block);
}
return 0;
}
const NaturalLoop* innerMostLoopOf(BasicBlock* block) const
{
unsigned index = block->innerMostLoopIndices[0];
if (index == UINT_MAX)
return 0;
return &m_loops[index];
}
const NaturalLoop* innerMostOuterLoop(const NaturalLoop& loop) const
{
if (loop.m_outerLoopIndex == UINT_MAX)
return 0;
return &m_loops[loop.m_outerLoopIndex];
}
// Return the indices of all loops this belongs to.
Vector<const NaturalLoop*> loopsOf(BasicBlock*) const;
......
......@@ -187,6 +187,13 @@ Plan::CompilationPath Plan::compileInThreadImpl(LongLivedState& longLivedState)
dfg.m_fixpointState = FixpointConverged;
performStoreElimination(dfg);
// If we're doing validation, then run some analyses, to give them an opportunity
// to self-validate. Now is as good a time as any to do this.
if (validationEnabled()) {
dfg.m_dominators.computeIfNecessary(dfg);
dfg.m_naturalLoops.computeIfNecessary(dfg);
}
#if ENABLE(FTL_JIT)
if (Options::useExperimentalFTL()
......
2013-07-16 Filip Pizlo <fpizlo@apple.com>
fourthTier: NaturalLoops should be able to quickly answer questions like "what loops own this basic block"
https://bugs.webkit.org/show_bug.cgi?id=118750
Reviewed by Mark Hahnenberg.
Add a utility function for inserting an element into a vector that has bounded size,
and where the insertion causes things to drop off the end.
* wtf/StdLibExtras.h:
(WTF):
(WTF::insertIntoBoundedVector):
2013-07-12 Filip Pizlo <fpizlo@apple.com>
fourthTier: DFG should have an SSA form for use by FTL
......
......@@ -260,6 +260,14 @@ inline ArrayElementType* approximateBinarySearch(const ArrayType& array, size_t
return binarySearchImpl<ArrayElementType, KeyType, ArrayType, ExtractKey, ReturnAdjacentElementIfKeyIsNotPresent>(const_cast<ArrayType&>(array), size, key, extractKey);
}
template<typename VectorType, typename ElementType>
inline void insertIntoBoundedVector(VectorType& vector, size_t size, const ElementType& element, size_t index)
{
for (unsigned i = size; i-- > index + 1;)
vector[i] = vector[i - 1];
vector[index] = element;
}
} // namespace WTF
#if OS(WINCE)
......@@ -297,6 +305,7 @@ inline void* operator new(size_t, NotNullTag, void* location)
using WTF::KB;
using WTF::MB;
using WTF::insertIntoBoundedVector;
using WTF::isPointerAligned;
using WTF::is8ByteAligned;
using WTF::binarySearch;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment