Previously, findFirstUse() only considered reads "uses". This fixes that by making it check both an instruction's sources and definitions. It also shortens both findFistUse() and findFirstDef() along the way.
--- .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 103 ++++++++++----------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp index 1f6189890c..c942db3ec9 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -3618,6 +3618,7 @@ private: bool insertBarriers(BasicBlock *); + bool doesInsnWriteTo(const Instruction *insn, const Value *val) const; Instruction *findFirstUse(const Instruction *) const; Instruction *findFirstDef(const Instruction *) const; @@ -3948,8 +3949,43 @@ SchedDataCalculatorGM107::needWrDepBar(const Instruction *insn) const return false; } -// Find the next instruction inside the same basic block which uses the output -// of the given instruction in order to avoid RaW hazards. +// Helper function for findFirstUse() and findFirstDef() +bool +SchedDataCalculatorGM107::doesInsnWriteTo(const Instruction *insn, + const Value *val) const +{ + for (int d = 0; insn->defExists(d); ++d) { + const Value* def = insn->getDef(d); + int minGPR = def->reg.data.id; + int maxGPR = minGPR + def->reg.size / 4 - 1; + + if (def->reg.file == FILE_GPR) { + if (val->reg.file != FILE_GPR || + val->reg.data.id + val->reg.size / 4 - 1 < minGPR || + val->reg.data.id > maxGPR) + continue; + return true; + } else + if (def->reg.file == FILE_PREDICATE) { + if (val->reg.file != FILE_PREDICATE || + val->reg.data.id != minGPR) + continue; + return true; + } else + if (def->reg.file == FILE_FLAGS) { + if (val->reg.file != FILE_FLAGS || + val->reg.data.id != minGPR) + continue; + return true; + } + } + + return false; +} + +// Find the next instruction inside the same basic block which uses (reads or +// writes from) the output of the given instruction in order to avoid RaW and +// WaW hazards. Instruction * SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const { @@ -3961,34 +3997,13 @@ SchedDataCalculatorGM107::findFirstUse(const Instruction *bari) const for (insn = bari->next; insn != NULL; insn = next) { next = insn->next; - for (int s = 0; insn->srcExists(s); ++s) { - const Value *src = insn->src(s).rep(); - for (int d = 0; bari->defExists(d); ++d) { - const ValueDef &def = bari->def(d); - int minGPR = def.rep()->reg.data.id; - int maxGPR = minGPR + def.rep()->reg.size / 4 - 1; - - if (def.getFile() == FILE_GPR) { - if (insn->src(s).getFile() != FILE_GPR || - src->reg.data.id + src->reg.size / 4 - 1 < minGPR || - src->reg.data.id > maxGPR) - continue; - return insn; - } else - if (def.getFile() == FILE_PREDICATE) { - if (insn->src(s).getFile() != FILE_PREDICATE || - src->reg.data.id != minGPR) - continue; - return insn; - } - if (def.getFile() == FILE_FLAGS) { - if (insn->src(s).getFile() != FILE_FLAGS || - src->reg.data.id != minGPR) - continue; - return insn; - } - } - } + for (int s = 0; insn->srcExists(s); ++s) + if (doesInsnWriteTo(bari, insn->getSrc(s))) + return insn; + + for (int d = 0; insn->defExists(d); ++d) + if (doesInsnWriteTo(bari, insn->getDef(d))) + return insn; } return NULL; } @@ -3999,34 +4014,16 @@ Instruction * SchedDataCalculatorGM107::findFirstDef(const Instruction *bari) const { Instruction *insn, *next; - int minGPR, maxGPR; + + if (!bari->srcExists(0)) + return NULL; for (insn = bari->next; insn != NULL; insn = next) { next = insn->next; - for (int d = 0; insn->defExists(d); ++d) { - const Value *def = insn->def(d).rep(); - if (insn->def(d).getFile() != FILE_GPR && - insn->def(d).getFile() != FILE_FLAGS) - continue; - - minGPR = def->reg.data.id; - maxGPR = minGPR + def->reg.size / 4 - 1; - - for (int s = 0; bari->srcExists(s); ++s) { - const Value *src = bari->src(s).rep(); - if (bari->src(s).getFile() == FILE_FLAGS && - insn->def(d).getFile() == FILE_FLAGS && - src->reg.data.id == minGPR) - return insn; - if (bari->src(s).getFile() != FILE_GPR || - insn->def(d).getFile() != FILE_GPR || - src->reg.data.id + src->reg.size / 4 - 1 < minGPR || - src->reg.data.id > maxGPR) - continue; + for (int s = 0; bari->srcExists(s); ++s) + if (doesInsnWriteTo(insn, bari->getSrc(s))) return insn; - } - } } return NULL; } -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev