9
9
namespace Slang
10
10
{
11
11
12
+ struct IRSerialWriter
13
+ {
14
+ typedef IRSerialData Ser;
15
+ typedef IRSerialBinary Bin;
16
+
17
+ Result write (
18
+ IRModule* module ,
19
+ SerialSourceLocWriter* sourceLocWriter,
20
+ IRSerialData* serialData);
21
+
22
+ // / Write to a container
23
+ static Result writeTo (const IRSerialData& data, RIFF::BuildCursor& cursor);
24
+
25
+ // / Get an instruction index from an instruction
26
+ Ser::InstIndex getInstIndex (IRInst* inst) const
27
+ {
28
+ return inst ? Ser::InstIndex (m_instMap.getValue (inst)) : Ser::InstIndex (0 );
29
+ }
30
+
31
+ // / Get a slice from an index
32
+ UnownedStringSlice getStringSlice (Ser::StringIndex index) const
33
+ {
34
+ return m_stringSlicePool.getSlice (StringSlicePool::Handle (index));
35
+ }
36
+ // / Get index from string representations
37
+ Ser::StringIndex getStringIndex (StringRepresentation* string)
38
+ {
39
+ return Ser::StringIndex (m_stringSlicePool.add (string));
40
+ }
41
+ Ser::StringIndex getStringIndex (const UnownedStringSlice& slice)
42
+ {
43
+ return Ser::StringIndex (m_stringSlicePool.add (slice));
44
+ }
45
+ Ser::StringIndex getStringIndex (Name* name)
46
+ {
47
+ return name ? getStringIndex (name->text ) : SerialStringData::kNullStringIndex ;
48
+ }
49
+ Ser::StringIndex getStringIndex (const char * chars)
50
+ {
51
+ return Ser::StringIndex (m_stringSlicePool.add (chars));
52
+ }
53
+ Ser::StringIndex getStringIndex (const String& string)
54
+ {
55
+ return Ser::StringIndex (m_stringSlicePool.add (string.getUnownedSlice ()));
56
+ }
57
+
58
+ StringSlicePool& getStringPool () { return m_stringSlicePool; }
59
+
60
+ IRSerialWriter ()
61
+ : m_serialData(nullptr ), m_stringSlicePool(StringSlicePool::Style::Default)
62
+ {
63
+ }
64
+
65
+ protected:
66
+ void _addInstruction (IRInst* inst);
67
+ Result _calcDebugInfo (SerialSourceLocWriter* sourceLocWriter);
68
+
69
+ List<IRInst*> m_insts; // /< Instructions in same order as stored in the
70
+
71
+ List<IRDecoration*>
72
+ m_decorations; // /< Holds all decorations in order of the instructions as found
73
+ List<IRInst*> m_instWithFirstDecoration; // /< All decorations are held in this order after all
74
+ // /< the regular instructions
75
+
76
+ Dictionary<IRInst*, Ser::InstIndex> m_instMap; // /< Map an instruction to an instruction index
77
+
78
+ StringSlicePool m_stringSlicePool;
79
+ IRSerialData* m_serialData; // /< Where the data is stored
80
+ };
81
+
82
+ struct IRSerialReader
83
+ {
84
+ typedef IRSerialData Ser;
85
+
86
+ // / Read a stream to fill in dataOut IRSerialData
87
+ static Result readFrom (RIFF::ListChunk const * irModuleChunk, IRSerialData* outData);
88
+
89
+ // / Read a module from serial data
90
+ Result read (
91
+ const IRSerialData& data,
92
+ Session* session,
93
+ SerialSourceLocReader* sourceLocReader,
94
+ RefPtr<IRModule>& outModule);
95
+
96
+ IRSerialReader ()
97
+ : m_serialData(nullptr ), m_module(nullptr ), m_stringTable(StringSlicePool::Style::Default)
98
+ {
99
+ }
100
+
101
+ protected:
102
+ StringSlicePool m_stringTable;
103
+
104
+ const IRSerialData* m_serialData;
105
+ IRModule* m_module;
106
+ };
107
+
12
108
static bool _isConstant (IROp opIn)
13
109
{
14
110
const int op = (kIROpMask_OpMask & opIn);
@@ -359,37 +455,6 @@ Result _writeInstArrayChunk(
359
455
return SLANG_OK;
360
456
}
361
457
362
- /* static */ void IRSerialWriter::calcInstructionList (IRModule* module , List<IRInst*>& instsOut)
363
- {
364
- // We reserve 0 for null
365
- instsOut.setCount (1 );
366
- instsOut[0 ] = nullptr ;
367
-
368
- // Stack for parentInst
369
- List<IRInst*> parentInstStack;
370
-
371
- IRModuleInst* moduleInst = module ->getModuleInst ();
372
- parentInstStack.add (moduleInst);
373
-
374
- // Add to list
375
- instsOut.add (moduleInst);
376
-
377
- // Traverse all of the instructions
378
- while (parentInstStack.getCount ())
379
- {
380
- // If it's in the stack it is assumed it is already in the inst map
381
- IRInst* parentInst = parentInstStack.getLast ();
382
- parentInstStack.removeLast ();
383
-
384
- IRInstListBase childrenList = parentInst->getDecorationsAndChildren ();
385
- for (IRInst* child : childrenList)
386
- {
387
- instsOut.add (child);
388
- parentInstStack.add (child);
389
- }
390
- }
391
- }
392
-
393
458
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IRSerialReader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
394
459
395
460
static Result _readInstArrayChunk (RIFF::DataChunk const * chunk, List<IRSerialData::Inst>& arrayOut)
@@ -399,7 +464,7 @@ static Result _readInstArrayChunk(RIFF::DataChunk const* chunk, List<IRSerialDat
399
464
}
400
465
401
466
/* static */ Result IRSerialReader::readFrom (
402
- IRModuleChunk const * irModuleChunk,
467
+ RIFF::ListChunk const * irModuleChunk,
403
468
IRSerialData* outData)
404
469
{
405
470
typedef IRSerialBinary Bin;
@@ -758,4 +823,53 @@ Result IRSerialReader::read(
758
823
return SLANG_OK;
759
824
}
760
825
826
+ void writeSerializedModuleIR (
827
+ RIFF::BuildCursor& cursor,
828
+ IRModule* irModule,
829
+ SerialSourceLocWriter* sourceLocWriter)
830
+ {
831
+ IRSerialData serialData;
832
+ IRSerialWriter writer;
833
+
834
+ writer.write (irModule, sourceLocWriter, &serialData);
835
+ IRSerialWriter::writeTo (serialData, cursor);
836
+ }
837
+
838
+ SlangResult readSerializedModuleIR (
839
+ RIFF::Chunk const * chunk,
840
+ // [[maybe_unused]] ISlangBlob* blobHoldingSerializedData,
841
+ Session* session,
842
+ // [[maybe_unused]] DiagnosticSink* sink,
843
+ SerialSourceLocReader* sourceLocReader,
844
+ RefPtr<IRModule>& outIRModule)
845
+ {
846
+ // IR serialization still uses the older approach, where
847
+ // data gets deserialized from the RIFF into an intermediate
848
+ // data structure (`IRSerialData`), and then the actual
849
+ // in-memory structures are created based on the intermediate.
850
+ //
851
+ // Thus we start by running the `IRSerialReader::readContainer`
852
+ // logic to get the `IRSerialData` representation.
853
+ //
854
+ // TODO(tfoley): This should all get streamlined so that we
855
+ // are deserializing IR nodes directly from the format written
856
+ // into the RIFF.
857
+ const auto moduleChunk = as<RIFF::ListChunk>(chunk);
858
+ if (!moduleChunk)
859
+ {
860
+ SLANG_UNEXPECTED (" invalid format for serialized module IR" );
861
+ }
862
+ IRSerialData serialData;
863
+ SLANG_RETURN_ON_FAIL (IRSerialReader::readFrom (moduleChunk, &serialData));
864
+
865
+ // Next we read the actual IR representation out from the
866
+ // `serialData`. This is the step that may pull source-location
867
+ // information from the provided `sourceLocReader`.
868
+ //
869
+ IRSerialReader reader;
870
+ SLANG_RETURN_ON_FAIL (reader.read (serialData, session, sourceLocReader, outIRModule));
871
+
872
+ return SLANG_OK;
873
+ }
874
+
761
875
} // namespace Slang
0 commit comments