Turn all function static non-POD variables into global POD variables
Function static non-POD data causes problems with DLL lifetime.
This pull request turns all static info tables into strict POD
tables. Specifically, the capabilities/extensions field of
opcode/operand/extended-instruction table are turned into two
fields, one for the count and the other a pointer to an array of
capabilities/extensions. CapabilitySet/EnumSet are not used in
the static table anymore, but they are still used for checking
inclusion by constructing on the fly, which should be cheap for
the majority cases.
Also moves all these tables into the global namespace to avoid
C++11 function static thread-safe initialization overhead.
diff --git a/source/opcode.cpp b/source/opcode.cpp
index 9bb8cb7..6c779d1 100644
--- a/source/opcode.cpp
+++ b/source/opcode.cpp
@@ -32,13 +32,16 @@
uint32_t len;
};
-OpcodeDescPtrLen getOpcodeTableEntries_1_2() {
- static const spv_opcode_desc_t opcodeTableEntries_1_2[] = {
-#include "core.insts-1.2.inc"
- };
+#include "core.insts-1.0.inc" // defines kOpcodeTableEntries_1_0
+#include "core.insts-1.1.inc" // defines kOpcodeTableEntries_1_1
+#include "core.insts-1.2.inc" // defines kOpcodeTableEntries_1_2
- return {opcodeTableEntries_1_2, ARRAY_SIZE(opcodeTableEntries_1_2)};
-}
+static const spv_opcode_table_t kTable_1_0 = {
+ ARRAY_SIZE(kOpcodeTableEntries_1_0), kOpcodeTableEntries_1_0};
+static const spv_opcode_table_t kTable_1_1 = {
+ ARRAY_SIZE(kOpcodeTableEntries_1_1), kOpcodeTableEntries_1_1};
+static const spv_opcode_table_t kTable_1_2 = {
+ ARRAY_SIZE(kOpcodeTableEntries_1_2), kOpcodeTableEntries_1_2};
// Represents a vendor tool entry in the SPIR-V XML Regsitry.
struct VendorTool {
@@ -84,20 +87,6 @@
// Descriptions of each opcode. Each entry describes the format of the
// instruction that follows a particular opcode.
- static const spv_opcode_desc_t opcodeTableEntries_1_0[] = {
-#include "core.insts-1.0.inc"
- };
- static const spv_opcode_desc_t opcodeTableEntries_1_1[] = {
-#include "core.insts-1.1.inc"
- };
-
- const auto ptr_len = getOpcodeTableEntries_1_2();
-
- static const spv_opcode_table_t table_1_0 = {
- ARRAY_SIZE(opcodeTableEntries_1_0), opcodeTableEntries_1_0};
- static const spv_opcode_table_t table_1_1 = {
- ARRAY_SIZE(opcodeTableEntries_1_1), opcodeTableEntries_1_1};
- static const spv_opcode_table_t table_1_2 = {ptr_len.len, ptr_len.ptr};
switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
@@ -108,14 +97,14 @@
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
- *pInstTable = &table_1_0;
+ *pInstTable = &kTable_1_0;
return SPV_SUCCESS;
case SPV_ENV_UNIVERSAL_1_1:
- *pInstTable = &table_1_1;
+ *pInstTable = &kTable_1_1;
return SPV_SUCCESS;
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_OPENCL_2_2:
- *pInstTable = &table_1_2;
+ *pInstTable = &kTable_1_2;
return SPV_SUCCESS;
}
assert(0 && "Unknown spv_target_env in spvOpcodeTableGet()");
@@ -183,10 +172,9 @@
const char* spvOpcodeString(const SpvOp opcode) {
// Use the latest SPIR-V version, which should be backward-compatible with all
// previous ones.
- const auto entries = getOpcodeTableEntries_1_2();
-
- for (uint32_t i = 0; i < entries.len; ++i) {
- if (entries.ptr[i].opcode == opcode) return entries.ptr[i].name;
+ for (uint32_t i = 0; i < ARRAY_SIZE(kOpcodeTableEntries_1_2); ++i) {
+ if (kOpcodeTableEntries_1_2[i].opcode == opcode)
+ return kOpcodeTableEntries_1_2[i].name;
}
assert(0 && "Unreachable!");