[Mesa-dev] [PATCH v3 09/12] nvc0/ir: add atomics support on shared memory for Kepler

Ilia Mirkin imirkin at alum.mit.edu
Fri Apr 1 17:24:35 UTC 2016


On Fri, Apr 1, 2016 at 12:56 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
>  .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      | 114 ++++++++++++++++++++-
>  .../nouveau/codegen/nv50_ir_lowering_nvc0.h        |   1 +
>  2 files changed, 114 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
> index 5a08fc7..26fc27f 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
> @@ -1081,6 +1081,114 @@ NVC0LoweringPass::handleSUQ(Instruction *suq)
>  }
>
>  void
> +NVC0LoweringPass::handleSharedATOMNVE4(Instruction *atom)
> +{
> +   assert(atom->src(0).getFile() == FILE_MEMORY_SHARED);
> +
> +   BasicBlock *currBB = atom->bb;
> +   BasicBlock *tryLockBB = atom->bb->splitBefore(atom, false);
> +   BasicBlock *joinBB = atom->bb->splitAfter(atom);
> +   BasicBlock *setAndUnlockBB = new BasicBlock(func);
> +   BasicBlock *failLockBB = new BasicBlock(func);
> +
> +   bld.setPosition(currBB, true);
> +   assert(!currBB->joinAt);
> +   currBB->joinAt = bld.mkFlow(OP_JOINAT, joinBB, CC_ALWAYS, NULL);
> +
> +   CmpInstruction *pred =
> +      bld.mkCmp(OP_SET, CC_EQ, TYPE_U32, bld.getSSA(1, FILE_PREDICATE),
> +                TYPE_U32, bld.mkImm(0), bld.mkImm(1));
> +
> +   bld.mkFlow(OP_BRA, tryLockBB, CC_ALWAYS, NULL);
> +   currBB->cfg.attach(&tryLockBB->cfg, Graph::Edge::TREE);
> +
> +   bld.setPosition(tryLockBB, true);
> +
> +   Instruction *ld =
> +      bld.mkLoad(TYPE_U32, atom->getDef(0),
> +                 bld.mkSymbol(FILE_MEMORY_SHARED, 0, TYPE_U32, 0), NULL);
> +   ld->setDef(1, bld.getSSA(1, FILE_PREDICATE));
> +   ld->subOp = NV50_IR_SUBOP_LOAD_LOCKED;
> +
> +   bld.mkFlow(OP_BRA, setAndUnlockBB, CC_P, ld->getDef(1));
> +   bld.mkFlow(OP_BRA, failLockBB, CC_ALWAYS, NULL);
> +   tryLockBB->cfg.attach(&failLockBB->cfg, Graph::Edge::CROSS);
> +   tryLockBB->cfg.attach(&setAndUnlockBB->cfg, Graph::Edge::TREE);
> +
> +   tryLockBB->cfg.detach(&joinBB->cfg);
> +   bld.remove(atom);
> +
> +   bld.setPosition(setAndUnlockBB, true);
> +   Value *stVal;
> +   if (atom->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
> +      // Read the old value, and write the new one.
> +      stVal = atom->getSrc(1);
> +   } else if (atom->subOp == NV50_IR_SUBOP_ATOM_CAS) {
> +      CmpInstruction *set =
> +         bld.mkCmp(OP_SET, CC_EQ, TYPE_U32, bld.getSSA(),
> +                   TYPE_U32, ld->getDef(0), atom->getSrc(1));
> +
> +      CmpInstruction *slct =
> +         bld.mkCmp(OP_SLCT, CC_NE, TYPE_U32, bld.getSSA(),
> +                   TYPE_U32, atom->getSrc(2), ld->getDef(0), set->getDef(0));

Up to you, but a common way of doing this elsewhere is

bld.mkCmp(..., (stVal = bld.getSSA()), ...)

And then you don't need the getDef().

> +
> +      stVal = slct->getDef(0);
> +   } else {
> +      operation op;
> +
> +      switch (atom->subOp) {
> +      case NV50_IR_SUBOP_ATOM_ADD:
> +         op = OP_ADD;
> +         break;
> +      case NV50_IR_SUBOP_ATOM_AND:
> +         op = OP_AND;
> +         break;
> +      case NV50_IR_SUBOP_ATOM_OR:
> +         op = OP_OR;
> +         break;
> +      case NV50_IR_SUBOP_ATOM_XOR:
> +         op = OP_XOR;
> +         break;
> +      case NV50_IR_SUBOP_ATOM_MIN:
> +         op = OP_MIN;
> +         break;
> +      case NV50_IR_SUBOP_ATOM_MAX:
> +         op = OP_MAX;
> +         break;
> +      default:
> +         assert(0);
> +         return;
> +      }
> +
> +      Instruction *i =
> +         bld.mkOp2(op, atom->dType, bld.getSSA(), ld->getDef(0),
> +                   atom->getSrc(1));
> +
> +      stVal = i->getDef(0);

Or just do bld.mkOp2v, which returns the value (and no need for the
Instruction var).

Either way,

Reviewed-by: Ilia Mirkin <imirkin at alum.mit.edu>

> +   }
> +
> +   Instruction *st =
> +      bld.mkStore(OP_STORE, TYPE_U32,
> +                  bld.mkSymbol(FILE_MEMORY_SHARED, 0, TYPE_U32, 0),
> +                  NULL, stVal);
> +   st->setDef(0, pred->getDef(0));
> +   st->subOp = NV50_IR_SUBOP_STORE_UNLOCKED;
> +
> +   bld.mkFlow(OP_BRA, failLockBB, CC_ALWAYS, NULL);
> +   setAndUnlockBB->cfg.attach(&failLockBB->cfg, Graph::Edge::TREE);
> +
> +   // Lock until the store has not been performed.
> +   bld.setPosition(failLockBB, true);
> +   bld.mkFlow(OP_BRA, tryLockBB, CC_NOT_P, pred->getDef(0));
> +   bld.mkFlow(OP_BRA, joinBB, CC_ALWAYS, NULL);
> +   failLockBB->cfg.attach(&tryLockBB->cfg, Graph::Edge::BACK);
> +   failLockBB->cfg.attach(&joinBB->cfg, Graph::Edge::TREE);
> +
> +   bld.setPosition(joinBB, false);
> +   bld.mkFlow(OP_JOIN, NULL, CC_ALWAYS, NULL)->fixed = 1;
> +}
> +
> +void
>  NVC0LoweringPass::handleSharedATOM(Instruction *atom)
>  {
>     assert(atom->src(0).getFile() == FILE_MEMORY_SHARED);
> @@ -1186,7 +1294,11 @@ NVC0LoweringPass::handleATOM(Instruction *atom)
>        sv = SV_LBASE;
>        break;
>     case FILE_MEMORY_SHARED:
> -      handleSharedATOM(atom);
> +      if (targ->getChipset() >= NVISA_GK104_CHIPSET) {
> +         handleSharedATOMNVE4(atom);
> +      } else {
> +         handleSharedATOM(atom);
> +      }
>        return true;
>     default:
>        assert(atom->src(0).getFile() == FILE_MEMORY_GLOBAL);
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
> index aa19249..d5c2cb5 100644
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
> @@ -106,6 +106,7 @@ protected:
>     bool handleCasExch(Instruction *, bool needCctl);
>     void handleSurfaceOpNVE4(TexInstruction *);
>     void handleSharedATOM(Instruction *);
> +   void handleSharedATOMNVE4(Instruction *);
>     void handleLDST(Instruction *);
>
>     void checkPredicate(Instruction *);
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list