nv50/ir: use unordered_set instead of list to keep track of var uses
authorTobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Tue, 8 Jul 2014 02:19:13 +0000 (04:19 +0200)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 8 Jul 2014 23:41:00 +0000 (19:41 -0400)
The set of variable uses does not need to be ordered in any way, and
removing/adding elements is a fairly common operation in various
optimization passes.

This shortens runtime of piglit test fp-long-alu to ~22s from ~4h

Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir.h
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp

index 13f8cf20c7665a6cf88ce15b9d6876de828ba320..ca3c806e92f82fff87ad9ab8233c7cee4c415f6d 100644 (file)
@@ -141,9 +141,9 @@ ValueRef::set(Value *refVal)
    if (value == refVal)
       return;
    if (value)
-      value->uses.remove(this);
+      value->uses.erase(this);
    if (refVal)
-      refVal->uses.push_back(this);
+      refVal->uses.insert(this);
 
    value = refVal;
 }
@@ -206,7 +206,7 @@ ValueDef::replace(const ValueRef &repVal, bool doSet)
       return;
 
    while (!value->uses.empty()) {
-      ValueRef *ref = value->uses.front();
+      ValueRef *ref = *value->uses.begin();
       ref->set(repVal.get());
       ref->mod *= repVal.mod;
    }
index 88440309e6b5ddc05fbcb0606a408a3abe5aaee1..0ff5e5dc3b2f2d20f039aa02e0ca714b46e8c852 100644 (file)
@@ -29,6 +29,7 @@
 #include <deque>
 #include <list>
 #include <vector>
+#include <tr1/unordered_set>
 
 #include "codegen/nv50_ir_util.h"
 #include "codegen/nv50_ir_graph.h"
@@ -581,10 +582,10 @@ public:
 
    static inline Value *get(Iterator&);
 
-   std::list<ValueRef *> uses;
+   std::tr1::unordered_set<ValueRef *> uses;
    std::list<ValueDef *> defs;
-   typedef std::list<ValueRef *>::iterator UseIterator;
-   typedef std::list<ValueRef *>::const_iterator UseCIterator;
+   typedef std::tr1::unordered_set<ValueRef *>::iterator UseIterator;
+   typedef std::tr1::unordered_set<ValueRef *>::const_iterator UseCIterator;
    typedef std::list<ValueDef *>::iterator DefIterator;
    typedef std::list<ValueDef *>::const_iterator DefCIterator;
 
index b89da43136e2c3553d76eb7a4c43c164b4b21500..1a9a25fa7ec4e1ef6dad297989a50e4c98974fb3 100644 (file)
@@ -686,7 +686,7 @@ ConstantFolding::tryCollapseChainedMULs(Instruction *mul2,
       // b = mul a, imm
       // d = mul b, c   -> d = mul_x_imm a, c
       int s2, t2;
-      insn = mul2->getDef(0)->uses.front()->getInsn();
+      insn = (*mul2->getDef(0)->uses.begin())->getInsn();
       if (!insn)
          return;
       mul1 = mul2;
index e4f56b140da008b4d5d5bc7c9a1663cd338420d0..6c83a60823404b729ecf4034d33f092ecdf10131 100644 (file)
@@ -983,7 +983,7 @@ GCRA::doCoalesce(ArrayList& insns, unsigned int mask)
             break;
          i = NULL;
          if (!insn->getDef(0)->uses.empty())
-            i = insn->getDef(0)->uses.front()->getInsn();
+            i = (*insn->getDef(0)->uses.begin())->getInsn();
          // if this is a contraint-move there will only be a single use
          if (i && i->op == OP_MERGE) // do we really still need this ?
             break;
@@ -1559,7 +1559,7 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
          // Unspill at each use *before* inserting spill instructions,
          // we don't want to have the spill instructions in the use list here.
          while (!dval->uses.empty()) {
-            ValueRef *u = dval->uses.front();
+            ValueRef *u = *dval->uses.begin();
             Instruction *usei = u->getInsn();
             assert(usei);
             if (usei->isPseudo()) {