nv50/ir/opt: make optimization aware of atomics, barriers, surface ops
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 20 Feb 2013 20:03:30 +0000 (21:03 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 12 Mar 2013 11:55:34 +0000 (12:55 +0100)
src/gallium/drivers/nv50/codegen/nv50_ir_inlines.h
src/gallium/drivers/nv50/codegen/nv50_ir_peephole.cpp

index 7ec22b55e66074e7ebe35ecaebae6dce1d5f06e8..43d5fc1e5b0b87b018453afdee2c05646ffb3b3b 100644 (file)
@@ -46,6 +46,11 @@ static inline bool isTextureOp(operation op)
    return (op >= OP_TEX && op <= OP_TEXPREP);
 }
 
+static inline bool isSurfaceOp(operation op)
+{
+   return (op >= OP_SULDB && op <= OP_SULEA);
+}
+
 static inline unsigned int typeSizeof(DataType ty)
 {
    switch (ty) {
index 19d1c369a3fb72f0bd96184c0a9ae28e64910a5d..6b3e5be3a78ab6216eb8123af6aa3e06d4d796d6 100644 (file)
@@ -37,6 +37,8 @@ Instruction::isNop() const
       return true;
    if (terminator || join) // XXX: should terminator imply flow ?
       return false;
+   if (op == OP_ATOM)
+      return false;
    if (!fixed && op == OP_NOP)
       return true;
 
@@ -63,6 +65,8 @@ bool Instruction::isDead() const
 {
    if (op == OP_STORE ||
        op == OP_EXPORT ||
+       op == OP_ATOM ||
+       op == OP_SUSTB || op == OP_SUSTP || op == OP_SUREDP || op == OP_SUREDB ||
        op == OP_WRSV)
       return false;
 
@@ -1727,12 +1731,23 @@ MemoryOpt::runOpt(BasicBlock *bb)
          isLoad = false;
       } else {
          // TODO: maybe have all fixed ops act as barrier ?
-         if (ldst->op == OP_CALL) {
+         if (ldst->op == OP_CALL ||
+             ldst->op == OP_BAR ||
+             ldst->op == OP_MEMBAR) {
             purgeRecords(NULL, FILE_MEMORY_LOCAL);
             purgeRecords(NULL, FILE_MEMORY_GLOBAL);
             purgeRecords(NULL, FILE_MEMORY_SHARED);
             purgeRecords(NULL, FILE_SHADER_OUTPUT);
          } else
+         if (ldst->op == OP_ATOM) {
+            if (ldst->src(0).getFile() == FILE_MEMORY_GLOBAL) {
+               purgeRecords(NULL, FILE_MEMORY_LOCAL);
+               purgeRecords(NULL, FILE_MEMORY_GLOBAL);
+               purgeRecords(NULL, FILE_MEMORY_SHARED);
+            } else {
+               purgeRecords(NULL, ldst->src(0).getFile());
+            }
+         } else
          if (ldst->op == OP_EMIT || ldst->op == OP_RESTART) {
             purgeRecords(NULL, FILE_SHADER_OUTPUT);
          }
@@ -1941,6 +1956,7 @@ FlatteningPass::visit(BasicBlock *bb)
           !insn->asFlow() &&
           insn->op != OP_TEXBAR &&
           !isTextureOp(insn->op) && // probably just nve4
+          !isSurfaceOp(insn->op) && // not confirmed
           insn->op != OP_LINTERP && // probably just nve4
           insn->op != OP_PINTERP && // probably just nve4
           ((insn->op != OP_LOAD && insn->op != OP_STORE) ||
@@ -2286,6 +2302,12 @@ DeadCodeElim::visit(BasicBlock *bb)
       } else
       if (i->defExists(1) && (i->op == OP_VFETCH || i->op == OP_LOAD)) {
          checkSplitLoad(i);
+      } else
+      if (i->defExists(0) && !i->getDef(0)->refCount()) {
+         if (i->op == OP_ATOM ||
+             i->op == OP_SUREDP ||
+             i->op == OP_SUREDB)
+            i->setDef(0, NULL);
       }
    }
    return true;