aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4ssa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler/qv4ssa.cpp')
-rw-r--r--src/qml/compiler/qv4ssa.cpp389
1 files changed, 183 insertions, 206 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 5861138dbe..c0a14a5c80 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -40,6 +40,7 @@
#include "qv4isel_util_p.h"
#include "qv4util_p.h"
+#include <QtCore/QBuffer>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QSet>
@@ -51,9 +52,6 @@
#include <cassert>
#include <algorithm>
-#undef SHOW_SSA
-#undef DEBUG_MOVEMAPPING
-
QT_USE_NAMESPACE
using namespace QV4;
@@ -61,21 +59,25 @@ using namespace IR;
namespace {
+enum { DebugMoveMapping = 0 };
+
#ifdef QT_NO_DEBUG
enum { DoVerification = 0 };
#else
enum { DoVerification = 1 };
#endif
-Q_GLOBAL_STATIC_WITH_ARGS(QTextStream, qout, (stderr, QIODevice::WriteOnly));
-#define qout *qout()
-
-void showMeTheCode(IR::Function *function)
+static void showMeTheCode(IR::Function *function, const char *marker)
{
static bool showCode = !qgetenv("QV4_SHOW_IR").isNull();
if (showCode) {
- IRPrinter(&qout).print(function);
- qout << endl;
+ qDebug() << marker;
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream stream(&buf);
+ IRPrinter(&stream).print(function);
+ stream << endl;
+ qDebug("%s", buf.data().constData());
}
}
@@ -104,10 +106,9 @@ public:
class BasicBlockSet
{
- typedef std::vector<int> Numbers;
typedef std::vector<bool> Flags;
- Numbers *blockNumbers;
+ QVarLengthArray<int, 8> blockNumbers;
Flags *blockFlags;
IR::Function *function;
enum { MaxVectorCapacity = 8 };
@@ -117,7 +118,7 @@ public:
{
const BasicBlockSet &set;
// ### These two members could go into a union, but clang won't compile (https://codereview.qt-project.org/#change,74259)
- Numbers::const_iterator numberIt;
+ QVarLengthArray<int, 8>::const_iterator numberIt;
size_t flagIt;
friend class BasicBlockSet;
@@ -125,13 +126,13 @@ public:
: set(set)
{
if (end || !set.function) {
- if (set.blockNumbers)
- numberIt = set.blockNumbers->end();
+ if (!set.blockFlags)
+ numberIt = set.blockNumbers.end();
else
flagIt = set.blockFlags->size();
} else {
- if (set.blockNumbers)
- numberIt = set.blockNumbers->begin();
+ if (!set.blockFlags)
+ numberIt = set.blockNumbers.begin();
else
findNextWithFlags(0);
}
@@ -161,8 +162,7 @@ public:
public:
BasicBlock *operator*() const
{
-
- if (set.blockNumbers) {
+ if (!set.blockFlags) {
return set.function->basicBlock(*numberIt);
} else {
Q_ASSERT(flagIt <= static_cast<size_t>(set.function->basicBlockCount()));
@@ -174,7 +174,7 @@ public:
{
if (&set != &other.set)
return false;
- if (set.blockNumbers)
+ if (!set.blockFlags)
return numberIt == other.numberIt;
else
return flagIt == other.flagIt;
@@ -185,7 +185,7 @@ public:
const_iterator &operator++()
{
- if (set.blockNumbers)
+ if (!set.blockFlags)
++numberIt;
else
findNextWithFlags(flagIt + 1);
@@ -197,14 +197,14 @@ public:
friend class const_iterator;
public:
- BasicBlockSet(IR::Function *f = 0): blockNumbers(0), blockFlags(0), function(0)
+ BasicBlockSet(IR::Function *f = 0): blockFlags(0), function(0)
{
if (f)
init(f);
}
#ifdef Q_COMPILER_RVALUE_REFS
- BasicBlockSet(BasicBlockSet &&other): blockNumbers(0), blockFlags(0)
+ BasicBlockSet(BasicBlockSet &&other): blockFlags(0)
{
std::swap(blockNumbers, other.blockNumbers);
std::swap(blockFlags, other.blockFlags);
@@ -213,14 +213,12 @@ public:
#endif // Q_COMPILER_RVALUE_REFS
BasicBlockSet(const BasicBlockSet &other)
- : blockNumbers(0)
- , blockFlags(0)
+ : blockFlags(0)
, function(other.function)
{
if (other.blockFlags)
blockFlags = new Flags(*other.blockFlags);
- else if (other.blockNumbers)
- blockNumbers = new Numbers(*other.blockNumbers);
+ blockNumbers = other.blockNumbers;
}
BasicBlockSet &operator=(const BasicBlockSet &other)
@@ -228,27 +226,24 @@ public:
if (blockFlags) {
delete blockFlags;
blockFlags = 0;
- } else {
- delete blockNumbers;
- blockNumbers = 0;
}
function = other.function;
if (other.blockFlags)
blockFlags = new Flags(*other.blockFlags);
- else if (other.blockNumbers)
- blockNumbers = new Numbers(*other.blockNumbers);
+ blockNumbers = other.blockNumbers;
return *this;
}
- ~BasicBlockSet() { delete blockNumbers; delete blockFlags; }
+ ~BasicBlockSet()
+ {
+ delete blockFlags;
+ }
void init(IR::Function *f)
{
Q_ASSERT(!function);
Q_ASSERT(f);
function = f;
- blockNumbers = new Numbers;
- blockNumbers->reserve(MaxVectorCapacity);
}
bool empty() const
@@ -265,21 +260,20 @@ public:
return;
}
- for (std::vector<int>::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end();
- i != ei; ++i)
- if (*i == bb->index())
+ for (int i = 0; i < blockNumbers.size(); ++i) {
+ if (blockNumbers[i] == bb->index())
return;
+ }
- if (blockNumbers->size() == MaxVectorCapacity) {
+ if (blockNumbers.size() == MaxVectorCapacity) {
blockFlags = new Flags(function->basicBlockCount(), false);
- for (std::vector<int>::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end();
- i != ei; ++i)
- blockFlags->operator[](*i) = true;
- delete blockNumbers;
- blockNumbers = 0;
+ for (int i = 0; i < blockNumbers.size(); ++i) {
+ blockFlags->operator[](blockNumbers[i]) = true;
+ }
+ blockNumbers.clear();
blockFlags->operator[](bb->index()) = true;
} else {
- blockNumbers->push_back(bb->index());
+ blockNumbers.append(bb->index());
}
}
@@ -292,9 +286,9 @@ public:
return;
}
- for (std::vector<int>::iterator i = blockNumbers->begin(), ei = blockNumbers->end(); i != ei; ++i) {
- if (*i == bb->index()) {
- blockNumbers->erase(i);
+ for (int i = 0; i < blockNumbers.size(); ++i) {
+ if (blockNumbers[i] == bb->index()) {
+ blockNumbers.remove(i);
return;
}
}
@@ -318,8 +312,8 @@ public:
if (blockFlags)
return (*blockFlags)[bb->index()];
- for (std::vector<int>::const_iterator i = blockNumbers->begin(), ei = blockNumbers->end(); i != ei; ++i) {
- if (*i == bb->index())
+ for (int i = 0; i < blockNumbers.size(); ++i) {
+ if (blockNumbers[i] == bb->index())
return true;
}
@@ -402,11 +396,6 @@ class DominatorTree
todo = worklist.back();
worklist.pop_back();
}
-
-#if defined(SHOW_SSA)
- for (int i = 0; i < nodes.size(); ++i)
- qDebug("\tL%d: dfnum = %d, parent = %d", i, dfnum[i], parent[i]);
-#endif // SHOW_SSA
}
BasicBlockIndex ancestorWithLowestSemi(BasicBlockIndex v, std::vector<BasicBlockIndex> &worklist) {
@@ -592,6 +581,9 @@ public:
}
if (DebugDominatorFrontiers) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout << "Dominator Frontiers:" << endl;
foreach (BasicBlock *n, function->basicBlocks()) {
if (n->isRemoved())
@@ -606,6 +598,7 @@ public:
}
qout << "}" << endl;
}
+ qDebug("%s", buf.data().constData());
}
if (DebugDominatorFrontiers && DebugCodeCanUseLotsOfCpu) {
@@ -624,7 +617,7 @@ public:
}
}
if (!hasDominatedSucc) {
- qout << fBlock << " in DF[" << n->index() << "] has no dominated predecessors" << endl;
+ qDebug("%d in DF[%d] has no dominated predecessors", fBlock->index(), n->index());
}
Q_ASSERT(hasDominatedSucc);
}
@@ -646,6 +639,9 @@ public:
void dumpImmediateDominators() const
{
if (DebugImmediateDominators) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout << "Immediate dominators:" << endl;
foreach (BasicBlock *to, function->basicBlocks()) {
if (to->isRemoved())
@@ -659,6 +655,7 @@ public:
qout << "(none)";
qout << " -> " << to->index() << endl;
}
+ qDebug("%s", buf.data().constData());
}
}
@@ -953,10 +950,6 @@ public:
for (int i = 0, ei = A_orig.size(); i != ei; ++i)
A_orig[i].reserve(8);
-#if defined(SHOW_SSA)
- qout << "Variables collected:" << endl;
-#endif // SHOW_SSA
-
foreach (BasicBlock *bb, function->basicBlocks()) {
if (bb->isRemoved())
continue;
@@ -966,17 +959,6 @@ public:
foreach (Stmt *s, bb->statements())
s->accept(this);
}
-
-#if defined(SHOW_SSA)
- qout << "Non-locals:" << endl;
- foreach (const Temp &nonLocal, nonLocals) {
- qout << "\t";
- nonLocal.dump(qout);
- qout << endl;
- }
-
- qout << "end collected variables." << endl;
-#endif // SHOW_SSA
}
const std::vector<Temp> &allTemps() const
@@ -1038,12 +1020,6 @@ protected:
addTemp(t);
if (isCollectable(t)) {
-#if defined(SHOW_SSA)
- qout << '\t';
- t->dump(qout);
- qout << " -> L" << currentBB->index << endl;
-#endif // SHOW_SSA
-
_defsites[t->index].insert(currentBB);
addDefInCurrentBlock(t);
@@ -1161,9 +1137,10 @@ public:
defUse.blockOfStatement = defBlock;
}
- QList<UntypedTemp> defsUntyped() const
+ QVector<UntypedTemp> defsUntyped() const
{
- QList<UntypedTemp> res;
+ QVector<UntypedTemp> res;
+ res.reserve(tempCount());
foreach (const DefUse &du, _defUses)
if (du.isValid())
res.append(UntypedTemp(du.temp));
@@ -1274,6 +1251,9 @@ public:
void dump() const
{
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout << "Defines and uses:" << endl;
foreach (const DefUse &du, _defUses) {
if (!du.isValid())
@@ -1294,16 +1274,11 @@ public:
qout << ' ' << t.index;
qout << endl;
}
+ qDebug("%s", buf.data().constData());
}
};
void insertPhiNode(const Temp &a, BasicBlock *y, IR::Function *f) {
-#if defined(SHOW_SSA)
- qout << "-> inserted phi node for variable ";
- a.dump(qout);
- qout << " in block " << y->index << endl;
-#endif
-
Phi *phiNode = f->NewStmt<Phi>();
phiNode->d = new Stmt::Data;
phiNode->targetTemp = f->New<Temp>();
@@ -1643,15 +1618,6 @@ protected:
// see [Appel]. For the changes needed for semi-pruned SSA form, and for its advantages, see [Briggs].
void convertToSSA(IR::Function *function, const DominatorTree &df, DefUses &defUses)
{
-#if defined(SHOW_SSA)
- qout << "Converting function ";
- if (function->name)
- qout << *function->name;
- else
- qout << "<no name>";
- qout << " to SSA..." << endl;
-#endif // SHOW_SSA
-
// Collect all applicable variables:
VariableCollector variables(function);
@@ -2113,12 +2079,15 @@ protected:
struct DiscoveredType {
int type;
- MemberExpressionResolver memberResolver;
+ MemberExpressionResolver *memberResolver;
- DiscoveredType() : type(UnknownType) {}
- DiscoveredType(Type t) : type(t) { Q_ASSERT(type != QObjectType); }
- explicit DiscoveredType(int t) : type(t) { Q_ASSERT(type != QObjectType); }
- explicit DiscoveredType(MemberExpressionResolver memberResolver) : type(QObjectType), memberResolver(memberResolver) {}
+ DiscoveredType() : type(UnknownType), memberResolver(0) {}
+ DiscoveredType(Type t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
+ explicit DiscoveredType(int t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
+ explicit DiscoveredType(MemberExpressionResolver *memberResolver)
+ : type(QObjectType)
+ , memberResolver(memberResolver)
+ { Q_ASSERT(memberResolver); }
bool test(Type t) const { return type & t; }
bool isNumber() const { return (type & NumberType) && !(type & ~NumberType); }
@@ -2223,7 +2192,7 @@ class TypeInference: public StmtVisitor, public ExprVisitor
this->type = type;
fullyTyped = type.type != UnknownType;
}
- explicit TypingResult(MemberExpressionResolver memberResolver)
+ explicit TypingResult(MemberExpressionResolver *memberResolver)
: type(memberResolver)
, fullyTyped(true)
{}
@@ -2248,23 +2217,32 @@ public:
continue;
if (DebugTypeInference) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout<<"Typing stmt ";
IRPrinter(&qout).print(s);
- qout<<endl;
+ qDebug("%s", buf.data().constData());
}
if (!run(s)) {
*_worklist += s;
if (DebugTypeInference) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout<<"Pushing back stmt: ";
IRPrinter(&qout).print(s);
- qout<<endl;
+ qDebug("%s", buf.data().constData());
}
} else {
if (DebugTypeInference) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout<<"Finished: ";
IRPrinter(&qout).print(s);
- qout<<endl;
+ qDebug("%s", buf.data().constData());
}
}
}
@@ -2306,9 +2284,9 @@ private:
void setType(Expr *e, DiscoveredType ty) {
if (Temp *t = e->asTemp()) {
if (DebugTypeInference)
- qout << "Setting type for temp " << t->index
- << " to " << typeName(Type(ty.type)) << " (" << ty.type << ")"
- << endl;
+ qDebug() << "Setting type for temp" << t->index
+ << " to " << typeName(Type(ty.type)) << "(" << ty.type << ")"
+ << endl;
DiscoveredType &it = _tempTypes[t->index];
if (it != ty) {
@@ -2316,9 +2294,12 @@ private:
if (DebugTypeInference) {
foreach (Stmt *s, _defUses.uses(*t)) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
qout << "Pushing back dependent stmt: ";
IRPrinter(&qout).print(s);
- qout<<endl;
+ qDebug("%s", buf.data().constData());
}
}
@@ -2345,7 +2326,7 @@ protected:
virtual void visitRegExp(IR::RegExp *) { _ty = TypingResult(VarType); }
virtual void visitName(Name *) { _ty = TypingResult(VarType); }
virtual void visitTemp(Temp *e) {
- if (e->memberResolver.isValid())
+ if (e->memberResolver && e->memberResolver->isValid())
_ty = TypingResult(e->memberResolver);
else
_ty = TypingResult(_tempTypes[e->index]);
@@ -2456,9 +2437,9 @@ protected:
virtual void visitMember(Member *e) {
_ty = run(e->base);
- if (_ty.fullyTyped && _ty.type.memberResolver.isValid()) {
- MemberExpressionResolver &resolver = _ty.type.memberResolver;
- _ty.type.type = resolver.resolveMember(qmlEngine, &resolver, e);
+ if (_ty.fullyTyped && _ty.type.memberResolver && _ty.type.memberResolver->isValid()) {
+ MemberExpressionResolver *resolver = _ty.type.memberResolver;
+ _ty.type.type = resolver->resolveMember(qmlEngine, resolver, e);
} else
_ty.type = VarType;
}
@@ -2492,8 +2473,8 @@ protected:
}
_ty.type.type |= ty.type.type;
_ty.fullyTyped &= ty.fullyTyped;
- if (_ty.type.test(QObjectType))
- _ty.type.memberResolver.clear(); // ### TODO: find common ancestor meta-object
+ if (_ty.type.test(QObjectType) && _ty.type.memberResolver)
+ _ty.type.memberResolver->clear(); // ### TODO: find common ancestor meta-object
}
switch (_ty.type.type) {
@@ -2539,7 +2520,7 @@ public:
Q_UNUSED(f);
QVector<UntypedTemp> knownOk;
- QList<UntypedTemp> candidates = _defUses.defsUntyped();
+ QVector<UntypedTemp> candidates = _defUses.defsUntyped();
while (!candidates.isEmpty()) {
UntypedTemp temp = candidates.last();
candidates.removeLast();
@@ -2711,15 +2692,6 @@ class TypePropagation: public StmtVisitor, public ExprVisitor {
if (requestedType != UnknownType) {
if (e->type != requestedType) {
if (requestedType & NumberType || requestedType == BoolType) {
-#ifdef SHOW_SSA
- QTextStream os(stdout, QIODevice::WriteOnly);
- os << "adding conversion from " << typeName(e->type)
- << " to " << typeName(requestedType) << " for expression ";
- e->dump(os);
- os << " in statement ";
- _currStmt->dump(os);
- os << endl;
-#endif
if (insertConversion)
addConversion(e, requestedType);
return true;
@@ -3416,15 +3388,9 @@ public:
QHash<BasicBlock *, BasicBlock *> go()
{
- showMeTheCode(function);
+ showMeTheCode(function, "Before block scheduling");
schedule(function->basicBlock(0));
-#if defined(SHOW_SSA)
- qDebug() << "Block sequence:";
- foreach (BasicBlock *bb, sequence)
- qDebug("\tL%d", bb->index());
-#endif // SHOW_SSA
-
Q_ASSERT(function->liveBasicBlocksCount() == sequence.size());
function->setScheduledBlocks(sequence);
function->renumberBasicBlocks();
@@ -3438,8 +3404,8 @@ void checkCriticalEdges(QVector<BasicBlock *> basicBlocks) {
if (bb && bb->out.size() > 1) {
foreach (BasicBlock *bb2, bb->out) {
if (bb2 && bb2->in.size() > 1) {
- qout << "found critical edge between block "
- << bb->index() << " and block " << bb2->index();
+ qDebug() << "found critical edge between block"
+ << bb->index() << "and block" << bb2->index();
Q_ASSERT(false);
}
}
@@ -3450,14 +3416,13 @@ void checkCriticalEdges(QVector<BasicBlock *> basicBlocks) {
void cleanupBasicBlocks(IR::Function *function)
{
- showMeTheCode(function);
+ showMeTheCode(function, "Before basic block cleanup");
// Algorithm: this is the iterative version of a depth-first search for all blocks that are
// reachable through outgoing edges, starting with the start block and all exception handler
// blocks.
QBitArray reachableBlocks(function->basicBlockCount());
- QVector<BasicBlock *> postponed;
- postponed.reserve(16);
+ QVarLengthArray<BasicBlock *, 16> postponed;
for (int i = 0, ei = function->basicBlockCount(); i != ei; ++i) {
BasicBlock *bb = function->basicBlock(i);
if (i == 0 || bb->isExceptionHandler())
@@ -3503,7 +3468,7 @@ void cleanupBasicBlocks(IR::Function *function)
function->removeBasicBlock(bb);
}
- showMeTheCode(function);
+ showMeTheCode(function, "After basic block cleanup");
}
inline Const *isConstPhi(Phi *phi)
@@ -3836,8 +3801,14 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
if (!showCode)
return;
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
+
struct Util {
- static void genLoop(LoopDetection::LoopInfo *loop)
+ QTextStream &qout;
+ Util(QTextStream &qout): qout(qout) {}
+ void genLoop(LoopDetection::LoopInfo *loop)
{
qout << " subgraph \"cluster" << quint64(loop) << "\" {\n";
qout << " L" << loop->loopHeader->index() << ";\n";
@@ -3856,7 +3827,7 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
foreach (LoopDetection::LoopInfo *l, loops) {
if (l->parentLoop == 0)
- Util::genLoop(l);
+ Util(qout).genLoop(l);
}
foreach (BasicBlock *bb, f->basicBlocks()) {
@@ -3874,7 +3845,8 @@ void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops =
qout << " L" << idx << " -> L" << out->index() << "\n";
}
- qout << "}\n" << flush;
+ qout << "}\n";
+ qDebug("%s", buf.data().constData());
}
} // anonymous namespace
@@ -4307,6 +4279,10 @@ public:
void dump() const
{
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream qout(&buf);
+
qout << "Life ranges:" << endl;
qout << "Intervals:" << endl;
foreach (const LifeTimeInterval *range, _sortedIntervals->intervals()) {
@@ -4327,6 +4303,7 @@ public:
}
qout << endl;
}
+ qDebug("%s", buf.data().constData());
}
private:
@@ -5074,12 +5051,7 @@ Optimizer::Optimizer(IR::Function *function)
void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool peelLoops)
{
-#if defined(SHOW_SSA)
- qout << "##### NOW IN FUNCTION " << (function->name ? qPrintable(*function->name) : "anonymous!")
- << " with " << function->basicBlocks.size() << " basic blocks." << endl << flush;
-#endif
-
-// showMeTheCode(function);
+ showMeTheCode(function, "Before running the optimizer");
cleanupBasicBlocks(function);
@@ -5093,7 +5065,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
// qout << "SSA for " << (function->name ? qPrintable(*function->name) : "<anonymous>") << endl;
ConvertArgLocals(function).toTemps();
- showMeTheCode(function);
+ showMeTheCode(function, "After converting arguments to locals");
// Calculate the dominator tree:
DominatorTree df(function);
@@ -5105,7 +5077,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
LoopDetection loopDetection(df);
loopDetection.run(function);
- showMeTheCode(function);
+ showMeTheCode(function, "After loop detection");
// cfg2dot(function, loopDetection.allLoops());
if (peelLoops) {
@@ -5113,7 +5085,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
LoopPeeling(df).run(innerLoops);
// cfg2dot(function, loopDetection.allLoops());
- showMeTheCode(function);
+ showMeTheCode(function, "After loop peeling");
if (!innerLoops.isEmpty())
verifyImmediateDominators(df, function);
}
@@ -5136,14 +5108,14 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
// qout << "Cleaning up phi nodes..." << endl;
cleanupPhis(defUses);
- showMeTheCode(function);
+ showMeTheCode(function, "After cleaning up phi-nodes");
StatementWorklist worklist(function);
if (doTypeInference) {
// qout << "Running type inference..." << endl;
TypeInference(qmlEngine, defUses).run(worklist);
- showMeTheCode(function);
+ showMeTheCode(function, "After type inference");
// qout << "Doing reverse inference..." << endl;
ReverseInference(defUses).run(function);
@@ -5160,7 +5132,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
// qout << "Running SSA optimization..." << endl;
worklist.reset();
optimizeSSA(worklist, defUses, df);
- showMeTheCode(function);
+ showMeTheCode(function, "After optimization");
verifyImmediateDominators(df, function);
verifyCFG(function);
@@ -5186,7 +5158,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee
// qout << "Doing block scheduling..." << endl;
// df.dumpImmediateDominators();
startEndLoops = BlockScheduler(function, df).go();
- showMeTheCode(function);
+ showMeTheCode(function, "After basic block scheduling");
// cfg2dot(function);
#ifndef QT_NO_DEBUG
@@ -5223,16 +5195,19 @@ void Optimizer::convertOutOfSSA() {
}
}
- #if defined(DEBUG_MOVEMAPPING)
- QTextStream os(stdout, QIODevice::WriteOnly);
- os << "Move mapping for function ";
- if (function->name)
- os << *function->name;
- else
- os << (void *) function;
- os << " on basic-block L" << bb->index << ":" << endl;
- moves.dump();
- #endif // DEBUG_MOVEMAPPING
+ if (DebugMoveMapping) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream os(&buf);
+ os << "Move mapping for function ";
+ if (function->name)
+ os << *function->name;
+ else
+ os << (void *) function;
+ os << " on basic-block L" << bb->index() << ":" << endl;
+ moves.dump();
+ qDebug("%s", buf.data().constData());
+ }
moves.order();
@@ -5288,22 +5263,12 @@ QSet<Jump *> Optimizer::calculateOptionalJumps()
reachableWithoutJump.insert(bb);
}
-#if 0
- QTextStream out(stdout, QIODevice::WriteOnly);
- out << "Jumps to ignore:" << endl;
- foreach (Jump *j, removed) {
- out << "\t" << j->id << ": ";
- j->dump(out, Stmt::MIR);
- out << endl;
- }
-#endif
-
return optional;
}
-void Optimizer::showMeTheCode(IR::Function *function)
+void Optimizer::showMeTheCode(IR::Function *function, const char *marker)
{
- ::showMeTheCode(function);
+ ::showMeTheCode(function, marker);
}
static inline bool overlappingStorage(const Temp &t1, const Temp &t2)
@@ -5345,14 +5310,17 @@ void MoveMapping::add(Expr *from, Temp *to) {
if (Temp *t = from->asTemp()) {
if (overlappingStorage(*t, *to)) {
// assignments like fp1 = fp1 or var{&1} = double{&1} can safely be skipped.
-#if defined(DEBUG_MOVEMAPPING)
- QTextStream os(stderr, QIODevice::WriteOnly);
- os << "Skipping ";
- to->dump(os);
- os << " <- ";
- from->dump(os);
- os << endl;
-#endif // DEBUG_MOVEMAPPING
+ if (DebugMoveMapping) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream os(&buf);
+ IRPrinter printer(&os);
+ os << "Skipping ";
+ printer.print(to);
+ os << " <- ";
+ printer.print(from);
+ qDebug("%s", buf.data().constData());
+ }
return;
}
}
@@ -5403,20 +5371,24 @@ QList<IR::Move *> MoveMapping::insertMoves(BasicBlock *bb, IR::Function *functio
void MoveMapping::dump() const
{
-#if defined(DEBUG_MOVEMAPPING)
- QTextStream os(stdout, QIODevice::WriteOnly);
- os << "Move mapping has " << _moves.size() << " moves..." << endl;
- foreach (const Move &m, _moves) {
- os << "\t";
- m.to->dump(os);
- if (m.needsSwap)
- os << " <-> ";
- else
- os << " <-- ";
- m.from->dump(os);
- os << endl;
+ if (DebugMoveMapping) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream os(&buf);
+ IRPrinter printer(&os);
+ os << "Move mapping has " << _moves.size() << " moves..." << endl;
+ foreach (const Move &m, _moves) {
+ os << "\t";
+ printer.print(m.to);
+ if (m.needsSwap)
+ os << " <-> ";
+ else
+ os << " <-- ";
+ printer.print(m.from);
+ os << endl;
+ }
+ qDebug("%s", buf.data().constData());
}
-#endif // DEBUG_MOVEMAPPING
}
MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed,
@@ -5427,19 +5399,24 @@ MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QLis
if (!output.contains(dependency)) {
if (delayed.contains(dependency)) {
// We have a cycle! Break it by swapping instead of assigning.
-#if defined(DEBUG_MOVEMAPPING)
- delayed+=m;
- QTextStream out(stderr, QIODevice::WriteOnly);
- out<<"we have a cycle! temps:" << endl;
- foreach (const Move &m, delayed) {
- out<<"\t";
- m.to->dump(out);
- out<<" <- ";
- m.from->dump(out);
- out<<endl;
+ if (DebugMoveMapping) {
+ delayed += m;
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream out(&buf);
+ IRPrinter printer(&out);
+ out<<"we have a cycle! temps:" << endl;
+ foreach (const Move &m, delayed) {
+ out<<"\t";
+ printer.print(m.to);
+ out<<" <- ";
+ printer.print(m.from);
+ out<<endl;
+ }
+ qDebug("%s", buf.data().constData());
+ delayed.removeOne(m);
}
- delayed.removeOne(m);
-#endif // DEBUG_MOVEMAPPING
+
return NeedsSwap;
} else {
delayed.append(m);