SPV: Correct SPIR-V operands for <id> versus immediate.
authorJohn Kessenich <cepheus@frii.com>
Tue, 14 Aug 2018 03:37:59 +0000 (21:37 -0600)
committerJohn Kessenich <cepheus@frii.com>
Tue, 14 Aug 2018 03:37:59 +0000 (21:37 -0600)
SPIRV/SpvBuilder.cpp
SPIRV/SpvPostProcess.cpp
SPIRV/spvIR.h

index 852a3e3ff81645d613f2bc69f44d0da73023709f..c20641c6c926d55e0f9aec3b7d65bedd11312f18 100755 (executable)
@@ -509,7 +509,7 @@ Id Builder::getDerefTypeId(Id resultId) const
     Id typeId = getTypeId(resultId);
     assert(isPointerType(typeId));
 
-    return module.getInstruction(typeId)->getImmediateOperand(1);
+    return module.getInstruction(typeId)->getIdOperand(1);
 }
 
 Op Builder::getMostBasicTypeClass(Id typeId) const
@@ -553,7 +553,7 @@ int Builder::getNumTypeConstituents(Id typeId) const
         return instr->getImmediateOperand(1);
     case OpTypeArray:
     {
-        Id lengthId = instr->getImmediateOperand(1);
+        Id lengthId = instr->getIdOperand(1);
         return module.getInstruction(lengthId)->getImmediateOperand(0);
     }
     case OpTypeStruct:
@@ -1351,17 +1351,17 @@ void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
 void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)
 {
     Instruction* op = new Instruction(OpControlBarrier);
-    op->addImmediateOperand(makeUintConstant(execution));
-    op->addImmediateOperand(makeUintConstant(memory));
-    op->addImmediateOperand(makeUintConstant(semantics));
+    op->addIdOperand(makeUintConstant(execution));
+    op->addIdOperand(makeUintConstant(memory));
+    op->addIdOperand(makeUintConstant(semantics));
     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
 }
 
 void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics)
 {
     Instruction* op = new Instruction(OpMemoryBarrier);
-    op->addImmediateOperand(makeUintConstant(executionScope));
-    op->addImmediateOperand(makeUintConstant(memorySemantics));
+    op->addIdOperand(makeUintConstant(executionScope));
+    op->addIdOperand(makeUintConstant(memorySemantics));
     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
 }
 
@@ -2026,7 +2026,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
     int numRows = getTypeNumRows(resultTypeId);
 
     Instruction* instr = module.getInstruction(componentTypeId);
-    Id bitCount = instr->getIdOperand(0);
+    unsigned bitCount = instr->getImmediateOperand(0);
 
     // Optimize matrix constructed from a bigger matrix
     if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
index 256079997ff92b0320eebbf6c2e7522c774aed9f..df6ba81729fbef7f46efa8b3909943f6783aa974 100755 (executable)
@@ -61,13 +61,13 @@ namespace spv {
 
 namespace spv {
 
-// Called for each instruction in a block.
+// Called for each instruction that resides in a block.
 void Builder::postProcess(Instruction& inst)
 {
     // Add capabilities based simply on the opcode.
     switch (inst.getOpCode()) {
     case OpExtInst:
-        switch (inst.getIdOperand(1)) {
+        switch (inst.getImmediateOperand(1)) {
         case GLSLstd450InterpolateAtCentroid:
         case GLSLstd450InterpolateAtSample:
         case GLSLstd450InterpolateAtOffset:
index 8b6c6447f466d020930193da7d68461fef90e10b..c126b4f6c27ca14ccc1cddcf2d99cc5efa42ce13 100755 (executable)
@@ -88,8 +88,14 @@ public:
     Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
     explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
     virtual ~Instruction() {}
-    void addIdOperand(Id id) { operands.push_back(id); }
-    void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
+    void addIdOperand(Id id) {
+        operands.push_back(id);
+        idOperand.push_back(true);
+    }
+    void addImmediateOperand(unsigned int immediate) {
+        operands.push_back(immediate);
+        idOperand.push_back(false);
+    }
     void addStringOperand(const char* str)
     {
         unsigned int word;
@@ -116,14 +122,25 @@ public:
             addImmediateOperand(word);
         }
     }
+    bool isIdOperand(int op) { return idOperand[op]; }
     void setBlock(Block* b) { block = b; }
     Block* getBlock() const { return block; }
     Op getOpCode() const { return opCode; }
-    int getNumOperands() const { return (int)operands.size(); }
+    int getNumOperands() const
+    {
+        assert(operands.size() == idOperand.size());
+        return (int)operands.size();
+    }
     Id getResultId() const { return resultId; }
     Id getTypeId() const { return typeId; }
-    Id getIdOperand(int op) const { return operands[op]; }
-    unsigned int getImmediateOperand(int op) const { return operands[op]; }
+    Id getIdOperand(int op) const {
+        assert(idOperand[op]);
+        return operands[op];
+    }
+    unsigned int getImmediateOperand(int op) const {
+        assert(!idOperand[op]);
+        return operands[op];
+    }
 
     // Write out the binary form.
     void dump(std::vector<unsigned int>& out) const
@@ -153,7 +170,8 @@ protected:
     Id resultId;
     Id typeId;
     Op opCode;
-    std::vector<Id> operands;
+    std::vector<Id> operands;     // operands, both <id> and immediates (both are unsigned int)
+    std::vector<bool> idOperand;  // true for operands that are <id>, false for immediates
     Block* block;
 };