summaryrefslogtreecommitdiff
path: root/source/slang/slang-serialize-ir.h
blob: 038335a600f7905dfe47842e10c0fbcab9084f50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// slang-serialize-ir.h
#ifndef SLANG_SERIALIZE_IR_H_INCLUDED
#define SLANG_SERIALIZE_IR_H_INCLUDED

#include "slang-serialize-ir-types.h"

#include "../core/slang-riff.h"

#include "slang-ir.h"
#include "slang-serialize-source-loc.h"

// For TranslationUnitRequest
// and FrontEndCompileRequest::ExtraEntryPointInfo
#include "slang-compiler.h"

namespace Slang {

struct IRSerialWriter
{
    typedef IRSerialData Ser;
    typedef IRSerialBinary Bin;

    Result write(IRModule* module, SerialSourceLocWriter* sourceLocWriter, SerialOptionFlags flags, IRSerialData* serialData);
  
        /// Write to a container
    static Result writeContainer(const IRSerialData& data, SerialCompressionType compressionType, RiffContainer* container);
    
    /// Get an instruction index from an instruction
    Ser::InstIndex getInstIndex(IRInst* inst) const { return inst ? Ser::InstIndex(m_instMap[inst]) : Ser::InstIndex(0); }

        /// Get a slice from an index
    UnownedStringSlice getStringSlice(Ser::StringIndex index) const { return m_stringSlicePool.getSlice(StringSlicePool::Handle(index)); }
        /// Get index from string representations
    Ser::StringIndex getStringIndex(StringRepresentation* string) { return Ser::StringIndex(m_stringSlicePool.add(string)); }
    Ser::StringIndex getStringIndex(const UnownedStringSlice& slice) { return Ser::StringIndex(m_stringSlicePool.add(slice)); }
    Ser::StringIndex getStringIndex(Name* name) { return name ? getStringIndex(name->text) : SerialStringData::kNullStringIndex; }
    Ser::StringIndex getStringIndex(const char* chars) { return Ser::StringIndex(m_stringSlicePool.add(chars)); }
    Ser::StringIndex getStringIndex(const String& string) { return Ser::StringIndex(m_stringSlicePool.add(string.getUnownedSlice())); }

    StringSlicePool& getStringPool() { return m_stringSlicePool;  }
    
    IRSerialWriter() :
        m_serialData(nullptr),
        m_stringSlicePool(StringSlicePool::Style::Default)
    {
    }

        /// Produces an instruction list which is in same order as written through IRSerialWriter
    static void calcInstructionList(IRModule* module, List<IRInst*>& instsOut);

protected:
    
    void _addInstruction(IRInst* inst);
    Result _calcDebugInfo(SerialSourceLocWriter* sourceLocWriter);
    
    List<IRInst*> m_insts;                              ///< Instructions in same order as stored in the 

    List<IRDecoration*> m_decorations;                  ///< Holds all decorations in order of the instructions as found
    List<IRInst*> m_instWithFirstDecoration;            ///< All decorations are held in this order after all the regular instructions

    Dictionary<IRInst*, Ser::InstIndex> m_instMap;      ///< Map an instruction to an instruction index

    StringSlicePool m_stringSlicePool;    
    IRSerialData* m_serialData;                         ///< Where the data is stored
};

struct IRSerialReader
{
    typedef IRSerialData Ser;
    
        /// Read a stream to fill in dataOut IRSerialData
    static Result readContainer(RiffContainer::ListChunk* module, SerialCompressionType containerCompressionType, IRSerialData* outData);

        /// Read a module from serial data
    Result read(const IRSerialData& data, Session* session, SerialSourceLocReader* sourceLocReader, RefPtr<IRModule>& outModule);

    IRSerialReader():
        m_serialData(nullptr),
        m_module(nullptr),
        m_stringTable(StringSlicePool::Style::Default)
    {
    }

    protected:

    StringSlicePool m_stringTable;

    const IRSerialData* m_serialData;
    IRModule* m_module;
};

} // namespace Slang

#endif