[Mesa-dev] [PATCH] nv50/ir: check if the target supports the new offset before inlining
Ilia Mirkin
imirkin at alum.mit.edu
Tue Dec 8 13:56:54 PST 2015
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=93300
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp | 9 ++++++---
src/gallium/drivers/nouveau/codegen/nv50_ir_target.h | 2 ++
.../drivers/nouveau/codegen/nv50_ir_target_nv50.cpp | 15 +++++++++++++++
src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h | 2 ++
4 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
index 1384a25..7b7352e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp
@@ -290,20 +290,23 @@ IndirectPropagation::visit(BasicBlock *bb)
continue;
if (insn->op == OP_ADD && !isFloatType(insn->dType)) {
if (insn->src(0).getFile() != targ->nativeFile(FILE_ADDRESS) ||
- !insn->src(1).getImmediate(imm))
+ !insn->src(1).getImmediate(imm) ||
+ !targ->insnCanLoadOffset(i, s, imm.reg.data.s32))
continue;
i->setIndirect(s, 0, insn->getSrc(0));
i->setSrc(s, cloneShallow(func, i->getSrc(s)));
i->src(s).get()->reg.data.offset += imm.reg.data.u32;
} else if (insn->op == OP_SUB && !isFloatType(insn->dType)) {
if (insn->src(0).getFile() != targ->nativeFile(FILE_ADDRESS) ||
- !insn->src(1).getImmediate(imm))
+ !insn->src(1).getImmediate(imm) ||
+ !targ->insnCanLoadOffset(i, s, -imm.reg.data.s32))
continue;
i->setIndirect(s, 0, insn->getSrc(0));
i->setSrc(s, cloneShallow(func, i->getSrc(s)));
i->src(s).get()->reg.data.offset -= imm.reg.data.u32;
} else if (insn->op == OP_MOV) {
- if (!insn->src(0).getImmediate(imm))
+ if (!insn->src(0).getImmediate(imm) ||
+ !targ->insnCanLoadOffset(i, s, imm.reg.data.s32))
continue;
i->setIndirect(s, 0, NULL);
i->setSrc(s, cloneShallow(func, i->getSrc(s)));
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
index 4e33997..673f881 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
@@ -191,6 +191,8 @@ public:
virtual bool insnCanLoad(const Instruction *insn, int s,
const Instruction *ld) const = 0;
+ virtual bool insnCanLoadOffset(const Instruction *insn, int s,
+ int offset) const { return true; }
virtual bool isOpSupported(operation, DataType) const = 0;
virtual bool isAccessSupported(DataFile, DataType) const = 0;
virtual bool isModSupported(const Instruction *,
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
index 2d5baed..101082e 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.cpp
@@ -385,6 +385,21 @@ TargetNV50::insnCanLoad(const Instruction *i, int s,
}
bool
+TargetNV50::insnCanLoadOffset(const Instruction *i, int s, int offset) const
+{
+ if (!i->src(s).isIndirect(0))
+ return true;
+ offset += i->src(s).get()->reg.data.offset;
+ if (i->op == OP_LOAD || i->op == OP_STORE) {
+ // There are some restrictions in theory, but in practice they're never
+ // going to be hit. When we enable shared/global memory, this will
+ // become more important.
+ return true;
+ }
+ return offset >= 0 && offset <= (int32_t)(127 * i->src(s).get()->reg.size);
+}
+
+bool
TargetNV50::isAccessSupported(DataFile file, DataType ty) const
{
if (ty == TYPE_B96 || ty == TYPE_NONE)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h
index 0cbf180..00243d7 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nv50.h
@@ -46,6 +46,8 @@ public:
virtual bool insnCanLoad(const Instruction *insn, int s,
const Instruction *ld) const;
+ virtual bool insnCanLoadOffset(const Instruction *insn, int s,
+ int offset) const;
virtual bool isOpSupported(operation, DataType) const;
virtual bool isAccessSupported(DataFile, DataType) const;
virtual bool isModSupported(const Instruction *, int s, Modifier) const;
--
2.4.10
More information about the mesa-dev
mailing list