@@ -111,11 +111,7 @@ class SpirvInstruction {
111111
112112 IK_SetMeshOutputsEXT, // OpSetMeshOutputsEXT
113113
114- // The following section is for group non-uniform instructions.
115- // Used by LLVM-style RTTI; order matters.
116- IK_GroupNonUniformBinaryOp, // Group non-uniform binary operations
117- IK_GroupNonUniformElect, // OpGroupNonUniformElect
118- IK_GroupNonUniformUnaryOp, // Group non-uniform unary operations
114+ IK_GroupNonUniformOp, // Group non-uniform operations
119115
120116 IK_ImageOp, // OpImage*
121117 IK_ImageQuery, // OpImageQuery*
@@ -1495,102 +1491,43 @@ class SpirvFunctionCall : public SpirvInstruction {
14951491 llvm::SmallVector<SpirvInstruction *, 4 > args;
14961492};
14971493
1498- // / \brief Base for OpGroupNonUniform* instructions
1494+ // / \brief OpGroupNonUniform* instructions
14991495class SpirvGroupNonUniformOp : public SpirvInstruction {
15001496public:
1501- // For LLVM-style RTTI
1502- static bool classof (const SpirvInstruction *inst) {
1503- return inst->getKind () >= IK_GroupNonUniformBinaryOp &&
1504- inst->getKind () <= IK_GroupNonUniformUnaryOp;
1505- }
1506-
1507- spv::Scope getExecutionScope () const { return execScope; }
1508-
1509- protected:
1510- SpirvGroupNonUniformOp (Kind kind, spv::Op opcode, QualType resultType,
1511- SourceLocation loc, spv::Scope scope);
1512-
1513- private:
1514- spv::Scope execScope;
1515- };
1516-
1517- // / \brief OpGroupNonUniform* binary instructions.
1518- class SpirvNonUniformBinaryOp : public SpirvGroupNonUniformOp {
1519- public:
1520- SpirvNonUniformBinaryOp (spv::Op opcode, QualType resultType,
1521- SourceLocation loc, spv::Scope scope,
1522- SpirvInstruction *arg1, SpirvInstruction *arg2);
1523-
1524- DEFINE_RELEASE_MEMORY_FOR_CLASS (SpirvNonUniformBinaryOp)
1525-
1526- // For LLVM-style RTTI
1527- static bool classof (const SpirvInstruction *inst) {
1528- return inst->getKind () == IK_GroupNonUniformBinaryOp;
1529- }
1530-
1531- bool invokeVisitor (Visitor *v) override ;
1532-
1533- SpirvInstruction *getArg1 () const { return arg1; }
1534- SpirvInstruction *getArg2 () const { return arg2; }
1535- void replaceOperand (
1536- llvm::function_ref<SpirvInstruction *(SpirvInstruction *)> remapOp,
1537- bool inEntryFunctionWrapper) override {
1538- arg1 = remapOp (arg1);
1539- arg2 = remapOp (arg2);
1540- }
1541-
1542- private:
1543- SpirvInstruction *arg1;
1544- SpirvInstruction *arg2;
1545- };
1546-
1547- // / \brief OpGroupNonUniformElect instruction. This is currently the only
1548- // / non-uniform instruction that takes no other arguments.
1549- class SpirvNonUniformElect : public SpirvGroupNonUniformOp {
1550- public:
1551- SpirvNonUniformElect (QualType resultType, SourceLocation loc,
1552- spv::Scope scope);
1497+ SpirvGroupNonUniformOp (spv::Op opcode, QualType resultType, spv::Scope scope,
1498+ llvm::ArrayRef<SpirvInstruction *> operands,
1499+ SourceLocation loc,
1500+ llvm::Optional<spv::GroupOperation> group);
15531501
1554- DEFINE_RELEASE_MEMORY_FOR_CLASS (SpirvNonUniformElect )
1502+ DEFINE_RELEASE_MEMORY_FOR_CLASS (SpirvGroupNonUniformOp )
15551503
15561504 // For LLVM-style RTTI
15571505 static bool classof (const SpirvInstruction *inst) {
1558- return inst->getKind () == IK_GroupNonUniformElect ;
1506+ return inst->getKind () == IK_GroupNonUniformOp ;
15591507 }
15601508
15611509 bool invokeVisitor (Visitor *v) override ;
1562- };
1563-
1564- // / \brief OpGroupNonUniform* unary instructions.
1565- class SpirvNonUniformUnaryOp : public SpirvGroupNonUniformOp {
1566- public:
1567- SpirvNonUniformUnaryOp (spv::Op opcode, QualType resultType,
1568- SourceLocation loc, spv::Scope scope,
1569- llvm::Optional<spv::GroupOperation> group,
1570- SpirvInstruction *arg);
1571-
1572- DEFINE_RELEASE_MEMORY_FOR_CLASS (SpirvNonUniformUnaryOp)
15731510
1574- // For LLVM-style RTTI
1575- static bool classof (const SpirvInstruction *inst) {
1576- return inst->getKind () == IK_GroupNonUniformUnaryOp;
1577- }
1511+ spv::Scope getExecutionScope () const { return execScope; }
15781512
1579- bool invokeVisitor (Visitor *v) override ;
1513+ llvm::ArrayRef<SpirvInstruction *> getOperands () const { return operands; }
15801514
1581- SpirvInstruction *getArg () const { return arg; }
15821515 bool hasGroupOp () const { return groupOp.hasValue (); }
15831516 spv::GroupOperation getGroupOp () const { return groupOp.getValue (); }
1517+
15841518 void replaceOperand (
15851519 llvm::function_ref<SpirvInstruction *(SpirvInstruction *)> remapOp,
15861520 bool inEntryFunctionWrapper) override {
1587- arg = remapOp (arg);
1521+ for (auto *operand : getOperands ()) {
1522+ operand = remapOp (operand);
1523+ }
15881524 if (inEntryFunctionWrapper)
1589- setAstResultType (arg ->getAstResultType ());
1525+ setAstResultType (getOperands ()[ 0 ] ->getAstResultType ());
15901526 }
15911527
15921528private:
1593- SpirvInstruction *arg;
1529+ spv::Scope execScope;
1530+ llvm::SmallVector<SpirvInstruction *, 4 > operands;
15941531 llvm::Optional<spv::GroupOperation> groupOp;
15951532};
15961533
0 commit comments