diff --git a/Android.mk b/Android.mk index cb7062c2d..7794c7659 100644 --- a/Android.mk +++ b/Android.mk @@ -178,73 +178,43 @@ SPVTOOLS_OPT_SRC_FILES := \ # Locations of grammar files. # -# TODO(dneto): Build a single set of tables that embeds versioning differences on -# a per-item basis. That must happen before SPIR-V 1.4, etc. -# https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 -SPV_CORE10_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/spirv.core.grammar.json -SPV_CORE11_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.1/spirv.core.grammar.json -SPV_CORE12_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/spirv.core.grammar.json SPV_COREUNIFIED1_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/unified1/spirv.core.grammar.json -SPV_CORELATEST_GRAMMAR=$(SPV_COREUNIFIED1_GRAMMAR) SPV_GLSL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/extinst.glsl.std.450.grammar.json SPV_OPENCL_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/extinst.opencl.std.100.grammar.json # TODO(dneto): I expect the DebugInfo grammar file to eventually migrate to SPIRV-Headers SPV_DEBUGINFO_GRAMMAR=$(LOCAL_PATH)/source/extinst.debuginfo.grammar.json +SPV_CLDEBUGINFO100_GRAMMAR=$(LOCAL_PATH)/source/extinst.opencl.debuginfo.100.grammar.json define gen_spvtools_grammar_tables -$(call generate-file-dir,$(1)/core.insts-1.0.inc) -$(1)/core.insts-1.0.inc $(1)/operand.kinds-1.0.inc $(1)/glsl.std.450.insts.inc $(1)/opencl.std.insts.inc: \ +$(call generate-file-dir,$(1)/core.insts-unified1.inc) +$(1)/core.insts-unified1.inc $(1)/operand.kinds-unified1.inc \ +$(1)/glsl.std.450.insts.inc \ +$(1)/opencl.std.insts.inc \ +: \ $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - $(SPV_CORE10_GRAMMAR) \ + $(SPV_COREUNIFIED1_GRAMMAR) \ $(SPV_GLSL_GRAMMAR) \ - $(SPV_OPENCL_GRAMMAR) \ - $(SPV_DEBUGINFO_GRAMMAR) + $(SPV_OpenCL_GRAMMAR) \ + $(SPV_DEBUGINFO_GRAMMAR) \ + $(SPV_CLDEBUGINFO100_GRAMMAR) @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - --spirv-core-grammar=$(SPV_CORE10_GRAMMAR) \ + --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \ --extinst-glsl-grammar=$(SPV_GLSL_GRAMMAR) \ --extinst-opencl-grammar=$(SPV_OPENCL_GRAMMAR) \ --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ - --core-insts-output=$(1)/core.insts-1.0.inc \ + --extinst-cldebuginfo100-grammar=$(SPV_CLDEBUGINFO100_GRAMMAR) \ + --core-insts-output=$(1)/core.insts-unified1.inc \ --glsl-insts-output=$(1)/glsl.std.450.insts.inc \ --opencl-insts-output=$(1)/opencl.std.insts.inc \ - --operand-kinds-output=$(1)/operand.kinds-1.0.inc - @echo "[$(TARGET_ARCH_ABI)] Grammar v1.0 : instructions & operands <= grammar JSON files" -$(1)/core.insts-1.1.inc $(1)/operand.kinds-1.1.inc: \ - $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - $(SPV_CORE11_GRAMMAR) \ - $(SPV_DEBUGINFO_GRAMMAR) - @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - --spirv-core-grammar=$(SPV_CORE11_GRAMMAR) \ - --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ - --core-insts-output=$(1)/core.insts-1.1.inc \ - --operand-kinds-output=$(1)/operand.kinds-1.1.inc - @echo "[$(TARGET_ARCH_ABI)] Grammar v1.1 : instructions & operands <= grammar JSON files" -$(1)/core.insts-1.2.inc $(1)/operand.kinds-1.2.inc: \ - $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - $(SPV_CORE12_GRAMMAR) \ - $(SPV_DEBUGINFO_GRAMMAR) - @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - --spirv-core-grammar=$(SPV_CORE12_GRAMMAR) \ - --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ - --core-insts-output=$(1)/core.insts-1.2.inc \ - --operand-kinds-output=$(1)/operand.kinds-1.2.inc - @echo "[$(TARGET_ARCH_ABI)] Grammar v1.2 : instructions & operands <= grammar JSON files" -$(1)/core.insts-unified1.inc $(1)/operand.kinds-unified1.inc: \ - $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - $(SPV_COREUNIFIED1_GRAMMAR) \ - $(SPV_DEBUGINFO_GRAMMAR) - @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \ - --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ - --core-insts-output=$(1)/core.insts-unified1.inc \ --operand-kinds-output=$(1)/operand.kinds-unified1.inc - @echo "[$(TARGET_ARCH_ABI)] Grammar v1.3 (from unified1) : instructions & operands <= grammar JSON files" -$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-1.0.inc $(1)/core.insts-1.1.inc $(1)/core.insts-1.2.inc $(1)/core.insts-unified1.inc -$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-1.0.inc $(1)/operand.kinds-1.1.inc $(1)/operand.kinds-1.2.inc $(1)/operand.kinds-unified1.inc + @echo "[$(TARGET_ARCH_ABI)] Grammar (from unified1) : instructions & operands <= grammar JSON files" +$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-unified1.inc +$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-unified1.inc $(LOCAL_PATH)/source/ext_inst.cpp: \ $(1)/glsl.std.450.insts.inc \ $(1)/opencl.std.insts.inc \ $(1)/debuginfo.insts.inc \ + $(1)/opencl.debuginfo.100.insts.inc \ $(1)/spv-amd-gcn-shader.insts.inc \ $(1)/spv-amd-shader-ballot.insts.inc \ $(1)/spv-amd-shader-explicit-vertex-parameter.insts.inc \ @@ -271,8 +241,9 @@ $(1)/$(2).h : \ @echo "[$(TARGET_ARCH_ABI)] Generate language specific header for $(2): headers <= grammar" $(LOCAL_PATH)/source/ext_inst.cpp: $(1)/$(2).h endef -# We generate language-specific headers for DebugInfo +# We generate language-specific headers for DebugInfo and OpenCL.DebugInfo.100 $(eval $(call gen_spvtools_lang_headers,$(SPVTOOLS_OUT_PATH),DebugInfo,$(SPV_DEBUGINFO_GRAMMAR))) +$(eval $(call gen_spvtools_lang_headers,$(SPVTOOLS_OUT_PATH),OpenCLDebugInfo100,$(SPV_CLDEBUGINFO100_GRAMMAR))) define gen_spvtools_vendor_tables @@ -282,22 +253,28 @@ $(1)/$(2).insts.inc : \ $(LOCAL_PATH)/source/extinst.$(2).grammar.json @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ --extinst-vendor-grammar=$(LOCAL_PATH)/source/extinst.$(2).grammar.json \ - --vendor-insts-output=$(1)/$(2).insts.inc + --vendor-insts-output=$(1)/$(2).insts.inc \ + --vendor-operand-kind-prefix=$(3) @echo "[$(TARGET_ARCH_ABI)] Vendor extended instruction set: $(2) tables <= grammar" $(LOCAL_PATH)/source/ext_inst.cpp: $(1)/$(2).insts.inc endef -# Vendor extended instruction sets, with grammars from SPIRV-Tools source tree. -SPV_NONSTANDARD_EXTINST_GRAMMARS=$(foreach F,$(wildcard $(LOCAL_PATH)/source/extinst.*.grammar.json),$(patsubst extinst.%.grammar.json,%,$(notdir $F))) -$(foreach E,$(SPV_NONSTANDARD_EXTINST_GRAMMARS),$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),$E))) +# Vendor and debug extended instruction sets, with grammars from SPIRV-Tools source tree. +$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),debuginfo,"")) +$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),opencl.debuginfo.100,"CLDEBUG100_")) +$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-gcn-shader,"")) +$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-ballot,"")) +$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-explicit-vertex-parameter,"")) +$(eval $(call gen_spvtools_vendor_tables,$(SPVTOOLS_OUT_PATH),spv-amd-shader-trinary-minmax,"")) define gen_spvtools_enum_string_mapping $(call generate-file-dir,$(1)/extension_enum.inc.inc) $(1)/extension_enum.inc $(1)/enum_string_mapping.inc: \ $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - $(SPV_CORELATEST_GRAMMAR) + $(SPV_COREUNIFIED1_GRAMMAR) @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ - --spirv-core-grammar=$(SPV_CORELATEST_GRAMMAR) \ + --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \ --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ + --extinst-cldebuginfo100-grammar=$(SPV_CLDEBUGINFO100_GRAMMAR) \ --extension-enum-output=$(1)/extension_enum.inc \ --enum-string-mapping-output=$(1)/enum_string_mapping.inc @echo "[$(TARGET_ARCH_ABI)] Generate enum<->string mapping <= grammar JSON files" diff --git a/BUILD.bazel b/BUILD.bazel index dc1ca6047..3046781fc 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -2,6 +2,7 @@ load( ":build_defs.bzl", "COMMON_COPTS", "DEBUGINFO_GRAMMAR_JSON_FILE", + "CLDEBUGINFO100_GRAMMAR_JSON_FILE", "TEST_COPTS", "base_test", "generate_core_tables", @@ -38,12 +39,6 @@ py_binary( srcs = ["utils/generate_language_headers.py"], ) -generate_core_tables("1.0") - -generate_core_tables("1.1") - -generate_core_tables("1.2") - generate_core_tables("unified1") generate_enum_string_mapping("unified1") @@ -62,8 +57,12 @@ generate_vendor_tables("spv-amd-shader-ballot") generate_vendor_tables("debuginfo") +generate_vendor_tables("opencl.debuginfo.100", "CLDEBUG100_") + generate_extinst_lang_headers("DebugInfo", DEBUGINFO_GRAMMAR_JSON_FILE) +generate_extinst_lang_headers("OpenCLDebugInfo100", CLDEBUGINFO100_GRAMMAR_JSON_FILE) + py_binary( name = "generate_registry_tables", srcs = ["utils/generate_registry_tables.py"], @@ -96,16 +95,15 @@ cc_library( name = "generated_headers", hdrs = [ ":gen_build_version", - ":gen_core_tables_1.0", - ":gen_core_tables_1.1", - ":gen_core_tables_1.2", ":gen_core_tables_unified1", ":gen_enum_string_mapping", ":gen_extinst_lang_headers_DebugInfo", + ":gen_extinst_lang_headers_OpenCLDebugInfo100", ":gen_glsl_tables_unified1", ":gen_opencl_tables_unified1", ":gen_registry_tables", ":gen_vendor_tables_debuginfo", + ":gen_vendor_tables_opencl_debuginfo_100", ":gen_vendor_tables_spv_amd_gcn_shader", ":gen_vendor_tables_spv_amd_shader_ballot", ":gen_vendor_tables_spv_amd_shader_explicit_vertex_parameter", diff --git a/BUILD.gn b/BUILD.gn index 5c8eb9a0d..3c85c4e4a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -32,7 +32,8 @@ template("spvtools_core_tables") { "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json" core_insts_file = "${target_gen_dir}/core.insts-$version.inc" operand_kinds_file = "${target_gen_dir}/operand.kinds-$version.inc" - extinst_file = "source/extinst.debuginfo.grammar.json" + debuginfo_insts_file = "source/extinst.debuginfo.grammar.json" + cldebuginfo100_insts_file = "source/extinst.opencl.debuginfo.100.grammar.json" sources = [ core_json_file, @@ -47,7 +48,9 @@ template("spvtools_core_tables") { "--core-insts-output", rebase_path(core_insts_file, root_build_dir), "--extinst-debuginfo-grammar", - rebase_path(extinst_file, root_build_dir), + rebase_path(debuginfo_insts_file, root_build_dir), + "--extinst-cldebuginfo100-grammar", + rebase_path(cldebuginfo100_insts_file, root_build_dir), "--operand-kinds-output", rebase_path(operand_kinds_file, root_build_dir), ] @@ -64,7 +67,8 @@ template("spvtools_core_enums") { core_json_file = "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json" - debug_insts_file = "source/extinst.debuginfo.grammar.json" + debuginfo_insts_file = "source/extinst.debuginfo.grammar.json" + cldebuginfo100_insts_file = "source/extinst.opencl.debuginfo.100.grammar.json" extension_enum_file = "${target_gen_dir}/extension_enum.inc" extension_map_file = "${target_gen_dir}/enum_string_mapping.inc" @@ -72,7 +76,9 @@ template("spvtools_core_enums") { "--spirv-core-grammar", rebase_path(core_json_file, root_build_dir), "--extinst-debuginfo-grammar", - rebase_path(debug_insts_file, root_build_dir), + rebase_path(debuginfo_insts_file, root_build_dir), + "--extinst-cldebuginfo100-grammar", + rebase_path(cldebuginfo100_insts_file, root_build_dir), "--extension-enum-output", rebase_path(extension_enum_file, root_build_dir), "--enum-string-mapping-output", @@ -100,7 +106,6 @@ template("spvtools_glsl_tables") { "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json" glsl_json_file = "${spirv_headers}/include/spirv/${version}/extinst.glsl.std.450.grammar.json" glsl_insts_file = "${target_gen_dir}/glsl.std.450.insts.inc" - debug_insts_file = "source/extinst.debuginfo.grammar.json" args = [ "--spirv-core-grammar", @@ -109,8 +114,6 @@ template("spvtools_glsl_tables") { rebase_path(glsl_json_file, root_build_dir), "--glsl-insts-output", rebase_path(glsl_insts_file, root_build_dir), - "--extinst-debuginfo-grammar", - rebase_path(debug_insts_file, root_build_dir), ] inputs = [ core_json_file, @@ -134,7 +137,6 @@ template("spvtools_opencl_tables") { "${spirv_headers}/include/spirv/$version/spirv.core.grammar.json" opengl_json_file = "${spirv_headers}/include/spirv/${version}/extinst.opencl.std.100.grammar.json" opencl_insts_file = "${target_gen_dir}/opencl.std.insts.inc" - debug_insts_file = "source/extinst.debuginfo.grammar.json" args = [ "--spirv-core-grammar", @@ -143,8 +145,6 @@ template("spvtools_opencl_tables") { rebase_path(opengl_json_file, root_build_dir), "--opencl-insts-output", rebase_path(opencl_insts_file, root_build_dir), - "--extinst-debuginfo-grammar", - rebase_path(debug_insts_file, root_build_dir), ] inputs = [ core_json_file, @@ -164,13 +164,12 @@ template("spvtools_language_header") { name = invoker.name extinst_output_base = "${target_gen_dir}/${name}" - debug_insts_file = "source/extinst.debuginfo.grammar.json" args = [ "--extinst-name", "${name}", "--extinst-grammar", - rebase_path(debug_insts_file, root_build_dir), + rebase_path(invoker.grammar_file, root_build_dir), "--extinst-output-base", rebase_path(extinst_output_base, root_build_dir), ] @@ -198,6 +197,8 @@ template("spvtools_vendor_table") { rebase_path(extinst_vendor_grammar, root_build_dir), "--vendor-insts-output", rebase_path(extinst_file, root_build_dir), + "--vendor-operand-kind-prefix", + invoker.operand_kind_prefix ] inputs = [ extinst_vendor_grammar, @@ -256,21 +257,28 @@ spvtools_glsl_tables("glsl1-0") { spvtools_opencl_tables("opencl1-0") { version = "1.0" } -spvtools_language_header("unified1") { +spvtools_language_header("debuginfo") { name = "DebugInfo" + grammar_file = "source/extinst.debuginfo.grammar.json" +} +spvtools_language_header("cldebuginfo100") { + name = "OpenCLDebugInfo100" + grammar_file = "source/extinst.opencl.debuginfo.100.grammar.json" } spvtools_vendor_tables = [ - "spv-amd-shader-explicit-vertex-parameter", - "spv-amd-shader-trinary-minmax", - "spv-amd-gcn-shader", - "spv-amd-shader-ballot", - "debuginfo", + ["spv-amd-shader-explicit-vertex-parameter", ""], + ["spv-amd-shader-trinary-minmax", ""], + ["spv-amd-gcn-shader", ""], + ["spv-amd-shader-ballot", ""], + ["debuginfo", ""], + ["opencl.debuginfo.100", "CLDEBUG100_"], ] -foreach(table, spvtools_vendor_tables) { +foreach(table_def, spvtools_vendor_tables) { spvtools_vendor_table(table) { - name = table + name = table_def[0] + operand_kind_prefix = table_def[1] } } @@ -320,10 +328,12 @@ static_library("spvtools") { ":spvtools_core_tables_unified1", ":spvtools_generators_inc", ":spvtools_glsl_tables_glsl1-0", - ":spvtools_language_header_unified1", + ":spvtools_language_header_debuginfo", + ":spvtools_language_header_cldebuginfo100", ":spvtools_opencl_tables_opencl1-0", ] - foreach(target_name, spvtools_vendor_tables) { + foreach(table_def, spvtools_vendor_tables) { + target_name = table_def[0] deps += [ ":spvtools_vendor_tables_$target_name" ] } @@ -818,6 +828,7 @@ if (build_with_chromium) { "test/ext_inst.debuginfo_test.cpp", "test/ext_inst.glsl_test.cpp", "test/ext_inst.opencl_test.cpp", + "test/ext_inst.cldebug100_test.cpp", "test/fix_word_test.cpp", "test/generator_magic_number_test.cpp", "test/hex_float_test.cpp", @@ -864,7 +875,8 @@ if (build_with_chromium) { deps = [ ":spvtools", - ":spvtools_language_header_unified1", + ":spvtools_language_header_debuginfo", + ":spvtools_language_header_cldebuginfo100", ":spvtools_val", "//testing/gmock", "//testing/gtest", diff --git a/build_defs.bzl b/build_defs.bzl index 483fd2ae3..5d913a14c 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -40,6 +40,7 @@ TEST_COPTS = COMMON_COPTS + select({ }) DEBUGINFO_GRAMMAR_JSON_FILE = "source/extinst.debuginfo.grammar.json" +CLDEBUGINFO100_GRAMMAR_JSON_FILE = "source/extinst.opencl.debuginfo.100.grammar.json" def generate_core_tables(version = None): if not version: @@ -47,6 +48,7 @@ def generate_core_tables(version = None): grammars = [ "@spirv_headers//:spirv_core_grammar_" + version, DEBUGINFO_GRAMMAR_JSON_FILE, + CLDEBUGINFO100_GRAMMAR_JSON_FILE, ] outs = [ "core.insts-{}.inc".format(version), @@ -61,8 +63,9 @@ def generate_core_tables(version = None): "$(location :generate_grammar_tables) " + "--spirv-core-grammar=$(location {0}) " + "--extinst-debuginfo-grammar=$(location {1}) " + - "--core-insts-output=$(location {2}) " + - "--operand-kinds-output=$(location {3})" + "--extinst-cldebuginfo100-grammar=$(location {2}) " + + "--core-insts-output=$(location {3}) " + + "--operand-kinds-output=$(location {4})" ).format(*fmtargs), tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], @@ -74,6 +77,7 @@ def generate_enum_string_mapping(version = None): grammars = [ "@spirv_headers//:spirv_core_grammar_" + version, DEBUGINFO_GRAMMAR_JSON_FILE, + CLDEBUGINFO100_GRAMMAR_JSON_FILE, ] outs = [ "extension_enum.inc", @@ -88,8 +92,9 @@ def generate_enum_string_mapping(version = None): "$(location :generate_grammar_tables) " + "--spirv-core-grammar=$(location {0}) " + "--extinst-debuginfo-grammar=$(location {1}) " + - "--extension-enum-output=$(location {2}) " + - "--enum-string-mapping-output=$(location {3})" + "--extinst-cldebuginfo100-grammar=$(location {2}) " + + "--extension-enum-output=$(location {3}) " + + "--enum-string-mapping-output=$(location {4})" ).format(*fmtargs), tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], @@ -137,13 +142,14 @@ def generate_glsl_tables(version = None): visibility = ["//visibility:private"], ) -def generate_vendor_tables(extension = None): +def generate_vendor_tables(extension, operand_kind_prefix = ""): if not extension: fail("Must specify extension", "extension") - extension_rule = extension.replace("-", "_") + extension_rule = extension.replace("-", "_").replace(".", "_") grammars = ["source/extinst.{}.grammar.json".format(extension)] outs = ["{}.insts.inc".format(extension)] - fmtargs = grammars + outs + prefices = [operand_kind_prefix] + fmtargs = grammars + outs + prefices native.genrule( name = "gen_vendor_tables_" + extension_rule, srcs = grammars, @@ -151,7 +157,8 @@ def generate_vendor_tables(extension = None): cmd = ( "$(location :generate_grammar_tables) " + "--extinst-vendor-grammar=$(location {0}) " + - "--vendor-insts-output=$(location {1})" + "--vendor-insts-output=$(location {1}) " + + "--vendor-operand-kind-prefix={2}" ).format(*fmtargs), tools = [":generate_grammar_tables"], visibility = ["//visibility:private"], diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index 723de0527..5dcb81add 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -225,13 +225,23 @@ typedef enum spv_operand_type_t { // A sequence of zero or more pairs of (Id, Literal integer) LAST_VARIABLE(SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER), - // The following are concrete enum types. + // The following are concrete enum types from the DebugInfo extended + // instruction set. SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, // DebugInfo Sec 3.2. A mask. SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // DebugInfo Sec 3.3 SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, // DebugInfo Sec 3.4 SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER, // DebugInfo Sec 3.5 SPV_OPERAND_TYPE_DEBUG_OPERATION, // DebugInfo Sec 3.6 + // The following are concrete enum types from the OpenCL.DebugInfo.100 + // extended instruction set. + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS, // Sec 3.2. A Mask + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, // Sec 3.3 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE, // Sec 3.4 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER, // Sec 3.5 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, // Sec 3.6 + SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, // Sec 3.7 + // This is a sentinel value, and does not represent an operand type. // It should come last. SPV_OPERAND_TYPE_NUM_OPERAND_TYPES, @@ -248,6 +258,7 @@ typedef enum spv_ext_inst_type_t { SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER, SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT, SPV_EXT_INST_TYPE_DEBUGINFO, + SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100, // Multiple distinct extended instruction set types could return this // value, if they are prefixed with NonSemantic. and are otherwise diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index f3b5942bc..4e7e10cb6 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -20,6 +20,7 @@ set(LANG_HEADER_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_lang # For now, assume the DebugInfo grammar file is in the current directory. # It might migrate to SPIRV-Headers. set(DEBUGINFO_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst.debuginfo.grammar.json") +set(CLDEBUGINFO100_GRAMMAR_JSON_FILE "${CMAKE_CURRENT_SOURCE_DIR}/extinst.opencl.debuginfo.100.grammar.json") # macro() definitions are used in the following because we need to append .inc # file paths into some global lists (*_CPP_DEPENDS). And those global lists are @@ -33,9 +34,13 @@ macro(spvtools_core_tables CONFIG_VERSION) COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --spirv-core-grammar=${GRAMMAR_JSON_FILE} --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} + --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE} --core-insts-output=${GRAMMAR_INSTS_INC_FILE} --operand-kinds-output=${GRAMMAR_KINDS_INC_FILE} - DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE} + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} + ${GRAMMAR_JSON_FILE} + ${DEBUGINFO_GRAMMAR_JSON_FILE} + ${CLDEBUGINFO100_GRAMMAR_JSON_FILE} COMMENT "Generate info tables for SPIR-V v${CONFIG_VERSION} core instructions and operands.") list(APPEND OPCODE_CPP_DEPENDS ${GRAMMAR_INSTS_INC_FILE}) list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE}) @@ -50,9 +55,13 @@ macro(spvtools_enum_string_mapping CONFIG_VERSION) COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --spirv-core-grammar=${GRAMMAR_JSON_FILE} --extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE} + --extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE} --extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE} --enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE} - DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE} ${DEBUGINFO_GRAMMAR_JSON_FILE} + DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} + ${GRAMMAR_JSON_FILE} + ${DEBUGINFO_GRAMMAR_JSON_FILE} + ${CLDEBUGINFO100_GRAMMAR_JSON_FILE} COMMENT "Generate enum-string mapping for SPIR-V v${CONFIG_VERSION}.") list(APPEND EXTENSION_H_DEPENDS ${GRAMMAR_EXTENSION_ENUM_INC_FILE}) list(APPEND ENUM_STRING_MAPPING_CPP_DEPENDS ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}) @@ -101,13 +110,14 @@ macro(spvtools_opencl_tables CONFIG_VERSION) list(APPEND EXTINST_CPP_DEPENDS ${GRAMMAR_INC_FILE}) endmacro(spvtools_opencl_tables) -macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME) +macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME OPERAND_KIND_PREFIX) set(INSTS_FILE "${spirv-tools_BINARY_DIR}/${VENDOR_TABLE}.insts.inc") set(GRAMMAR_FILE "${spirv-tools_SOURCE_DIR}/source/extinst.${VENDOR_TABLE}.grammar.json") add_custom_command(OUTPUT ${INSTS_FILE} COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT} --extinst-vendor-grammar=${GRAMMAR_FILE} --vendor-insts-output=${INSTS_FILE} + --vendor-operand-kind-prefix=${OPERAND_KIND_PREFIX} DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_FILE} COMMENT "Generate extended instruction tables for ${VENDOR_TABLE}.") add_custom_target(spv-tools-${SHORT_NAME} DEPENDS ${INSTS_FILE}) @@ -134,12 +144,14 @@ spvtools_core_tables("unified1") spvtools_enum_string_mapping("unified1") spvtools_opencl_tables("unified1") spvtools_glsl_tables("unified1") -spvtools_vendor_tables("spv-amd-shader-explicit-vertex-parameter" "spv-amd-sevp") -spvtools_vendor_tables("spv-amd-shader-trinary-minmax" "spv-amd-stm") -spvtools_vendor_tables("spv-amd-gcn-shader" "spv-amd-gs") -spvtools_vendor_tables("spv-amd-shader-ballot" "spv-amd-sb") -spvtools_vendor_tables("debuginfo" "debuginfo") +spvtools_vendor_tables("spv-amd-shader-explicit-vertex-parameter" "spv-amd-sevp" "") +spvtools_vendor_tables("spv-amd-shader-trinary-minmax" "spv-amd-stm" "") +spvtools_vendor_tables("spv-amd-gcn-shader" "spv-amd-gs" "") +spvtools_vendor_tables("spv-amd-shader-ballot" "spv-amd-sb" "") +spvtools_vendor_tables("debuginfo" "debuginfo" "") +spvtools_vendor_tables("opencl.debuginfo.100" "cldi100" "CLDEBUG100_") spvtools_extinst_lang_headers("DebugInfo" ${DEBUGINFO_GRAMMAR_JSON_FILE}) +spvtools_extinst_lang_headers("OpenCLDebugInfo100" ${CLDEBUGINFO100_GRAMMAR_JSON_FILE}) spvtools_vimsyntax("unified1" "1.0") add_custom_target(spirv-tools-vimsyntax DEPENDS ${VIMSYNTAX_FILE}) diff --git a/source/binary.cpp b/source/binary.cpp index 8229e53af..046306185 100644 --- a/source/binary.cpp +++ b/source/binary.cpp @@ -636,7 +636,12 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: - case SPV_OPERAND_TYPE_DEBUG_OPERATION: { + case SPV_OPERAND_TYPE_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: { // A single word that is a plain enum value. // Map an optional operand type to its corresponding concrete type. @@ -660,6 +665,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: { // This operand is a mask. diff --git a/source/disassemble.cpp b/source/disassemble.cpp index 2ba0d3d88..4b3972b51 100644 --- a/source/disassemble.cpp +++ b/source/disassemble.cpp @@ -280,7 +280,12 @@ void Disassembler::EmitOperand(const spv_parsed_instruction_t& inst, case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: - case SPV_OPERAND_TYPE_DEBUG_OPERATION: { + case SPV_OPERAND_TYPE_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: { spv_operand_desc entry; if (grammar_.lookupOperand(operand.type, word, &entry)) assert(false && "should have caught this earlier"); @@ -293,6 +298,7 @@ void Disassembler::EmitOperand(const spv_parsed_instruction_t& inst, case SPV_OPERAND_TYPE_MEMORY_ACCESS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: EmitMaskOperand(operand.type, word); break; default: diff --git a/source/ext_inst.cpp b/source/ext_inst.cpp index 6ac5756cc..e332f0d96 100644 --- a/source/ext_inst.cpp +++ b/source/ext_inst.cpp @@ -28,6 +28,7 @@ #include "debuginfo.insts.inc" #include "glsl.std.450.insts.inc" +#include "opencl.debuginfo.100.insts.inc" #include "opencl.std.insts.inc" #include "spirv-tools/libspirv.h" @@ -51,6 +52,8 @@ static const spv_ext_inst_group_t kGroups_1_0[] = { ARRAY_SIZE(spv_amd_shader_ballot_entries), spv_amd_shader_ballot_entries}, {SPV_EXT_INST_TYPE_DEBUGINFO, ARRAY_SIZE(debuginfo_entries), debuginfo_entries}, + {SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100, + ARRAY_SIZE(opencl_debuginfo_100_entries), opencl_debuginfo_100_entries}, }; static const spv_ext_inst_table_t kTable_1_0 = {ARRAY_SIZE(kGroups_1_0), @@ -116,6 +119,9 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) { if (!strcmp("DebugInfo", name)) { return SPV_EXT_INST_TYPE_DEBUGINFO; } + if (!strcmp("OpenCL.DebugInfo.100", name)) { + return SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100; + } // ensure to add any known non-semantic extended instruction sets // above this point, and update spvExtInstIsNonSemantic() if (!strncmp("NonSemantic.", name, 12)) { diff --git a/source/extinst.opencl.debuginfo.100.grammar.json b/source/extinst.opencl.debuginfo.100.grammar.json new file mode 100644 index 000000000..08062be4f --- /dev/null +++ b/source/extinst.opencl.debuginfo.100.grammar.json @@ -0,0 +1,632 @@ +{ + "copyright" : [ + "Copyright (c) 2018 The Khronos Group Inc.", + "", + "Permission is hereby granted, free of charge, to any person obtaining a copy", + "of this software and/or associated documentation files (the \"Materials\"),", + "to deal in the Materials without restriction, including without limitation", + "the rights to use, copy, modify, merge, publish, distribute, sublicense,", + "and/or sell copies of the Materials, and to permit persons to whom the", + "Materials are furnished to do so, subject to the following conditions:", + "", + "The above copyright notice and this permission notice shall be included in", + "all copies or substantial portions of the Materials.", + "", + "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS", + "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND", + "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ", + "", + "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS", + "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL", + "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING", + "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS", + "IN THE MATERIALS." + ], + "version" : 200, + "revision" : 2, + "instructions" : [ + { + "opname" : "DebugInfoNone", + "opcode" : 0 + }, + { + "opname" : "DebugCompilationUnit", + "opcode" : 1, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Version'" }, + { "kind" : "LiteralInteger", "name" : "'DWARF Version'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "SourceLanguage", "name" : "'Language'" } + ] + }, + { + "opname" : "DebugTypeBasic", + "opcode" : 2, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugBaseTypeAttributeEncoding", "name" : "'Encoding'" } + ] + }, + { + "opname" : "DebugTypePointer", + "opcode" : 3, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "StorageClass", "name" : "'Storage Class'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypeQualifier", + "opcode" : 4, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "DebugTypeQualifier", "name" : "'Type Qualifier'" } + ] + }, + { + "opname" : "DebugTypeArray", + "opcode" : 5, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeVector", + "opcode" : 6, + "operands" : [ + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "LiteralInteger", "name" : "'Component Count'" } + ] + }, + { + "opname" : "DebugTypedef", + "opcode" : 7, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeFunction", + "opcode" : 8, + "operands" : [ + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Return Type'" }, + { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeEnum", + "opcode" : 9, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Underlying Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeComposite", + "opcode" : 10, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugCompositeType", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeMember", + "opcode" : 11, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugTypeInheritance", + "opcode" : 12, + "operands" : [ + { "kind" : "IdRef", "name" : "'Child'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Offset'" }, + { "kind" : "IdRef", "name" : "'Size'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugTypePtrToMember", + "opcode" : 13, + "operands" : [ + { "kind" : "IdRef", "name" : "'Member Type'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugTypeTemplate", + "opcode" : 14, + "operands" : [ + { "kind" : "IdRef", "name" : "'Target'" }, + { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugTypeTemplateParameter", + "opcode" : 15, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Actual Type'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateTemplateParameter", + "opcode" : 16, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Template Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" } + ] + }, + { + "opname" : "DebugTypeTemplateParameterPack", + "opcode" : 17, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugGlobalVariable", + "opcode" : 18, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugFunctionDeclaration", + "opcode" : 19, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugFunction", + "opcode" : 20, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Linkage Name'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Scope Line'" }, + { "kind" : "IdRef", "name" : "'Function'" }, + { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlock", + "opcode" : 21, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLexicalBlockDiscriminator", + "opcode" : 22, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Discriminator'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugScope", + "opcode" : 23, + "operands" : [ + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugNoScope", + "opcode" : 24 + }, + { + "opname" : "DebugInlinedAt", + "opcode" : 25, + "operands" : [ + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Scope'" }, + { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugLocalVariable", + "opcode" : 26, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Type'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" }, + { "kind" : "DebugInfoFlags", "name" : "'Flags'" }, + { "kind" : "LiteralInteger", "name" : "'Arg Number'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugInlinedVariable", + "opcode" : 27, + "operands" : [ + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Inlined'" } + ] + }, + { + "opname" : "DebugDeclare", + "opcode" : 28, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Variable'" }, + { "kind" : "IdRef", "name" : "'Expression'" } + ] + }, + { + "opname" : "DebugValue", + "opcode" : 29, + "operands" : [ + { "kind" : "IdRef", "name" : "'Local Variable'" }, + { "kind" : "IdRef", "name" : "'Value'" }, + { "kind" : "IdRef", "name" : "'Expression'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugOperation", + "opcode" : 30, + "operands" : [ + { "kind" : "DebugOperation", "name" : "'OpCode'" }, + { "kind" : "LiteralInteger", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugExpression", + "opcode" : 31, + "operands" : [ + { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" } + ] + }, + { + "opname" : "DebugMacroDef", + "opcode" : 32, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" } + ] + }, + { + "opname" : "DebugMacroUndef", + "opcode" : 33, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "IdRef", "name" : "'Macro'" } + ] + }, + { + "opname" : "DebugImportedEntity", + "opcode" : 34, + "operands" : [ + { "kind" : "IdRef", "name" : "'Name'" }, + { "kind" : "DebugImportedEntity", "name" : "'Tag'" }, + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Entity'" }, + { "kind" : "LiteralInteger", "name" : "'Line'" }, + { "kind" : "LiteralInteger", "name" : "'Column'" }, + { "kind" : "IdRef", "name" : "'Parent'" } + ] + }, + { + "opname" : "DebugSource", + "opcode" : 35, + "operands" : [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "FlagIsProtected", + "value" : "0x01" + }, + { + "enumerant" : "FlagIsPrivate", + "value" : "0x02" + }, + { + "enumerant" : "FlagIsPublic", + "value" : "0x03" + }, + { + "enumerant" : "FlagIsLocal", + "value" : "0x04" + }, + { + "enumerant" : "FlagIsDefinition", + "value" : "0x08" + }, + { + "enumerant" : "FlagFwdDecl", + "value" : "0x10" + }, + { + "enumerant" : "FlagArtificial", + "value" : "0x20" + }, + { + "enumerant" : "FlagExplicit", + "value" : "0x40" + }, + { + "enumerant" : "FlagPrototyped", + "value" : "0x80" + }, + { + "enumerant" : "FlagObjectPointer", + "value" : "0x100" + }, + { + "enumerant" : "FlagStaticMember", + "value" : "0x200" + }, + { + "enumerant" : "FlagIndirectVariable", + "value" : "0x400" + }, + { + "enumerant" : "FlagLValueReference", + "value" : "0x800" + }, + { + "enumerant" : "FlagRValueReference", + "value" : "0x1000" + }, + { + "enumerant" : "FlagIsOptimized", + "value" : "0x2000" + }, + { + "enumerant" : "FlagIsEnumClass", + "value" : "0x4000" + }, + { + "enumerant" : "FlagTypePassByValue", + "value" : "0x8000" + }, + { + "enumerant" : "FlagTypePassByReference", + "value" : "0x10000" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugBaseTypeAttributeEncoding", + "enumerants" : [ + { + "enumerant" : "Unspecified", + "value" : "0" + }, + { + "enumerant" : "Address", + "value" : "1" + }, + { + "enumerant" : "Boolean", + "value" : "2" + }, + { + "enumerant" : "Float", + "value" : "3" + }, + { + "enumerant" : "Signed", + "value" : "4" + }, + { + "enumerant" : "SignedChar", + "value" : "5" + }, + { + "enumerant" : "Unsigned", + "value" : "6" + }, + { + "enumerant" : "UnsignedChar", + "value" : "7" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugCompositeType", + "enumerants" : [ + { + "enumerant" : "Class", + "value" : "0" + }, + { + "enumerant" : "Structure", + "value" : "1" + }, + { + "enumerant" : "Union", + "value" : "2" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugTypeQualifier", + "enumerants" : [ + { + "enumerant" : "ConstType", + "value" : "0" + }, + { + "enumerant" : "VolatileType", + "value" : "1" + }, + { + "enumerant" : "RestrictType", + "value" : "2" + }, + { + "enumerant" : "AtomicType", + "value" : "3" + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugOperation", + "enumerants" : [ + { + "enumerant" : "Deref", + "value" : "0" + }, + { + "enumerant" : "Plus", + "value" : "1" + }, + { + "enumerant" : "Minus", + "value" : "2" + }, + { + "enumerant" : "PlusUconst", + "value" : "3", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "BitPiece", + "value" : "4", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Swap", + "value" : "5" + }, + { + "enumerant" : "Xderef", + "value" : "6" + }, + { + "enumerant" : "StackValue", + "value" : "7" + }, + { + "enumerant" : "Constu", + "value" : "8", + "parameters" : [ + { "kind" : "LiteralInteger" } + ] + }, + { + "enumerant" : "Fragment", + "value" : "9", + "parameters" : [ + { "kind" : "LiteralInteger" }, + { "kind" : "LiteralInteger" } + ] + } + ] + }, + { + "category" : "ValueEnum", + "kind" : "DebugImportedEntity", + "enumerants" : [ + { + "enumerant" : "ImportedModule", + "value" : "0" + }, + { + "enumerant" : "ImportedDeclaration", + "value" : "1" + } + ] + } + ] +} diff --git a/source/operand.cpp b/source/operand.cpp index cd26a3d1a..39d17a687 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -29,6 +29,7 @@ // per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 #include "operand.kinds-unified1.inc" +#include "spirv-tools/libspirv.h" static const spv_operand_table_t kOperandTable = { ARRAY_SIZE(pygen_variable_OperandInfoTable), @@ -228,6 +229,18 @@ const char* spvOperandTypeStr(spv_operand_type_t type) { return "debug type qualifier"; case SPV_OPERAND_TYPE_DEBUG_OPERATION: return "debug operation"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: + return "OpenCL.DebugInfo.100 debug info flags"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + return "OpenCL.DebugInfo.100 debug base type encoding"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + return "OpenCL.DebugInfo.100 debug composite type"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + return "OpenCL.DebugInfo.100 debug type qualifier"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + return "OpenCL.DebugInfo.100 debug operation"; + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: + return "OpenCL.DebugInfo.100 debug imported entity"; // The next values are for values returned from an instruction, not actually // an operand. So the specific strings don't matter. But let's add them @@ -312,6 +325,11 @@ bool spvOperandIsConcrete(spv_operand_type_t type) { case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE: case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER: case SPV_OPERAND_TYPE_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY: return true; default: break; @@ -328,6 +346,7 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) { case SPV_OPERAND_TYPE_FUNCTION_CONTROL: case SPV_OPERAND_TYPE_MEMORY_ACCESS: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: return true; default: break; diff --git a/source/text.cpp b/source/text.cpp index fb475d84e..88a8e8ffa 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -400,7 +400,8 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: - case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: { + case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: + case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: { uint32_t value; if (grammar.parseMaskOperand(type, textValue, &value)) { return context->diagnostic() << "Invalid " << spvOperandTypeStr(type) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e6857e04e..70999f997 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -100,6 +100,7 @@ set(TEST_SOURCES diagnostic_test.cpp enum_string_mapping_test.cpp enum_set_test.cpp + ext_inst.cldebug100_test.cpp ext_inst.debuginfo_test.cpp ext_inst.glsl_test.cpp ext_inst.non_semantic_test.cpp diff --git a/test/ext_inst.cldebug100_test.cpp b/test/ext_inst.cldebug100_test.cpp new file mode 100644 index 000000000..4f1e10672 --- /dev/null +++ b/test/ext_inst.cldebug100_test.cpp @@ -0,0 +1,1070 @@ +// Copyright (c) 2017-2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "OpenCLDebugInfo100.h" +#include "gmock/gmock.h" +#include "source/util/string_utils.h" +#include "spirv/unified1/spirv.h" +#include "test/test_fixture.h" +#include "test/unit_spirv.h" + +// This file tests the correctness of encoding and decoding of instructions +// involving the OpenCL.DebugInfo.100 extended instruction set. +// Validation is not checked here. + +namespace spvtools { +namespace { + +using spvtest::Concatenate; +using spvtest::MakeInstruction; +using testing::Eq; +using utils::MakeVector; + +// Test values of enums vs. what is written in the spec. + +TEST(ExtInstCLDebugInfo, InstructionValues) { + EXPECT_EQ(0, OpenCLDebugInfo100DebugInfoNone); + EXPECT_EQ(1, OpenCLDebugInfo100DebugCompilationUnit); + EXPECT_EQ(2, OpenCLDebugInfo100DebugTypeBasic); + EXPECT_EQ(3, OpenCLDebugInfo100DebugTypePointer); + EXPECT_EQ(4, OpenCLDebugInfo100DebugTypeQualifier); + EXPECT_EQ(5, OpenCLDebugInfo100DebugTypeArray); + EXPECT_EQ(6, OpenCLDebugInfo100DebugTypeVector); + EXPECT_EQ(7, OpenCLDebugInfo100DebugTypedef); + EXPECT_EQ(8, OpenCLDebugInfo100DebugTypeFunction); + EXPECT_EQ(9, OpenCLDebugInfo100DebugTypeEnum); + EXPECT_EQ(10, OpenCLDebugInfo100DebugTypeComposite); + EXPECT_EQ(11, OpenCLDebugInfo100DebugTypeMember); + EXPECT_EQ(12, OpenCLDebugInfo100DebugTypeInheritance); + EXPECT_EQ(13, OpenCLDebugInfo100DebugTypePtrToMember); + EXPECT_EQ(14, OpenCLDebugInfo100DebugTypeTemplate); + EXPECT_EQ(15, OpenCLDebugInfo100DebugTypeTemplateParameter); + EXPECT_EQ(16, OpenCLDebugInfo100DebugTypeTemplateTemplateParameter); + EXPECT_EQ(17, OpenCLDebugInfo100DebugTypeTemplateParameterPack); + EXPECT_EQ(18, OpenCLDebugInfo100DebugGlobalVariable); + EXPECT_EQ(19, OpenCLDebugInfo100DebugFunctionDeclaration); + EXPECT_EQ(20, OpenCLDebugInfo100DebugFunction); + EXPECT_EQ(21, OpenCLDebugInfo100DebugLexicalBlock); + EXPECT_EQ(22, OpenCLDebugInfo100DebugLexicalBlockDiscriminator); + EXPECT_EQ(23, OpenCLDebugInfo100DebugScope); + EXPECT_EQ(24, OpenCLDebugInfo100DebugNoScope); + EXPECT_EQ(25, OpenCLDebugInfo100DebugInlinedAt); + EXPECT_EQ(26, OpenCLDebugInfo100DebugLocalVariable); + EXPECT_EQ(27, OpenCLDebugInfo100DebugInlinedVariable); + EXPECT_EQ(28, OpenCLDebugInfo100DebugDeclare); + EXPECT_EQ(29, OpenCLDebugInfo100DebugValue); + EXPECT_EQ(30, OpenCLDebugInfo100DebugOperation); + EXPECT_EQ(31, OpenCLDebugInfo100DebugExpression); + EXPECT_EQ(32, OpenCLDebugInfo100DebugMacroDef); + EXPECT_EQ(33, OpenCLDebugInfo100DebugMacroUndef); + EXPECT_EQ(34, OpenCLDebugInfo100DebugImportedEntity); + EXPECT_EQ(35, OpenCLDebugInfo100DebugSource); +} + +TEST(ExtInstCLDebugInfo, InfoFlagValues) { + EXPECT_EQ(1 << 0, OpenCLDebugInfo100FlagIsProtected); + EXPECT_EQ(1 << 1, OpenCLDebugInfo100FlagIsPrivate); + EXPECT_EQ(((1 << 0) | (1 << 1)), OpenCLDebugInfo100FlagIsPublic); + EXPECT_EQ(1 << 2, OpenCLDebugInfo100FlagIsLocal); + EXPECT_EQ(1 << 3, OpenCLDebugInfo100FlagIsDefinition); + EXPECT_EQ(1 << 4, OpenCLDebugInfo100FlagFwdDecl); + EXPECT_EQ(1 << 5, OpenCLDebugInfo100FlagArtificial); + EXPECT_EQ(1 << 6, OpenCLDebugInfo100FlagExplicit); + EXPECT_EQ(1 << 7, OpenCLDebugInfo100FlagPrototyped); + EXPECT_EQ(1 << 8, OpenCLDebugInfo100FlagObjectPointer); + EXPECT_EQ(1 << 9, OpenCLDebugInfo100FlagStaticMember); + EXPECT_EQ(1 << 10, OpenCLDebugInfo100FlagIndirectVariable); + EXPECT_EQ(1 << 11, OpenCLDebugInfo100FlagLValueReference); + EXPECT_EQ(1 << 12, OpenCLDebugInfo100FlagRValueReference); + EXPECT_EQ(1 << 13, OpenCLDebugInfo100FlagIsOptimized); + EXPECT_EQ(1 << 14, OpenCLDebugInfo100FlagIsEnumClass); + EXPECT_EQ(1 << 15, OpenCLDebugInfo100FlagTypePassByValue); + EXPECT_EQ(1 << 16, OpenCLDebugInfo100FlagTypePassByReference); +} + +TEST(ExtInstCLDebugInfo, BaseTypeAttributeEndodingValues) { + EXPECT_EQ(0, OpenCLDebugInfo100Unspecified); + EXPECT_EQ(1, OpenCLDebugInfo100Address); + EXPECT_EQ(2, OpenCLDebugInfo100Boolean); + EXPECT_EQ(3, OpenCLDebugInfo100Float); + EXPECT_EQ(4, OpenCLDebugInfo100Signed); + EXPECT_EQ(5, OpenCLDebugInfo100SignedChar); + EXPECT_EQ(6, OpenCLDebugInfo100Unsigned); + EXPECT_EQ(7, OpenCLDebugInfo100UnsignedChar); +} + +TEST(ExtInstCLDebugInfo, CompositeTypeValues) { + EXPECT_EQ(0, OpenCLDebugInfo100Class); + EXPECT_EQ(1, OpenCLDebugInfo100Structure); + EXPECT_EQ(2, OpenCLDebugInfo100Union); +} + +TEST(ExtInstCLDebugInfo, TypeQualifierValues) { + EXPECT_EQ(0, OpenCLDebugInfo100ConstType); + EXPECT_EQ(1, OpenCLDebugInfo100VolatileType); + EXPECT_EQ(2, OpenCLDebugInfo100RestrictType); + EXPECT_EQ(3, OpenCLDebugInfo100AtomicType); +} + +TEST(ExtInstCLDebugInfo, DebugOperationValues) { + EXPECT_EQ(0, OpenCLDebugInfo100Deref); + EXPECT_EQ(1, OpenCLDebugInfo100Plus); + EXPECT_EQ(2, OpenCLDebugInfo100Minus); + EXPECT_EQ(3, OpenCLDebugInfo100PlusUconst); + EXPECT_EQ(4, OpenCLDebugInfo100BitPiece); + EXPECT_EQ(5, OpenCLDebugInfo100Swap); + EXPECT_EQ(6, OpenCLDebugInfo100Xderef); + EXPECT_EQ(7, OpenCLDebugInfo100StackValue); + EXPECT_EQ(8, OpenCLDebugInfo100Constu); + EXPECT_EQ(9, OpenCLDebugInfo100Fragment); +} + +TEST(ExtInstCLDebugInfo, ImportedEntityValues) { + EXPECT_EQ(0, OpenCLDebugInfo100ImportedModule); + EXPECT_EQ(1, OpenCLDebugInfo100ImportedDeclaration); +} + +// Test round trip through assembler and disassembler. + +struct InstructionCase { + uint32_t opcode; + std::string name; + std::string operands; + std::vector expected_operands; +}; + +using ExtInstCLDebugInfo100RoundTripTest = + spvtest::TextToBinaryTestBase<::testing::TestWithParam>; +using ExtInstCLDebugInfo100RoundTripTestExplicit = spvtest::TextToBinaryTest; + +TEST_P(ExtInstCLDebugInfo100RoundTripTest, ParameterizedExtInst) { + const std::string input = + "%1 = OpExtInstImport \"OpenCL.DebugInfo.100\"\n" + "%3 = OpExtInst %2 %1 " + + GetParam().name + GetParam().operands + "\n"; + // First make sure it assembles correctly. + std::cout << input << std::endl; + EXPECT_THAT(CompiledInstructions(input), + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, + MakeVector("OpenCL.DebugInfo.100")), + MakeInstruction(SpvOpExtInst, {2, 3, 1, GetParam().opcode}, + GetParam().expected_operands)}))) + << input; + // Now check the round trip through the disassembler. + EXPECT_THAT(EncodeAndDecodeSuccessfully(input), input) << input; +} + +#define EPREFIX "Debug" + +#define CASE_0(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, "", {} \ + } + +#define CASE_ILL(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #L0 " " #L1, { \ + 4, L0, L1 \ + } \ + } + +#define CASE_IL(Enum, L0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 " #L0, { \ + 4, L0 \ + } \ + } + +#define CASE_I(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4", { 4 } \ + } + +#define CASE_II(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5", { 4, 5 } \ + } + +#define CASE_III(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 %6", { \ + 4, 5, 6 \ + } \ + } + +#define CASE_IIII(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 %6 %7", { \ + 4, 5, 6, 7 \ + } \ + } + +#define CASE_IIIII(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 %6 %7 %8", \ + { \ + 4, 5, 6, 7, 8 \ + } \ + } + +#define CASE_IIIIII(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 %7 %8 %9", { \ + 4, 5, 6, 7, 8, 9 \ + } \ + } + +#define CASE_IIIIIII(Enum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 %7 %8 %9 %10", { \ + 4, 5, 6, 7, 8, 9, 10 \ + } \ + } + +#define CASE_IIILLI(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7", { \ + 4, 5, 6, L0, L1, 7 \ + } \ + } + +#define CASE_IIILLIF(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 " Fstr, { \ + 4, 5, 6, L0, L1, 7, Fnum \ + } \ + } + +#define CASE_IIILLIFL(Enum, L0, L1, Fstr, Fnum, L2) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 " Fstr " " #L2, { \ + 4, 5, 6, L0, L1, 7, Fnum, L2 \ + } \ + } + +#define CASE_IIILLIL(Enum, L0, L1, L2) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 " #L2, { \ + 4, 5, 6, L0, L1, 7, L2 \ + } \ + } + +#define CASE_IE(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 " #E0, { \ + 4, uint32_t(OpenCLDebugInfo100##E0) \ + } \ + } + +#define CASE_IEIILLI(Enum, E0, L1, L2) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #E0 " %5 %6 " #L1 " " #L2 " %7", { \ + 4, uint32_t(OpenCLDebugInfo100##E0), 5, 6, L1, L2, 7 \ + } \ + } + +#define CASE_IIE(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 %5 " #E0, { \ + 4, 5, uint32_t(OpenCLDebugInfo100##E0) \ + } \ + } + +#define CASE_ISF(Enum, S0, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #S0 " " Fstr, { \ + 4, uint32_t(SpvStorageClass##S0), Fnum \ + } \ + } + +#define CASE_LII(Enum, L0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #L0 " %4 %5", \ + { \ + L0, 4, 5 \ + } \ + } + +#define CASE_LLIe(Enum, L0, L1, RawEnumName, RawEnumValue) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " " #L0 " " #L1 " %4 " RawEnumName, { \ + L0, L1, 4, RawEnumValue \ + } \ + } + +#define CASE_ILI(Enum, L0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " %4 " #L0 " %5", \ + { \ + 4, L0, 5 \ + } \ + } + +#define CASE_ILII(Enum, L0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #L0 " %5 %6", { \ + 4, L0, 5, 6 \ + } \ + } + +#define CASE_ILLII(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #L0 " " #L1 " %5 %6", { \ + 4, L0, L1, 5, 6 \ + } \ + } + +#define CASE_IIILLIIF(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr, { \ + 4, 5, 6, L0, L1, 7, 8, Fnum \ + } \ + } + +#define CASE_IIILLIIFII(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10", { \ + 4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10 \ + } \ + } + +#define CASE_IIILLIIFIIII(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10 %11 %12", { \ + 4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10, 11, 12 \ + } \ + } + +#define CASE_IIILLIIFIIIIII(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " %9 %10 %11 %12 %13 %14", { \ + 4, 5, 6, L0, L1, 7, 8, Fnum, 9, 10, 11, 12, 13, 14 \ + } \ + } + +#define CASE_IEILLIIIF(Enum, E0, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr, { \ + 4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum \ + } \ + } + +#define CASE_IEILLIIIFI(Enum, E0, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9", { \ + 4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9 \ + } \ + } + +#define CASE_IEILLIIIFII(Enum, E0, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9 %10", { \ + 4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9, 10 \ + } \ + } + +#define CASE_IEILLIIIFIII(Enum, E0, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9 %10 %11", { \ + 4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9, 10, 11 \ + } \ + } + +#define CASE_IEILLIIIFIIII(Enum, E0, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 " #E0 " %5 " #L0 " " #L1 " %6 %7 %8 " Fstr " %9 %10 %11 %12", { \ + 4, uint32_t(OpenCLDebugInfo100##E0), 5, L0, L1, 6, 7, 8, Fnum, 9, 10, \ + 11, 12 \ + } \ + } + +#define CASE_IIILLIIIF(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 %9 " Fstr, { \ + 4, 5, 6, L0, L1, 7, 8, 9, Fnum \ + } \ + } + +#define CASE_IIILLIIIFI(Enum, L0, L1, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 %9 " Fstr " %10", { \ + 4, 5, 6, L0, L1, 7, 8, 9, Fnum, 10 \ + } \ + } + +#define CASE_IIIIF(Enum, Fstr, Fnum) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 %7 " Fstr, { \ + 4, 5, 6, 7, Fnum \ + } \ + } + +#define CASE_IIILL(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1, { \ + 4, 5, 6, L0, L1 \ + } \ + } + +#define CASE_IIIILL(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 %7 " #L0 " " #L1, { \ + 4, 5, 6, 7, L0, L1 \ + } \ + } + +#define CASE_IILLI(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 " #L0 " " #L1 " %6", { \ + 4, 5, L0, L1, 6 \ + } \ + } + +#define CASE_IILLII(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 " #L0 " " #L1 " %6 %7", { \ + 4, 5, L0, L1, 6, 7 \ + } \ + } + +#define CASE_IILLIII(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 " #L0 " " #L1 " %6 %7 %8", { \ + 4, 5, L0, L1, 6, 7, 8 \ + } \ + } + +#define CASE_IILLIIII(Enum, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 " #L0 " " #L1 " %6 %7 %8 %9", { \ + 4, 5, L0, L1, 6, 7, 8, 9 \ + } \ + } + +#define CASE_IIILLIIFLI(Enum, L0, L1, Fstr, Fnum, L2) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " " #L2 " %9", { \ + 4, 5, 6, L0, L1, 7, 8, Fnum, L2, 9 \ + } \ + } + +#define CASE_IIILLIIFLII(Enum, L0, L1, Fstr, Fnum, L2) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " %4 %5 %6 " #L0 " " #L1 " %7 %8 " Fstr " " #L2 " %9 %10", { \ + 4, 5, 6, L0, L1, 7, 8, Fnum, L2, 9, 10 \ + } \ + } + +#define CASE_E(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0, { \ + uint32_t(OpenCLDebugInfo100##E0) \ + } \ + } + +#define CASE_EI(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0 " %4", { \ + uint32_t(OpenCLDebugInfo100##E0), 4 \ + } \ + } + +#define CASE_EII(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0 " %4 %5", \ + { \ + uint32_t(OpenCLDebugInfo100##E0), 4, 5 \ + } \ + } + +#define CASE_EIII(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " " #E0 " %4 %5 %6", { \ + uint32_t(OpenCLDebugInfo100##E0), 4, 5, 6 \ + } \ + } + +#define CASE_EIIII(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " " #E0 " %4 %5 %6 %7", { \ + uint32_t(OpenCLDebugInfo100##E0), 4, 5, 6, 7 \ + } \ + } + +#define CASE_EIIIII(Enum, E0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " " #E0 " %4 %5 %6 %7 %8", { \ + uint32_t(OpenCLDebugInfo100##E0), 4, 5, 6, 7, 8 \ + } \ + } + +#define CASE_EL(Enum, E0, L0) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, " " #E0 " " #L0, { \ + uint32_t(OpenCLDebugInfo100##E0), L0 \ + } \ + } + +#define CASE_ELL(Enum, E0, L0, L1) \ + { \ + uint32_t(OpenCLDebugInfo100Debug##Enum), EPREFIX #Enum, \ + " " #E0 " " #L0 " " #L1, { \ + uint32_t(OpenCLDebugInfo100##E0), L0, L1 \ + } \ + } + +// OpenCL.DebugInfo.100 4.1 Missing Debugging Information +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInfoNone, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_0(InfoNone), // enum value 0 + }))); + +// OpenCL.DebugInfo.100 4.2 Compilation Unit +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugCompilationUnit, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_LLIe(CompilationUnit, 100, 42, "HLSL", SpvSourceLanguageHLSL), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugSource, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + // TODO(dneto): Should this be a list of sourc texts, + // to accomodate length limits? + CASE_I(Source), + CASE_II(Source), + }))); + +// OpenCL.DebugInfo.100 4.3 Type instructions +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeBasic, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIE(TypeBasic, Unspecified), + CASE_IIE(TypeBasic, Address), + CASE_IIE(TypeBasic, Boolean), + CASE_IIE(TypeBasic, Float), + CASE_IIE(TypeBasic, Signed), + CASE_IIE(TypeBasic, SignedChar), + CASE_IIE(TypeBasic, Unsigned), + CASE_IIE(TypeBasic, UnsignedChar), + }))); + +// The FlagIsPublic is value is (1 << 0) | (1 << 2) which is the same +// as the bitwise-OR of FlagIsProtected and FlagIsPrivate. +// The disassembler will emit the compound expression instead. +// There is no simple fix for this. This enum is not really a mask +// for the bottom two bits. +TEST_F(ExtInstCLDebugInfo100RoundTripTestExplicit, FlagIsPublic) { + const std::string prefix = + "%1 = OpExtInstImport \"DebugInfo\"\n" + "%3 = OpExtInst %2 %1 DebugTypePointer %4 Private "; + const std::string input = prefix + "FlagIsPublic\n"; + const std::string expected = prefix + "FlagIsProtected|FlagIsPrivate\n"; + // First make sure it assembles correctly. + EXPECT_THAT( + CompiledInstructions(input), + Eq(Concatenate( + {MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("DebugInfo")), + MakeInstruction(SpvOpExtInst, + {2, 3, 1, OpenCLDebugInfo100DebugTypePointer, 4, + uint32_t(SpvStorageClassPrivate), + OpenCLDebugInfo100FlagIsPublic})}))) + << input; + // Now check the round trip through the disassembler. + EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(expected)) << input; +} + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugTypePointer, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + + //// Use each flag independently. + CASE_ISF(TypePointer, Private, "FlagIsProtected", + uint32_t(OpenCLDebugInfo100FlagIsProtected)), + CASE_ISF(TypePointer, Private, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + + // FlagIsPublic is tested above. + + CASE_ISF(TypePointer, Private, "FlagIsLocal", + uint32_t(OpenCLDebugInfo100FlagIsLocal)), + CASE_ISF(TypePointer, Private, "FlagIsDefinition", + uint32_t(OpenCLDebugInfo100FlagIsDefinition)), + CASE_ISF(TypePointer, Private, "FlagFwdDecl", + uint32_t(OpenCLDebugInfo100FlagFwdDecl)), + CASE_ISF(TypePointer, Private, "FlagArtificial", + uint32_t(OpenCLDebugInfo100FlagArtificial)), + CASE_ISF(TypePointer, Private, "FlagExplicit", + uint32_t(OpenCLDebugInfo100FlagExplicit)), + CASE_ISF(TypePointer, Private, "FlagPrototyped", + uint32_t(OpenCLDebugInfo100FlagPrototyped)), + CASE_ISF(TypePointer, Private, "FlagObjectPointer", + uint32_t(OpenCLDebugInfo100FlagObjectPointer)), + CASE_ISF(TypePointer, Private, "FlagStaticMember", + uint32_t(OpenCLDebugInfo100FlagStaticMember)), + CASE_ISF(TypePointer, Private, "FlagIndirectVariable", + uint32_t(OpenCLDebugInfo100FlagIndirectVariable)), + CASE_ISF(TypePointer, Private, "FlagLValueReference", + uint32_t(OpenCLDebugInfo100FlagLValueReference)), + CASE_ISF(TypePointer, Private, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + CASE_ISF(TypePointer, Private, "FlagIsEnumClass", + uint32_t(OpenCLDebugInfo100FlagIsEnumClass)), + CASE_ISF(TypePointer, Private, "FlagTypePassByValue", + uint32_t(OpenCLDebugInfo100FlagTypePassByValue)), + CASE_ISF(TypePointer, Private, "FlagTypePassByReference", + uint32_t(OpenCLDebugInfo100FlagTypePassByReference)), + + //// Use flags in combination, and try different storage classes. + CASE_ISF(TypePointer, Function, "FlagIsProtected|FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsProtected) | + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_ISF( + TypePointer, Workgroup, + "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsPrivate) | + uint32_t(OpenCLDebugInfo100FlagFwdDecl) | + uint32_t(OpenCLDebugInfo100FlagIndirectVariable) | + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeQualifier, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IE(TypeQualifier, ConstType), + CASE_IE(TypeQualifier, VolatileType), + CASE_IE(TypeQualifier, RestrictType), + CASE_IE(TypeQualifier, AtomicType), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeArray, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_II(TypeArray), + CASE_III(TypeArray), + CASE_IIII(TypeArray), + CASE_IIIII(TypeArray), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeVector, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IL(TypeVector, 2), + CASE_IL(TypeVector, 3), + CASE_IL(TypeVector, 4), + CASE_IL(TypeVector, 16), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypedef, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLI(Typedef, 12, 13), + CASE_IIILLI(Typedef, 14, 99), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeFunction, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_EI(TypeFunction, FlagIsProtected), + CASE_EII(TypeFunction, FlagIsDefinition), + CASE_EIII(TypeFunction, FlagArtificial), + CASE_EIIII(TypeFunction, FlagExplicit), + CASE_EIIIII(TypeFunction, FlagIsPrivate), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugTypeEnum, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLIIFII( + TypeEnum, 12, 13, + "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsPrivate) | + uint32_t(OpenCLDebugInfo100FlagFwdDecl) | + uint32_t(OpenCLDebugInfo100FlagIndirectVariable) | + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + CASE_IIILLIIFIIII(TypeEnum, 17, 18, "FlagStaticMember", + uint32_t(OpenCLDebugInfo100FlagStaticMember)), + CASE_IIILLIIFIIIIII(TypeEnum, 99, 1, "FlagStaticMember", + uint32_t(OpenCLDebugInfo100FlagStaticMember)), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugTypeComposite, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IEILLIIIF( + TypeComposite, Class, 12, 13, + "FlagIsPrivate|FlagFwdDecl|FlagIndirectVariable|FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsPrivate) | + uint32_t(OpenCLDebugInfo100FlagFwdDecl) | + uint32_t(OpenCLDebugInfo100FlagIndirectVariable) | + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + // Cover all tag values: Class, Structure, Union + CASE_IEILLIIIF(TypeComposite, Class, 12, 13, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IEILLIIIF(TypeComposite, Structure, 12, 13, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IEILLIIIF(TypeComposite, Union, 12, 13, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + // Now add members + CASE_IEILLIIIFI(TypeComposite, Class, 9, 10, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IEILLIIIFII(TypeComposite, Class, 9, 10, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IEILLIIIFIII(TypeComposite, Class, 9, 10, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IEILLIIIFIIII(TypeComposite, Class, 9, 10, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugTypeMember, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLIIIF(TypeMember, 12, 13, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IIILLIIIF(TypeMember, 99, 100, "FlagIsPrivate|FlagFwdDecl", + uint32_t(OpenCLDebugInfo100FlagIsPrivate) | + uint32_t(OpenCLDebugInfo100FlagFwdDecl)), + // Add the optional Id argument. + CASE_IIILLIIIFI(TypeMember, 12, 13, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugTypeInheritance, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIIIF(TypeInheritance, "FlagIsPrivate", + uint32_t(OpenCLDebugInfo100FlagIsPrivate)), + CASE_IIIIF(TypeInheritance, "FlagIsPrivate|FlagFwdDecl", + uint32_t(OpenCLDebugInfo100FlagIsPrivate) | + uint32_t(OpenCLDebugInfo100FlagFwdDecl)), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypePtrToMember, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_II(TypePtrToMember), + }))); + +// OpenCL.DebugInfo.100 4.4 Templates + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplate, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_II(TypeTemplate), + CASE_III(TypeTemplate), + CASE_IIII(TypeTemplate), + CASE_IIIII(TypeTemplate), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplateParameter, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIIILL(TypeTemplateParameter, 1, 2), + CASE_IIIILL(TypeTemplateParameter, 99, 102), + CASE_IIIILL(TypeTemplateParameter, 10, 7), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplateTemplateParameter, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILL(TypeTemplateTemplateParameter, 1, 2), + CASE_IIILL(TypeTemplateTemplateParameter, 99, 102), + CASE_IIILL(TypeTemplateTemplateParameter, 10, 7), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugTypeTemplateParameterPack, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IILLI(TypeTemplateParameterPack, 1, 2), + CASE_IILLII(TypeTemplateParameterPack, 99, 102), + CASE_IILLIII(TypeTemplateParameterPack, 10, 7), + CASE_IILLIIII(TypeTemplateParameterPack, 10, 7), + }))); + +// OpenCL.DebugInfo.100 4.5 Global Variables + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugGlobalVariable, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLIIIF(GlobalVariable, 1, 2, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + CASE_IIILLIIIF(GlobalVariable, 42, 43, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + CASE_IIILLIIIFI(GlobalVariable, 1, 2, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + CASE_IIILLIIIFI(GlobalVariable, 42, 43, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + }))); + +// OpenCL.DebugInfo.100 4.6 Functions + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugFunctionDeclaration, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLIIF(FunctionDeclaration, 1, 2, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized)), + CASE_IIILLIIF(FunctionDeclaration, 42, 43, "FlagFwdDecl", + uint32_t(OpenCLDebugInfo100FlagFwdDecl)), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugFunction, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLIIFLI(Function, 1, 2, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized), 3), + CASE_IIILLIIFLI(Function, 42, 43, "FlagFwdDecl", + uint32_t(OpenCLDebugInfo100FlagFwdDecl), 44), + // Add the optional declaration Id. + CASE_IIILLIIFLII(Function, 1, 2, "FlagIsOptimized", + uint32_t(OpenCLDebugInfo100FlagIsOptimized), 3), + CASE_IIILLIIFLII(Function, 42, 43, "FlagFwdDecl", + uint32_t(OpenCLDebugInfo100FlagFwdDecl), 44), + }))); + +// OpenCL.DebugInfo.100 4.7 Local Information + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugLexicalBlock, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_ILLII(LexicalBlock, 1, 2), + CASE_ILLII(LexicalBlock, 42, 43), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugLexicalBlockDiscriminator, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_ILI(LexicalBlockDiscriminator, 1), + CASE_ILI(LexicalBlockDiscriminator, 42), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugScope, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_I(Scope), + CASE_II(Scope), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugNoScope, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_0(NoScope), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInlinedAt, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_LII(InlinedAt, 1), + CASE_LII(InlinedAt, 42), + }))); + +// OpenCL.DebugInfo.100 4.8 Local Variables + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugLocalVariable, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIILLIF(LocalVariable, 1, 2, "FlagIsPrivate", + OpenCLDebugInfo100FlagIsPrivate), + CASE_IIILLIF(LocalVariable, 4, 5, "FlagIsProtected", + OpenCLDebugInfo100FlagIsProtected), + CASE_IIILLIFL(LocalVariable, 9, 99, "FlagIsProtected", + OpenCLDebugInfo100FlagIsProtected, 195), + CASE_IIILLIFL(LocalVariable, 19, 199, "FlagIsPrivate", + OpenCLDebugInfo100FlagIsPrivate, 195), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugInlinedVariable, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_II(InlinedVariable), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugDebugDeclare, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_III(Declare), + }))); + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugDebugValue, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_IIII(Value), + CASE_IIIII(Value), + CASE_IIIIII(Value), + // Test up to 3 id parameters. We can always try more. + CASE_IIIIIII(Value), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugDebugOperation, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_E(Operation, Deref), + CASE_E(Operation, Plus), + CASE_E(Operation, Minus), + CASE_EL(Operation, PlusUconst, 1), + CASE_EL(Operation, PlusUconst, 42), + CASE_ELL(Operation, BitPiece, 1, 2), + CASE_ELL(Operation, BitPiece, 4, 5), + CASE_E(Operation, Swap), + CASE_E(Operation, Xderef), + CASE_E(Operation, StackValue), + CASE_EL(Operation, Constu, 1), + CASE_EL(Operation, Constu, 42), + CASE_ELL(Operation, Fragment, 100, 200), + CASE_ELL(Operation, Fragment, 8, 9), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugDebugExpression, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_0(Expression), + CASE_I(Expression), + CASE_II(Expression), + CASE_III(Expression), + CASE_IIII(Expression), + CASE_IIIII(Expression), + CASE_IIIIII(Expression), + CASE_IIIIIII(Expression), + }))); + +// OpenCL.DebugInfo.100 4.9 Macros + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugMacroDef, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_ILI(MacroDef, 1), + CASE_ILI(MacroDef, 42), + CASE_ILII(MacroDef, 1), + CASE_ILII(MacroDef, 42), + }))); + +INSTANTIATE_TEST_SUITE_P(OpenCLDebugInfo100DebugMacroUndef, + ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + CASE_ILI(MacroUndef, 1), + CASE_ILI(MacroUndef, 42), + }))); + +// OpenCL.DebugInfo.100 4.10 Imported Entities + +INSTANTIATE_TEST_SUITE_P( + OpenCLDebugInfo100DebugImportedEntity, ExtInstCLDebugInfo100RoundTripTest, + ::testing::ValuesIn(std::vector({ + // ID Name + // Literal Tag + // ID Source + // ID Entity + // Literal Number Line + // Literal Number Column + // ID Parent + CASE_IEIILLI(ImportedEntity, ImportedModule, 67, 68), + CASE_IEIILLI(ImportedEntity, ImportedDeclaration, 42, 43), + }))); + +#undef EPREFIX +#undef CASE_0 +#undef CASE_ILL +#undef CASE_IL +#undef CASE_I +#undef CASE_II +#undef CASE_III +#undef CASE_IIII +#undef CASE_IIIII +#undef CASE_IIIIII +#undef CASE_IIIIIII +#undef CASE_IIILLI +#undef CASE_IIILLIL +#undef CASE_IE +#undef CASE_IEIILLI +#undef CASE_IIE +#undef CASE_ISF +#undef CASE_LII +#undef CASE_LLIe +#undef CASE_ILI +#undef CASE_ILII +#undef CASE_ILLII +#undef CASE_IIILLIF +#undef CASE_IIILLIFL +#undef CASE_IIILLIIF +#undef CASE_IIILLIIFII +#undef CASE_IIILLIIFIIII +#undef CASE_IIILLIIFIIIIII +#undef CASE_IEILLIIIF +#undef CASE_IEILLIIIFI +#undef CASE_IEILLIIIFII +#undef CASE_IEILLIIIFIII +#undef CASE_IEILLIIIFIIII +#undef CASE_IIILLIIIF +#undef CASE_IIILLIIIFI +#undef CASE_IIIIF +#undef CASE_IIILL +#undef CASE_IIIILL +#undef CASE_IILLI +#undef CASE_IILLII +#undef CASE_IILLIII +#undef CASE_IILLIIII +#undef CASE_IIILLIIFLI +#undef CASE_IIILLIIFLII +#undef CASE_E +#undef CASE_EI +#undef CASE_EII +#undef CASE_EIII +#undef CASE_EIIII +#undef CASE_EIIIII +#undef CASE_EL +#undef CASE_ELL + +} // namespace +} // namespace spvtools diff --git a/utils/check_copyright.py b/utils/check_copyright.py index cfeef80a6..969371de2 100755 --- a/utils/check_copyright.py +++ b/utils/check_copyright.py @@ -34,7 +34,7 @@ AUTHORS = ['The Khronos Group Inc.', 'Samsung Inc'] CURRENT_YEAR='2019' -YEARS = '(2014-2016|2015-2016|2016|2016-2017|2017|2018|2019)' +YEARS = '(2014-2016|2015-2016|2016|2016-2017|2017|2017-2019|2018|2019)' COPYRIGHT_RE = re.compile( 'Copyright \(c\) {} ({})'.format(YEARS, '|'.join(AUTHORS))) diff --git a/utils/generate_grammar_tables.py b/utils/generate_grammar_tables.py index f6c671e82..06fcf9448 100755 --- a/utils/generate_grammar_tables.py +++ b/utils/generate_grammar_tables.py @@ -360,14 +360,22 @@ def generate_instruction_table(inst_table): return '{}\n\n{}\n\n{}'.format(caps_arrays, exts_arrays, '\n'.join(insts)) -def generate_extended_instruction_table(inst_table, set_name): +def generate_extended_instruction_table(json_grammar, set_name, operand_kind_prefix=""): """Returns the info table containing all SPIR-V extended instructions, sorted by opcode, and prefixed by capability arrays. Arguments: - inst_table: a list containing all SPIR-V instructions. - set_name: the name of the extended instruction set. + - operand_kind_prefix: the prefix, if any, to add to the front + of operand kind names. """ + if operand_kind_prefix: + prefix_operand_kind_names(operand_kind_prefix, json_grammar) + + inst_table = json_grammar["instructions"] + set_name = set_name.replace(".", "_") + inst_table = sorted(inst_table, key=lambda k: k['opcode']) caps = [inst.get('capabilities', []) for inst in inst_table] caps_arrays = generate_capability_arrays(caps) @@ -452,6 +460,7 @@ def generate_enum_operand_kind_entry(entry, extension_map): def generate_enum_operand_kind(enum, synthetic_exts_list): """Returns the C definition for the given operand kind. + It's a static const named array of spv_operand_desc_t. Also appends to |synthetic_exts_list| a list of extension lists used. @@ -681,6 +690,26 @@ def precondition_operand_kinds(operand_kinds): return operand_kinds +def prefix_operand_kind_names(prefix, json_dict): + """Modifies json_dict, by prefixing all the operand kind names + with the given prefix. Also modifies their uses in the instructions + to match. + """ + + old_to_new = {} + for operand_kind in json_dict["operand_kinds"]: + old_name = operand_kind["kind"] + new_name = prefix + old_name + operand_kind["kind"] = new_name + old_to_new[old_name] = new_name + + for instruction in json_dict["instructions"]: + for operand in instruction.get("operands", []): + replacement = old_to_new.get(operand["kind"]) + if replacement is not None: + operand["kind"] = replacement + + def main(): import argparse parser = argparse.ArgumentParser(description='Generate SPIR-V info tables') @@ -693,6 +722,10 @@ def main(): type=str, required=False, default=None, help='input JSON grammar file for DebugInfo extended ' 'instruction set') + parser.add_argument('--extinst-cldebuginfo100-grammar', metavar='', + type=str, required=False, default=None, + help='input JSON grammar file for OpenCL.DebugInfo.100 ' + 'extended instruction set') parser.add_argument('--extinst-glsl-grammar', metavar='', type=str, required=False, default=None, help='input JSON grammar file for GLSL extended ' @@ -727,6 +760,9 @@ def main(): parser.add_argument('--vendor-insts-output', metavar='', type=str, required=False, default=None, help='output file for vendor extended instruction set') + parser.add_argument('--vendor-operand-kind-prefix', metavar='', + type=str, required=False, default=None, + help='prefix for operand kinds (to disambiguate operand type enums)') args = parser.parse_args() if (args.core_insts_output is None) != \ @@ -734,9 +770,12 @@ def main(): print('error: --core-insts-output and --operand-kinds-output ' 'should be specified together.') exit(1) - if args.operand_kinds_output and not (args.spirv_core_grammar and args.extinst_debuginfo_grammar): + if args.operand_kinds_output and not (args.spirv_core_grammar and + args.extinst_debuginfo_grammar and + args.extinst_cldebuginfo100_grammar): print('error: --operand-kinds-output requires --spirv-core-grammar ' - 'and --exinst-debuginfo-grammar') + 'and --exinst-debuginfo-grammar ' + 'and --exinst-cldebuginfo100-grammar') exit(1) if (args.glsl_insts_output is None) != \ (args.extinst_glsl_grammar is None): @@ -767,14 +806,19 @@ def main(): core_grammar = json.loads(json_file.read()) with open(args.extinst_debuginfo_grammar) as debuginfo_json_file: debuginfo_grammar = json.loads(debuginfo_json_file.read()) - instructions = [] - instructions.extend(core_grammar['instructions']) - instructions.extend(debuginfo_grammar['instructions']) - operand_kinds = [] - operand_kinds.extend(core_grammar['operand_kinds']) - operand_kinds.extend(debuginfo_grammar['operand_kinds']) - extensions = get_extension_list(instructions, operand_kinds) - operand_kinds = precondition_operand_kinds(operand_kinds) + with open(args.extinst_cldebuginfo100_grammar) as cldebuginfo100_json_file: + cldebuginfo100_grammar = json.loads(cldebuginfo100_json_file.read()) + prefix_operand_kind_names("CLDEBUG100_", cldebuginfo100_grammar) + instructions = [] + instructions.extend(core_grammar['instructions']) + instructions.extend(debuginfo_grammar['instructions']) + instructions.extend(cldebuginfo100_grammar['instructions']) + operand_kinds = [] + operand_kinds.extend(core_grammar['operand_kinds']) + operand_kinds.extend(debuginfo_grammar['operand_kinds']) + operand_kinds.extend(cldebuginfo100_grammar['operand_kinds']) + extensions = get_extension_list(instructions, operand_kinds) + operand_kinds = precondition_operand_kinds(operand_kinds) if args.core_insts_output is not None: make_path_to_file(args.core_insts_output) make_path_to_file(args.operand_kinds_output) @@ -799,7 +843,7 @@ def main(): make_path_to_file(args.glsl_insts_output) with open(args.glsl_insts_output, 'w') as f: f.write(generate_extended_instruction_table( - grammar['instructions'], 'glsl')) + grammar, 'glsl')) if args.extinst_opencl_grammar is not None: with open(args.extinst_opencl_grammar) as json_file: @@ -807,7 +851,7 @@ def main(): make_path_to_file(args.opencl_insts_output) with open(args.opencl_insts_output, 'w') as f: f.write(generate_extended_instruction_table( - grammar['instructions'], 'opencl')) + grammar, 'opencl')) if args.extinst_vendor_grammar is not None: with open(args.extinst_vendor_grammar) as json_file: @@ -818,7 +862,7 @@ def main(): name = name[start:-len('.grammar.json')].replace('-', '_') with open(args.vendor_insts_output, 'w') as f: f.write(generate_extended_instruction_table( - grammar['instructions'], name)) + grammar, name, args.vendor_operand_kind_prefix)) if __name__ == '__main__':