The way we currently do constants (particularly of arrays) is making LLVM cry. We need to do better so that compilation does not take ages. The plan is as follows:
- Pluggable Storage: Parametrise the
SSA type with an additional structure that supports arbitrary operations and can be used for storing the constants. In HLSSA we effectively want a high-level map from ValueId to value, while in LLSSA we care more about doing reads and writes on byte ranges.
- Split Data: The data for constants is stored in a read-only segment of the executable (using
constant on the LLVM global definition). It is initialised with a pointer to a pre-defined global that contains *LookupData initialised to nullptr. Note that the read-only segment will differ depending on the target in order to support relocations. This approach is explicitly supported by the LLVM docs.
- Init Lookup: If the lookup data is needed, it gets initialised on first read at runtime, replacing the
nullptr with an actual instance of the data.
- RC Sentinels: The ref-count for constants is stored in the read-only segment, and is statically initialised to a known constant
IMMORTAL_RC. When an RC operation is called, it first checks for the sentinel, and only continues if it is not found.
- RC Elision: If we can statically prove that a value is constant, then its RC operations can be elided entirely.
- Constant Read Optimisation: If we read from a constant array at a compile-time constant index, then we do not have to initialise the lookup data.
The way we currently do constants (particularly of arrays) is making LLVM cry. We need to do better so that compilation does not take ages. The plan is as follows:
SSAtype with an additional structure that supports arbitrary operations and can be used for storing the constants. In HLSSA we effectively want a high-level map fromValueIdto value, while in LLSSA we care more about doing reads and writes on byte ranges.constanton the LLVM global definition). It is initialised with a pointer to a pre-defined global that contains*LookupDatainitialised tonullptr. Note that the read-only segment will differ depending on the target in order to support relocations. This approach is explicitly supported by the LLVM docs.nullptrwith an actual instance of the data.IMMORTAL_RC. When an RC operation is called, it first checks for the sentinel, and only continues if it is not found.