Skip to content

Commit

Permalink
Turn all function static non-POD variables into global POD variables
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
antiagainst committed Oct 25, 2017
1 parent 90862fe commit 063dbea
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 227 deletions.
12 changes: 6 additions & 6 deletions source/enum_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class EnumSet {
EnumSet(std::initializer_list<EnumType> cs) {
for (auto c : cs) Add(c);
}
EnumSet(uint32_t count, const EnumType* ptr) {
for (uint32_t i = 0; i < count; ++i) Add(ptr[i]);
}
// Copy constructor.
EnumSet(const EnumSet& other) { *this = other; }
// Move constructor. The moved-from set is emptied.
Expand Down Expand Up @@ -95,15 +98,12 @@ class EnumSet {
bool HasAnyOf(const EnumSet<EnumType>& in_set) const {
if (in_set.IsEmpty()) return true;

if (mask_ & in_set.mask_)
return true;
if (mask_ & in_set.mask_) return true;

if (!overflow_ || !in_set.overflow_)
return false;
if (!overflow_ || !in_set.overflow_) return false;

for (uint32_t item : *in_set.overflow_) {
if (overflow_->find(item) != overflow_->end())
return true;
if (overflow_->find(item) != overflow_->end()) return true;
}

return false;
Expand Down
4 changes: 2 additions & 2 deletions source/enum_string_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

#include "spirv/1.1/spirv.h"

namespace libspirv {
#include "extensions.h"

enum class Extension;
namespace libspirv {

// Finds Extension enum corresponding to |str|. Returns false if not found.
bool GetExtensionFromString(const std::string& str, Extension* extension);
Expand Down
70 changes: 25 additions & 45 deletions source/ext_inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,55 +23,35 @@

#include "macro.h"

spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable,
spv_target_env env) {
if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER;

static const spv_ext_inst_desc_t glslStd450Entries_1_0[] = {
#include "glsl.std.450.insts-1.0.inc"
};
#include "glsl.std.450.insts-1.0.inc" // defines glsl_entries
#include "opencl.std.insts-1.0.inc" // defines opencl_entries

static const spv_ext_inst_desc_t openclEntries_1_0[] = {
#include "opencl.std.insts-1.0.inc"
};

static const spv_ext_inst_desc_t
spv_amd_shader_explicit_vertex_parameter_entries[] = {
#include "spv-amd-gcn-shader.insts.inc"
#include "spv-amd-shader-ballot.insts.inc"
#include "spv-amd-shader-explicit-vertex-parameter.insts.inc"
};

static const spv_ext_inst_desc_t spv_amd_shader_trinary_minmax_entries[] = {
#include "spv-amd-shader-trinary-minmax.insts.inc"
};

static const spv_ext_inst_desc_t spv_amd_gcn_shader_entries[] = {
#include "spv-amd-gcn-shader.insts.inc"
};
static const spv_ext_inst_group_t kGroups_1_0[] = {
{SPV_EXT_INST_TYPE_GLSL_STD_450, ARRAY_SIZE(glsl_entries), glsl_entries},
{SPV_EXT_INST_TYPE_OPENCL_STD, ARRAY_SIZE(opencl_entries), opencl_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER,
ARRAY_SIZE(spv_amd_shader_explicit_vertex_parameter_entries),
spv_amd_shader_explicit_vertex_parameter_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX,
ARRAY_SIZE(spv_amd_shader_trinary_minmax_entries),
spv_amd_shader_trinary_minmax_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER,
ARRAY_SIZE(spv_amd_gcn_shader_entries), spv_amd_gcn_shader_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT,
ARRAY_SIZE(spv_amd_shader_ballot_entries), spv_amd_shader_ballot_entries},
};

static const spv_ext_inst_table_t kTable_1_0 = {ARRAY_SIZE(kGroups_1_0),
kGroups_1_0};

static const spv_ext_inst_desc_t spv_amd_shader_ballot_entries[] = {
#include "spv-amd-shader-ballot.insts.inc"
};

static const spv_ext_inst_group_t groups_1_0[] = {
{SPV_EXT_INST_TYPE_GLSL_STD_450, ARRAY_SIZE(glslStd450Entries_1_0),
glslStd450Entries_1_0},
{SPV_EXT_INST_TYPE_OPENCL_STD, ARRAY_SIZE(openclEntries_1_0),
openclEntries_1_0},
{SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER,
ARRAY_SIZE(spv_amd_shader_explicit_vertex_parameter_entries),
spv_amd_shader_explicit_vertex_parameter_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX,
ARRAY_SIZE(spv_amd_shader_trinary_minmax_entries),
spv_amd_shader_trinary_minmax_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER,
ARRAY_SIZE(spv_amd_gcn_shader_entries), spv_amd_gcn_shader_entries},
{SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT,
ARRAY_SIZE(spv_amd_shader_ballot_entries),
spv_amd_shader_ballot_entries},
};

static const spv_ext_inst_table_t table_1_0 = {ARRAY_SIZE(groups_1_0),
groups_1_0};
spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable,
spv_target_env env) {
if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER;

switch (env) {
// The extended instruction sets are all version 1.0 so far.
Expand All @@ -86,7 +66,7 @@ spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable,
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
*pExtInstTable = &table_1_0;
*pExtInstTable = &kTable_1_0;
return SPV_SUCCESS;
default:
assert(0 && "Unknown spv_target_env in spvExtInstTableGet()");
Expand Down
2 changes: 1 addition & 1 deletion source/extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
namespace libspirv {

// The known SPIR-V extensions.
enum class Extension {
enum Extension {
#include "extension_enum.inc"
};

Expand Down
42 changes: 15 additions & 27 deletions source/opcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ struct OpcodeDescPtrLen {
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 {
Expand Down Expand Up @@ -84,20 +87,6 @@ spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable,

// 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:
Expand All @@ -108,14 +97,14 @@ spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable,
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()");
Expand Down Expand Up @@ -183,10 +172,9 @@ void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
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!");
Expand Down
32 changes: 16 additions & 16 deletions source/operand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@

#include "macro.h"

spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
spv_target_env env) {
if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;

#include "operand.kinds-1.0.inc"
#include "operand.kinds-1.1.inc"
#include "operand.kinds-1.2.inc"

static const spv_operand_table_t table_1_0 = {
ARRAY_SIZE(pygen_variable_OperandInfoTable_1_0),
pygen_variable_OperandInfoTable_1_0};
static const spv_operand_table_t table_1_1 = {
ARRAY_SIZE(pygen_variable_OperandInfoTable_1_1),
pygen_variable_OperandInfoTable_1_1};
static const spv_operand_table_t table_1_2 = {
ARRAY_SIZE(pygen_variable_OperandInfoTable_1_2),
pygen_variable_OperandInfoTable_1_2};
static const spv_operand_table_t kTable_1_0 = {
ARRAY_SIZE(pygen_variable_OperandInfoTable_1_0),
pygen_variable_OperandInfoTable_1_0};
static const spv_operand_table_t kTable_1_1 = {
ARRAY_SIZE(pygen_variable_OperandInfoTable_1_1),
pygen_variable_OperandInfoTable_1_1};
static const spv_operand_table_t kTable_1_2 = {
ARRAY_SIZE(pygen_variable_OperandInfoTable_1_2),
pygen_variable_OperandInfoTable_1_2};

spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
spv_target_env env) {
if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;

switch (env) {
case SPV_ENV_UNIVERSAL_1_0:
Expand All @@ -47,14 +47,14 @@ spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
case SPV_ENV_OPENGL_4_2:
case SPV_ENV_OPENGL_4_3:
case SPV_ENV_OPENGL_4_5:
*pOperandTable = &table_1_0;
*pOperandTable = &kTable_1_0;
return SPV_SUCCESS;
case SPV_ENV_UNIVERSAL_1_1:
*pOperandTable = &table_1_1;
*pOperandTable = &kTable_1_1;
return SPV_SUCCESS;
case SPV_ENV_UNIVERSAL_1_2:
case SPV_ENV_OPENCL_2_2:
*pOperandTable = &table_1_2;
*pOperandTable = &kTable_1_2;
return SPV_SUCCESS;
}
assert(0 && "Unknown spv_target_env in spvOperandTableGet()");
Expand Down
12 changes: 8 additions & 4 deletions source/table.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
typedef struct spv_opcode_desc_t {
const char* name;
const SpvOp opcode;
const libspirv::CapabilitySet capabilities;
const uint32_t numCapabilities;
const SpvCapability* capabilities;
// operandTypes[0..numTypes-1] describe logical operands for the instruction.
// The operand types include result id and result-type id, followed by
// the types of arguments.
Expand All @@ -37,12 +38,14 @@ typedef struct spv_opcode_desc_t {
typedef struct spv_operand_desc_t {
const char* name;
const uint32_t value;
const libspirv::CapabilitySet capabilities;
const uint32_t numCapabilities;
const SpvCapability* capabilities;
// A set of extensions that enable this feature. If empty then this operand
// value is always enabled, i.e. it's in core. The assembler, binary parser,
// and disassembler ignore this rule, so you can freely process invalid
// modules.
const libspirv::ExtensionSet extensions;
const uint32_t numExtensions;
const libspirv::Extension* extensions;
const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger?
} spv_operand_desc_t;

Expand All @@ -55,7 +58,8 @@ typedef struct spv_operand_desc_group_t {
typedef struct spv_ext_inst_desc_t {
const char* name;
const uint32_t ext_inst;
const libspirv::CapabilitySet capabilities;
const uint32_t numCapabilities;
const SpvCapability* capabilities;
const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger?
} spv_ext_inst_desc_t;

Expand Down
Loading

0 comments on commit 063dbea

Please sign in to comment.