Skip to content

Commit 5b64163

Browse files
authored
Improve decoding of constant composites (#885)
* Improve decoding of constant composites Signed-off-by: Alexey Sotkin <alexey.sotkin@intel.com>
1 parent bec81d1 commit 5b64163

File tree

4 files changed

+31
-24
lines changed

4 files changed

+31
-24
lines changed

lib/SPIRV/libSPIRV/SPIRVStream.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,4 +296,29 @@ spv_ostream &operator<<(spv_ostream &O, const SPIRVNL &E) {
296296
return O;
297297
}
298298

299+
// Read the next word from the stream and if OpCode matches the argument,
300+
// decode the whole instruction. Multiple such instructions are possible. If
301+
// OpCode doesn't match the argument, set position of the next character to be
302+
// extracted from the stream to the beginning of the non-matching instruction.
303+
// Returns vector of extracted instructions.
304+
// Used to decode SPIRVTypeStructContinuedINTEL,
305+
// SPIRVConstantCompositeContinuedINTEL and
306+
// SPIRVSpecConstantCompositeContinuedINTEL.
307+
std::vector<SPIRVEntry *>
308+
SPIRVDecoder::getContinuedInstructions(const spv::Op ContinuedOpCode) {
309+
std::vector<SPIRVEntry *> ContinuedInst;
310+
std::streampos Pos = IS.tellg(); // remember position
311+
getWordCountAndOpCode();
312+
while (OpCode == ContinuedOpCode) {
313+
SPIRVEntry *Entry = getEntry();
314+
assert(Entry && "Failed to decode entry! Invalid instruction!");
315+
M.add(Entry);
316+
ContinuedInst.push_back(Entry);
317+
Pos = IS.tellg();
318+
getWordCountAndOpCode();
319+
}
320+
IS.seekg(Pos); // restore position
321+
return ContinuedInst;
322+
}
323+
299324
} // namespace SPIRV

lib/SPIRV/libSPIRV/SPIRVStream.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class SPIRVDecoder {
7676
void validate() const;
7777
void ignore(size_t N);
7878
void ignoreInstruction();
79+
std::vector<SPIRVEntry *>
80+
getContinuedInstructions(const spv::Op ContinuedOpCode);
7981

8082
std::istream &IS;
8183
SPIRVModule &M;

lib/SPIRV/libSPIRV/SPIRVType.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -700,18 +700,8 @@ class SPIRVTypeStruct : public SPIRVType {
700700
Decoder >> Id >> MemberTypeIdVec;
701701
Module->add(this);
702702

703-
Decoder.getWordCountAndOpCode();
704-
while (!I.eof()) {
705-
SPIRVEntry *Entry = Decoder.getEntry();
706-
if (Entry != nullptr)
707-
Module->add(Entry);
708-
if (Entry && Decoder.OpCode == ContinuedOpCode) {
709-
auto ContinuedInst = static_cast<ContinuedInstType>(Entry);
710-
addContinuedInstruction(ContinuedInst);
711-
Decoder.getWordCountAndOpCode();
712-
} else {
713-
break;
714-
}
703+
for (SPIRVEntry *E : Decoder.getContinuedInstructions(ContinuedOpCode)) {
704+
addContinuedInstruction(static_cast<ContinuedInstType>(E));
715705
}
716706
}
717707

lib/SPIRV/libSPIRV/SPIRVValue.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -344,18 +344,8 @@ template <spv::Op OC> class SPIRVConstantCompositeBase : public SPIRVValue {
344344
SPIRVDecoder Decoder = getDecoder(I);
345345
Decoder >> Type >> Id >> Elements;
346346

347-
Decoder.getWordCountAndOpCode();
348-
while (!I.eof()) {
349-
SPIRVEntry *Entry = Decoder.getEntry();
350-
if (Entry != nullptr)
351-
Module->add(Entry);
352-
if (Entry && Decoder.OpCode == ContinuedOpCode) {
353-
auto ContinuedInst = static_cast<ContinuedInstType>(Entry);
354-
addContinuedInstruction(ContinuedInst);
355-
Decoder.getWordCountAndOpCode();
356-
} else {
357-
break;
358-
}
347+
for (SPIRVEntry *E : Decoder.getContinuedInstructions(ContinuedOpCode)) {
348+
addContinuedInstruction(static_cast<ContinuedInstType>(E));
359349
}
360350
}
361351

0 commit comments

Comments
 (0)