aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4isel_moth.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-05-14 14:44:27 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2014-06-13 10:29:33 +0200
commitd74927cf5d6b6601e9ac01c22475c2cbe07f1a0e (patch)
tree1e67e34da64e87adf1f615d9b9bafa8bec38ece4 /src/qml/compiler/qv4isel_moth.cpp
parentcb0a47a48d5dc0ce4f5e8cfa68a39cd4cbfde11c (diff)
V4 RegAlloc: change life-time intervals from closed to half-open.
There are two changes in this patch, that go hand-in-hand. First, when re-numbering the statements in order of occurrence in the scheduled basic-blocks, the (new) position is not stored in the statement itself, but in the LifeTimeIntervals class. This makes it possible to re-use information gathered during SSA formation or optimization. The re-numbering itself has also changed, resulting in some minor changes to the life-time interval calculation. The new numbering is described in LifeTimeIntervals::renumber(). The reason is to make it easy for the register allocator and stack-slot allocator to distinguish between definition of a temporary and its uses. Example: 20: %3 = %2 + %1 22: print(%3) If the life-time of %2 or %1 ends at 20, then at the point that %3 gets assigned, it can re-use the storage occupied by %1 or %2. Also, when both %1 and %2 need to get a register assigned (because they were spilled to the stack, for example), %3 should be allocated "after" both %1 and %2. So, instead of having a closed interval of [20-22] for %3, we want to use an open interval of (20-22]. To simulate the "open" part, the life-time of %3 is set to [21-22]. So, all statements live on even positions, and temporaries defined by a statement start at statmentPosition + 1. Change-Id: I0eda2c653b0edf1a529bd0762d338b0ea9a66aa0 Sanity-Review: Qt Sanity Bot <qt_sanitybot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4isel_moth.cpp')
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp13
1 files changed, 8 insertions, 5 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 18877565da..c684aa3e79 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -174,7 +174,12 @@ class AllocateStackSlots: protected ConvertTemps
QBitArray _slotIsInUse;
IR::Function *_function;
- int position(IR::Stmt *s) const
+ int defPosition(IR::Stmt *s) const
+ {
+ return usePosition(s) + 1;
+ }
+
+ int usePosition(IR::Stmt *s) const
{
return _intervals->positionForStatement(s);
}
@@ -222,8 +227,6 @@ protected:
virtual void process(IR::Stmt *s)
{
- Q_ASSERT(position(s) > 0);
-
// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id);
if (IR::Phi *phi = s->asPhi()) {
@@ -232,7 +235,7 @@ protected:
// purge ranges no longer alive:
for (int i = 0; i < _live.size(); ) {
const IR::LifeTimeInterval *lti = _live.at(i);
- if (lti->end() < position(s)) {
+ if (lti->end() < usePosition(s)) {
// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index];
_live.remove(i);
Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]);
@@ -246,7 +249,7 @@ protected:
// active new ranges:
while (!_unhandled.isEmpty()) {
IR::LifeTimeInterval *lti = _unhandled.last();
- if (lti->start() > position(s))
+ if (lti->start() > defPosition(s))
break; // we're done
Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index));
_stackSlotForTemp[lti->temp().index] = allocateFreeSlot();