debug_info_manager_test.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. // Copyright (c) 2020 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/opt/debug_info_manager.h"
  15. #include <memory>
  16. #include <string>
  17. #include <vector>
  18. #include "effcee/effcee.h"
  19. #include "gmock/gmock.h"
  20. #include "gtest/gtest.h"
  21. #include "source/opt/build_module.h"
  22. #include "source/opt/instruction.h"
  23. #include "spirv-tools/libspirv.hpp"
  24. // Constants for OpenCL.DebugInfo.100 extension instructions.
  25. static const uint32_t kDebugFunctionOperandFunctionIndex = 13;
  26. static const uint32_t kDebugInlinedAtOperandLineIndex = 4;
  27. static const uint32_t kDebugInlinedAtOperandScopeIndex = 5;
  28. static const uint32_t kDebugInlinedAtOperandInlinedIndex = 6;
  29. static const uint32_t kOpLineInOperandFileIndex = 0;
  30. static const uint32_t kOpLineInOperandLineIndex = 1;
  31. static const uint32_t kOpLineInOperandColumnIndex = 2;
  32. namespace spvtools {
  33. namespace opt {
  34. namespace analysis {
  35. namespace {
  36. TEST(DebugInfoManager, GetDebugInlinedAt) {
  37. const std::string text = R"(
  38. OpCapability Shader
  39. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  40. OpMemoryModel Logical GLSL450
  41. OpEntryPoint Fragment %main "main" %in_var_COLOR
  42. OpExecutionMode %main OriginUpperLeft
  43. %5 = OpString "ps.hlsl"
  44. %14 = OpString "#line 1 \"ps.hlsl\"
  45. void main(float in_var_color : COLOR) {
  46. float color = in_var_color;
  47. }
  48. "
  49. %17 = OpString "float"
  50. %21 = OpString "main"
  51. %24 = OpString "color"
  52. OpName %in_var_COLOR "in.var.COLOR"
  53. OpName %main "main"
  54. OpDecorate %in_var_COLOR Location 0
  55. %uint = OpTypeInt 32 0
  56. %uint_32 = OpConstant %uint 32
  57. %float = OpTypeFloat 32
  58. %_ptr_Input_float = OpTypePointer Input %float
  59. %void = OpTypeVoid
  60. %27 = OpTypeFunction %void
  61. %_ptr_Function_float = OpTypePointer Function %float
  62. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  63. %13 = OpExtInst %void %1 DebugExpression
  64. %15 = OpExtInst %void %1 DebugSource %5 %14
  65. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  66. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  67. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  68. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  69. %100 = OpExtInst %void %1 DebugInlinedAt 7 %22
  70. %main = OpFunction %void None %27
  71. %28 = OpLabel
  72. %31 = OpLoad %float %in_var_COLOR
  73. OpStore %100 %31
  74. OpReturn
  75. OpFunctionEnd
  76. )";
  77. std::unique_ptr<IRContext> context =
  78. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  79. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  80. DebugInfoManager manager(context.get());
  81. EXPECT_EQ(manager.GetDebugInlinedAt(150), nullptr);
  82. EXPECT_EQ(manager.GetDebugInlinedAt(31), nullptr);
  83. EXPECT_EQ(manager.GetDebugInlinedAt(22), nullptr);
  84. auto* inst = manager.GetDebugInlinedAt(100);
  85. EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
  86. EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
  87. }
  88. TEST(DebugInfoManager, CreateDebugInlinedAt) {
  89. const std::string text = R"(
  90. OpCapability Shader
  91. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  92. OpMemoryModel Logical GLSL450
  93. OpEntryPoint Fragment %main "main" %in_var_COLOR
  94. OpExecutionMode %main OriginUpperLeft
  95. %5 = OpString "ps.hlsl"
  96. %14 = OpString "#line 1 \"ps.hlsl\"
  97. void main(float in_var_color : COLOR) {
  98. float color = in_var_color;
  99. }
  100. "
  101. %17 = OpString "float"
  102. %21 = OpString "main"
  103. %24 = OpString "color"
  104. OpName %in_var_COLOR "in.var.COLOR"
  105. OpName %main "main"
  106. OpDecorate %in_var_COLOR Location 0
  107. %uint = OpTypeInt 32 0
  108. %uint_32 = OpConstant %uint 32
  109. %float = OpTypeFloat 32
  110. %_ptr_Input_float = OpTypePointer Input %float
  111. %void = OpTypeVoid
  112. %27 = OpTypeFunction %void
  113. %_ptr_Function_float = OpTypePointer Function %float
  114. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  115. %13 = OpExtInst %void %1 DebugExpression
  116. %15 = OpExtInst %void %1 DebugSource %5 %14
  117. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  118. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  119. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  120. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  121. %100 = OpExtInst %void %1 DebugInlinedAt 7 %22
  122. %main = OpFunction %void None %27
  123. %28 = OpLabel
  124. %31 = OpLoad %float %in_var_COLOR
  125. OpStore %100 %31
  126. OpReturn
  127. OpFunctionEnd
  128. )";
  129. DebugScope scope(22U, 0U);
  130. std::unique_ptr<IRContext> context =
  131. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  132. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  133. DebugInfoManager manager(context.get());
  134. uint32_t inlined_at_id = manager.CreateDebugInlinedAt(nullptr, scope);
  135. auto* inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
  136. EXPECT_NE(inlined_at, nullptr);
  137. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
  138. 1);
  139. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
  140. 22);
  141. EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
  142. const uint32_t line_number = 77U;
  143. Instruction line(context.get(), spv::Op::OpLine);
  144. line.SetInOperands({
  145. {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}},
  146. {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}},
  147. {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0U}},
  148. });
  149. inlined_at_id = manager.CreateDebugInlinedAt(&line, scope);
  150. inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
  151. EXPECT_NE(inlined_at, nullptr);
  152. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
  153. line_number);
  154. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
  155. 22);
  156. EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
  157. scope.SetInlinedAt(100U);
  158. inlined_at_id = manager.CreateDebugInlinedAt(&line, scope);
  159. inlined_at = manager.GetDebugInlinedAt(inlined_at_id);
  160. EXPECT_NE(inlined_at, nullptr);
  161. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
  162. line_number);
  163. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex),
  164. 22);
  165. EXPECT_EQ(inlined_at->NumOperands(), kDebugInlinedAtOperandInlinedIndex + 1);
  166. EXPECT_EQ(
  167. inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandInlinedIndex),
  168. 100U);
  169. }
  170. TEST(DebugInfoManager, CreateDebugInlinedAtWithConstantManager) {
  171. // Show that CreateDebugInlinedAt will use the Constant manager to generate
  172. // its line operand if the Constant and DefUse managers are valid. This is
  173. // proven by checking that the id for the line operand 7 is the same as the
  174. // existing constant 7.
  175. //
  176. // int function1() {
  177. // return 1;
  178. // }
  179. //
  180. // void main() {
  181. // function1();
  182. // }
  183. const std::string text = R"(OpCapability Shader
  184. OpExtension "SPV_KHR_non_semantic_info"
  185. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  186. OpMemoryModel Logical GLSL450
  187. OpEntryPoint Fragment %main "main"
  188. OpExecutionMode %main OriginUpperLeft
  189. %3 = OpString "parent3.hlsl"
  190. %8 = OpString "int"
  191. %19 = OpString "function1"
  192. %20 = OpString ""
  193. %26 = OpString "main"
  194. OpName %main "main"
  195. OpName %src_main "src.main"
  196. OpName %bb_entry "bb.entry"
  197. OpName %function1 "function1"
  198. OpName %bb_entry_0 "bb.entry"
  199. %int = OpTypeInt 32 1
  200. %int_1 = OpConstant %int 1
  201. %uint = OpTypeInt 32 0
  202. %uint_32 = OpConstant %uint 32
  203. %void = OpTypeVoid
  204. %uint_4 = OpConstant %uint 4
  205. %uint_0 = OpConstant %uint 0
  206. %uint_3 = OpConstant %uint 3
  207. %uint_1 = OpConstant %uint 1
  208. %uint_5 = OpConstant %uint 5
  209. %uint_2 = OpConstant %uint 2
  210. %uint_17 = OpConstant %uint 17
  211. %uint_6 = OpConstant %uint 6
  212. %uint_13 = OpConstant %uint 13
  213. %100 = OpConstant %uint 7
  214. %31 = OpTypeFunction %void
  215. %42 = OpTypeFunction %int
  216. %10 = OpExtInst %void %1 DebugTypeBasic %8 %uint_32 %uint_4 %uint_0
  217. %13 = OpExtInst %void %1 DebugTypeFunction %uint_3 %10
  218. %15 = OpExtInst %void %1 DebugSource %3
  219. %16 = OpExtInst %void %1 DebugCompilationUnit %uint_1 %uint_4 %15 %uint_5
  220. %21 = OpExtInst %void %1 DebugFunction %19 %13 %15 %uint_2 %uint_1 %16 %20 %uint_3 %uint_2
  221. %23 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_2 %uint_17 %21
  222. %25 = OpExtInst %void %1 DebugTypeFunction %uint_3 %void
  223. %27 = OpExtInst %void %1 DebugFunction %26 %25 %15 %uint_6 %uint_1 %16 %20 %uint_3 %uint_6
  224. %29 = OpExtInst %void %1 DebugLexicalBlock %15 %uint_6 %uint_13 %27
  225. %main = OpFunction %void None %31
  226. %32 = OpLabel
  227. %33 = OpFunctionCall %void %src_main
  228. OpLine %3 8 1
  229. OpReturn
  230. OpFunctionEnd
  231. OpLine %3 6 1
  232. %src_main = OpFunction %void None %31
  233. OpNoLine
  234. %bb_entry = OpLabel
  235. %47 = OpExtInst %void %1 DebugScope %27
  236. %37 = OpExtInst %void %1 DebugFunctionDefinition %27 %src_main
  237. %48 = OpExtInst %void %1 DebugScope %29
  238. OpLine %3 7 3
  239. %39 = OpFunctionCall %int %function1
  240. %49 = OpExtInst %void %1 DebugScope %27
  241. OpLine %3 8 1
  242. OpReturn
  243. %50 = OpExtInst %void %1 DebugNoScope
  244. OpFunctionEnd
  245. OpLine %3 2 1
  246. %function1 = OpFunction %int None %42
  247. OpNoLine
  248. %bb_entry_0 = OpLabel
  249. %51 = OpExtInst %void %1 DebugScope %21
  250. %45 = OpExtInst %void %1 DebugFunctionDefinition %21 %function1
  251. %52 = OpExtInst %void %1 DebugScope %23
  252. OpLine %3 3 3
  253. OpReturnValue %int_1
  254. %53 = OpExtInst %void %1 DebugNoScope
  255. OpFunctionEnd
  256. )";
  257. std::unique_ptr<IRContext> context =
  258. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  259. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  260. const uint32_t line_number = 7U;
  261. Instruction line(context.get(), spv::Op::OpLine);
  262. line.SetInOperands({
  263. {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {5U}},
  264. {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}},
  265. {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {0U}},
  266. });
  267. DebugScope scope(29U, 0U);
  268. auto db_manager = context.get()->get_debug_info_mgr();
  269. auto du_manager = context.get()->get_def_use_mgr();
  270. auto c_manager = context.get()->get_constant_mgr();
  271. (void)du_manager;
  272. (void)c_manager;
  273. uint32_t inlined_at_id = db_manager->CreateDebugInlinedAt(&line, scope);
  274. auto* inlined_at = db_manager->GetDebugInlinedAt(inlined_at_id);
  275. EXPECT_NE(inlined_at, nullptr);
  276. EXPECT_EQ(inlined_at->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex),
  277. 100);
  278. }
  279. TEST(DebugInfoManager, GetDebugInfoNone) {
  280. const std::string text = R"(
  281. OpCapability Shader
  282. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  283. OpMemoryModel Logical GLSL450
  284. OpEntryPoint Fragment %main "main" %in_var_COLOR
  285. OpExecutionMode %main OriginUpperLeft
  286. %5 = OpString "ps.hlsl"
  287. %14 = OpString "#line 1 \"ps.hlsl\"
  288. void main(float in_var_color : COLOR) {
  289. float color = in_var_color;
  290. }
  291. "
  292. %17 = OpString "float"
  293. %21 = OpString "main"
  294. %24 = OpString "color"
  295. OpName %in_var_COLOR "in.var.COLOR"
  296. OpName %main "main"
  297. OpDecorate %in_var_COLOR Location 0
  298. %uint = OpTypeInt 32 0
  299. %uint_32 = OpConstant %uint 32
  300. %float = OpTypeFloat 32
  301. %_ptr_Input_float = OpTypePointer Input %float
  302. %void = OpTypeVoid
  303. %27 = OpTypeFunction %void
  304. %_ptr_Function_float = OpTypePointer Function %float
  305. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  306. %13 = OpExtInst %void %1 DebugExpression
  307. %15 = OpExtInst %void %1 DebugSource %5 %14
  308. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  309. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  310. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  311. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  312. %12 = OpExtInst %void %1 DebugInfoNone
  313. %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
  314. %main = OpFunction %void None %27
  315. %28 = OpLabel
  316. %100 = OpVariable %_ptr_Function_float Function
  317. %31 = OpLoad %float %in_var_COLOR
  318. OpStore %100 %31
  319. %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  320. OpReturn
  321. OpFunctionEnd
  322. )";
  323. std::unique_ptr<IRContext> context =
  324. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  325. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  326. DebugInfoManager manager(context.get());
  327. Instruction* debug_info_none_inst = manager.GetDebugInfoNone();
  328. EXPECT_NE(debug_info_none_inst, nullptr);
  329. EXPECT_EQ(debug_info_none_inst->GetOpenCL100DebugOpcode(),
  330. OpenCLDebugInfo100DebugInfoNone);
  331. EXPECT_EQ(debug_info_none_inst->PreviousNode(), nullptr);
  332. }
  333. TEST(DebugInfoManager, CreateDebugInfoNone) {
  334. const std::string text = R"(
  335. OpCapability Shader
  336. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  337. OpMemoryModel Logical GLSL450
  338. OpEntryPoint Fragment %main "main" %in_var_COLOR
  339. OpExecutionMode %main OriginUpperLeft
  340. %5 = OpString "ps.hlsl"
  341. %14 = OpString "#line 1 \"ps.hlsl\"
  342. void main(float in_var_color : COLOR) {
  343. float color = in_var_color;
  344. }
  345. "
  346. %17 = OpString "float"
  347. %21 = OpString "main"
  348. %24 = OpString "color"
  349. OpName %in_var_COLOR "in.var.COLOR"
  350. OpName %main "main"
  351. OpDecorate %in_var_COLOR Location 0
  352. %uint = OpTypeInt 32 0
  353. %uint_32 = OpConstant %uint 32
  354. %float = OpTypeFloat 32
  355. %_ptr_Input_float = OpTypePointer Input %float
  356. %void = OpTypeVoid
  357. %27 = OpTypeFunction %void
  358. %_ptr_Function_float = OpTypePointer Function %float
  359. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  360. %13 = OpExtInst %void %1 DebugExpression
  361. %15 = OpExtInst %void %1 DebugSource %5 %14
  362. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  363. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  364. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  365. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  366. %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
  367. %main = OpFunction %void None %27
  368. %28 = OpLabel
  369. %100 = OpVariable %_ptr_Function_float Function
  370. %31 = OpLoad %float %in_var_COLOR
  371. OpStore %100 %31
  372. %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  373. OpReturn
  374. OpFunctionEnd
  375. )";
  376. std::unique_ptr<IRContext> context =
  377. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  378. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  379. DebugInfoManager manager(context.get());
  380. Instruction* debug_info_none_inst = manager.GetDebugInfoNone();
  381. EXPECT_NE(debug_info_none_inst, nullptr);
  382. EXPECT_EQ(debug_info_none_inst->GetOpenCL100DebugOpcode(),
  383. OpenCLDebugInfo100DebugInfoNone);
  384. EXPECT_EQ(debug_info_none_inst->PreviousNode(), nullptr);
  385. }
  386. TEST(DebugInfoManager, GetDebugFunction) {
  387. const std::string text = R"(
  388. OpCapability Shader
  389. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  390. OpMemoryModel Logical GLSL450
  391. OpEntryPoint Fragment %200 "200" %in_var_COLOR
  392. OpExecutionMode %200 OriginUpperLeft
  393. %5 = OpString "ps.hlsl"
  394. %14 = OpString "#line 1 \"ps.hlsl\"
  395. void 200(float in_var_color : COLOR) {
  396. float color = in_var_color;
  397. }
  398. "
  399. %17 = OpString "float"
  400. %21 = OpString "200"
  401. %24 = OpString "color"
  402. OpName %in_var_COLOR "in.var.COLOR"
  403. OpName %200 "200"
  404. OpDecorate %in_var_COLOR Location 0
  405. %uint = OpTypeInt 32 0
  406. %uint_32 = OpConstant %uint 32
  407. %float = OpTypeFloat 32
  408. %_ptr_Input_float = OpTypePointer Input %float
  409. %void = OpTypeVoid
  410. %27 = OpTypeFunction %void
  411. %_ptr_Function_float = OpTypePointer Function %float
  412. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  413. %13 = OpExtInst %void %1 DebugExpression
  414. %15 = OpExtInst %void %1 DebugSource %5 %14
  415. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  416. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  417. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  418. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %200
  419. %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
  420. %200 = OpFunction %void None %27
  421. %28 = OpLabel
  422. %100 = OpVariable %_ptr_Function_float Function
  423. %31 = OpLoad %float %in_var_COLOR
  424. OpStore %100 %31
  425. %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  426. OpReturn
  427. OpFunctionEnd
  428. )";
  429. std::unique_ptr<IRContext> context =
  430. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  431. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  432. DebugInfoManager manager(context.get());
  433. EXPECT_EQ(manager.GetDebugFunction(100), nullptr);
  434. EXPECT_EQ(manager.GetDebugFunction(150), nullptr);
  435. Instruction* dbg_fn = manager.GetDebugFunction(200);
  436. EXPECT_EQ(dbg_fn->GetOpenCL100DebugOpcode(), OpenCLDebugInfo100DebugFunction);
  437. EXPECT_EQ(dbg_fn->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex),
  438. 200);
  439. }
  440. TEST(DebugInfoManager, GetDebugFunction_InlinedAway) {
  441. // struct PS_INPUT
  442. // {
  443. // float4 iColor : COLOR;
  444. // };
  445. //
  446. // struct PS_OUTPUT
  447. // {
  448. // float4 oColor : SV_Target0;
  449. // };
  450. //
  451. // float4 foo(float4 ic)
  452. // {
  453. // float4 c = ic / 2.0;
  454. // return c;
  455. // }
  456. //
  457. // PS_OUTPUT MainPs(PS_INPUT i)
  458. // {
  459. // PS_OUTPUT ps_output;
  460. // float4 ic = i.iColor;
  461. // ps_output.oColor = foo(ic);
  462. // return ps_output;
  463. // }
  464. const std::string text = R"(
  465. OpCapability Shader
  466. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  467. OpMemoryModel Logical GLSL450
  468. OpEntryPoint Fragment %MainPs "MainPs" %in_var_COLOR %out_var_SV_Target0
  469. OpExecutionMode %MainPs OriginUpperLeft
  470. %15 = OpString "foo2.frag"
  471. %19 = OpString "PS_OUTPUT"
  472. %23 = OpString "float"
  473. %26 = OpString "oColor"
  474. %28 = OpString "PS_INPUT"
  475. %31 = OpString "iColor"
  476. %33 = OpString "foo"
  477. %37 = OpString "c"
  478. %39 = OpString "ic"
  479. %42 = OpString "src.MainPs"
  480. %47 = OpString "ps_output"
  481. %50 = OpString "i"
  482. OpName %in_var_COLOR "in.var.COLOR"
  483. OpName %out_var_SV_Target0 "out.var.SV_Target0"
  484. OpName %MainPs "MainPs"
  485. OpDecorate %in_var_COLOR Location 0
  486. OpDecorate %out_var_SV_Target0 Location 0
  487. %int = OpTypeInt 32 1
  488. %int_0 = OpConstant %int 0
  489. %float = OpTypeFloat 32
  490. %v4float = OpTypeVector %float 4
  491. %uint = OpTypeInt 32 0
  492. %uint_32 = OpConstant %uint 32
  493. %_ptr_Input_v4float = OpTypePointer Input %v4float
  494. %_ptr_Output_v4float = OpTypePointer Output %v4float
  495. %void = OpTypeVoid
  496. %uint_128 = OpConstant %uint 128
  497. %uint_0 = OpConstant %uint 0
  498. %52 = OpTypeFunction %void
  499. %in_var_COLOR = OpVariable %_ptr_Input_v4float Input
  500. %out_var_SV_Target0 = OpVariable %_ptr_Output_v4float Output
  501. %float_0_5 = OpConstant %float 0.5
  502. %130 = OpConstantComposite %v4float %float_0_5 %float_0_5 %float_0_5 %float_0_5
  503. %115 = OpExtInst %void %1 DebugInfoNone
  504. %49 = OpExtInst %void %1 DebugExpression
  505. %17 = OpExtInst %void %1 DebugSource %15
  506. %18 = OpExtInst %void %1 DebugCompilationUnit 1 4 %17 HLSL
  507. %21 = OpExtInst %void %1 DebugTypeComposite %19 Structure %17 6 1 %18 %19 %uint_128 FlagIsProtected|FlagIsPrivate %22
  508. %24 = OpExtInst %void %1 DebugTypeBasic %23 %uint_32 Float
  509. %25 = OpExtInst %void %1 DebugTypeVector %24 4
  510. %22 = OpExtInst %void %1 DebugTypeMember %26 %25 %17 8 5 %21 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  511. %29 = OpExtInst %void %1 DebugTypeComposite %28 Structure %17 1 1 %18 %28 %uint_128 FlagIsProtected|FlagIsPrivate %30
  512. %30 = OpExtInst %void %1 DebugTypeMember %31 %25 %17 3 5 %29 %uint_0 %uint_128 FlagIsProtected|FlagIsPrivate
  513. %32 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %25 %25
  514. %34 = OpExtInst %void %1 DebugFunction %33 %32 %17 11 1 %18 %33 FlagIsProtected|FlagIsPrivate 12 %115
  515. %36 = OpExtInst %void %1 DebugLexicalBlock %17 12 1 %34
  516. %38 = OpExtInst %void %1 DebugLocalVariable %37 %25 %17 13 12 %36 FlagIsLocal
  517. %41 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %21 %29
  518. %43 = OpExtInst %void %1 DebugFunction %42 %41 %17 17 1 %18 %42 FlagIsProtected|FlagIsPrivate 18 %115
  519. %45 = OpExtInst %void %1 DebugLexicalBlock %17 18 1 %43
  520. %46 = OpExtInst %void %1 DebugLocalVariable %39 %25 %17 20 12 %45 FlagIsLocal
  521. %48 = OpExtInst %void %1 DebugLocalVariable %47 %21 %17 19 15 %45 FlagIsLocal
  522. %107 = OpExtInst %void %1 DebugInlinedAt 21 %45
  523. %MainPs = OpFunction %void None %52
  524. %53 = OpLabel
  525. %57 = OpLoad %v4float %in_var_COLOR
  526. %131 = OpExtInst %void %1 DebugScope %45
  527. OpLine %15 20 12
  528. %117 = OpExtInst %void %1 DebugValue %46 %57 %49
  529. %132 = OpExtInst %void %1 DebugScope %36 %107
  530. OpLine %15 13 19
  531. %112 = OpFMul %v4float %57 %130
  532. OpLine %15 13 12
  533. %116 = OpExtInst %void %1 DebugValue %38 %112 %49
  534. %133 = OpExtInst %void %1 DebugScope %45
  535. %128 = OpExtInst %void %1 DebugValue %48 %112 %49 %int_0
  536. %134 = OpExtInst %void %1 DebugNoScope
  537. OpStore %out_var_SV_Target0 %112
  538. OpReturn
  539. OpFunctionEnd
  540. )";
  541. std::unique_ptr<IRContext> context =
  542. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  543. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  544. DebugInfoManager manager(context.get());
  545. EXPECT_EQ(manager.GetDebugFunction(115), nullptr);
  546. }
  547. TEST(DebugInfoManager, CloneDebugInlinedAt) {
  548. const std::string text = R"(
  549. OpCapability Shader
  550. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  551. OpMemoryModel Logical GLSL450
  552. OpEntryPoint Fragment %main "main" %in_var_COLOR
  553. OpExecutionMode %main OriginUpperLeft
  554. %5 = OpString "ps.hlsl"
  555. %14 = OpString "#line 1 \"ps.hlsl\"
  556. void main(float in_var_color : COLOR) {
  557. float color = in_var_color;
  558. }
  559. "
  560. %17 = OpString "float"
  561. %21 = OpString "main"
  562. %24 = OpString "color"
  563. OpName %in_var_COLOR "in.var.COLOR"
  564. OpName %main "main"
  565. OpDecorate %in_var_COLOR Location 0
  566. %uint = OpTypeInt 32 0
  567. %uint_32 = OpConstant %uint 32
  568. %float = OpTypeFloat 32
  569. %_ptr_Input_float = OpTypePointer Input %float
  570. %void = OpTypeVoid
  571. %27 = OpTypeFunction %void
  572. %_ptr_Function_float = OpTypePointer Function %float
  573. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  574. %13 = OpExtInst %void %1 DebugExpression
  575. %15 = OpExtInst %void %1 DebugSource %5 %14
  576. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  577. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  578. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  579. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  580. %100 = OpExtInst %void %1 DebugInlinedAt 7 %22
  581. %main = OpFunction %void None %27
  582. %28 = OpLabel
  583. %31 = OpLoad %float %in_var_COLOR
  584. OpStore %100 %31
  585. OpReturn
  586. OpFunctionEnd
  587. )";
  588. std::unique_ptr<IRContext> context =
  589. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  590. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  591. DebugInfoManager manager(context.get());
  592. EXPECT_EQ(manager.CloneDebugInlinedAt(150), nullptr);
  593. EXPECT_EQ(manager.CloneDebugInlinedAt(22), nullptr);
  594. auto* inst = manager.CloneDebugInlinedAt(100);
  595. EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
  596. EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
  597. EXPECT_EQ(inst->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
  598. Instruction* before_100 = nullptr;
  599. for (auto it = context->module()->ext_inst_debuginfo_begin();
  600. it != context->module()->ext_inst_debuginfo_end(); ++it) {
  601. if (it->result_id() == 100) break;
  602. before_100 = &*it;
  603. }
  604. EXPECT_NE(inst, before_100);
  605. inst = manager.CloneDebugInlinedAt(100, manager.GetDebugInlinedAt(100));
  606. EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandLineIndex), 7);
  607. EXPECT_EQ(inst->GetSingleWordOperand(kDebugInlinedAtOperandScopeIndex), 22);
  608. EXPECT_EQ(inst->NumOperands(), kDebugInlinedAtOperandScopeIndex + 1);
  609. before_100 = nullptr;
  610. for (auto it = context->module()->ext_inst_debuginfo_begin();
  611. it != context->module()->ext_inst_debuginfo_end(); ++it) {
  612. if (it->result_id() == 100) break;
  613. before_100 = &*it;
  614. }
  615. EXPECT_EQ(inst, before_100);
  616. }
  617. TEST(DebugInfoManager, KillDebugDeclares) {
  618. const std::string text = R"(
  619. OpCapability Shader
  620. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  621. OpMemoryModel Logical GLSL450
  622. OpEntryPoint Fragment %main "main" %in_var_COLOR
  623. OpExecutionMode %main OriginUpperLeft
  624. %5 = OpString "ps.hlsl"
  625. %14 = OpString "#line 1 \"ps.hlsl\"
  626. void main(float in_var_color : COLOR) {
  627. float color = in_var_color;
  628. }
  629. "
  630. %17 = OpString "float"
  631. %21 = OpString "main"
  632. %24 = OpString "color"
  633. OpName %in_var_COLOR "in.var.COLOR"
  634. OpName %main "main"
  635. OpDecorate %in_var_COLOR Location 0
  636. %uint = OpTypeInt 32 0
  637. %uint_32 = OpConstant %uint 32
  638. %float = OpTypeFloat 32
  639. %_ptr_Input_float = OpTypePointer Input %float
  640. %void = OpTypeVoid
  641. %27 = OpTypeFunction %void
  642. %_ptr_Function_float = OpTypePointer Function %float
  643. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  644. %13 = OpExtInst %void %1 DebugExpression
  645. %15 = OpExtInst %void %1 DebugSource %5 %14
  646. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  647. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  648. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  649. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  650. %12 = OpExtInst %void %1 DebugInfoNone
  651. %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
  652. %main = OpFunction %void None %27
  653. %28 = OpLabel
  654. %100 = OpVariable %_ptr_Function_float Function
  655. %31 = OpLoad %float %in_var_COLOR
  656. OpStore %100 %31
  657. %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  658. %37 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  659. %38 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  660. OpReturn
  661. OpFunctionEnd
  662. )";
  663. std::unique_ptr<IRContext> context =
  664. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  665. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  666. auto* dbg_info_mgr = context->get_debug_info_mgr();
  667. auto* def_use_mgr = context->get_def_use_mgr();
  668. EXPECT_TRUE(dbg_info_mgr->IsVariableDebugDeclared(100));
  669. EXPECT_EQ(def_use_mgr->GetDef(36)->GetOpenCL100DebugOpcode(),
  670. OpenCLDebugInfo100DebugDeclare);
  671. EXPECT_EQ(def_use_mgr->GetDef(37)->GetOpenCL100DebugOpcode(),
  672. OpenCLDebugInfo100DebugDeclare);
  673. EXPECT_EQ(def_use_mgr->GetDef(38)->GetOpenCL100DebugOpcode(),
  674. OpenCLDebugInfo100DebugDeclare);
  675. dbg_info_mgr->KillDebugDeclares(100);
  676. EXPECT_EQ(def_use_mgr->GetDef(36), nullptr);
  677. EXPECT_EQ(def_use_mgr->GetDef(37), nullptr);
  678. EXPECT_EQ(def_use_mgr->GetDef(38), nullptr);
  679. EXPECT_FALSE(dbg_info_mgr->IsVariableDebugDeclared(100));
  680. }
  681. TEST(DebugInfoManager, AddDebugValueForDecl) {
  682. const std::string text = R"(
  683. OpCapability Shader
  684. %1 = OpExtInstImport "OpenCL.DebugInfo.100"
  685. OpMemoryModel Logical GLSL450
  686. OpEntryPoint Fragment %main "main" %in_var_COLOR
  687. OpExecutionMode %main OriginUpperLeft
  688. %5 = OpString "ps.hlsl"
  689. %14 = OpString "#line 1 \"ps.hlsl\"
  690. void main(float in_var_color : COLOR) {
  691. float color = in_var_color;
  692. }
  693. "
  694. %17 = OpString "float"
  695. %21 = OpString "main"
  696. %24 = OpString "color"
  697. OpName %in_var_COLOR "in.var.COLOR"
  698. OpName %main "main"
  699. OpDecorate %in_var_COLOR Location 0
  700. %uint = OpTypeInt 32 0
  701. %uint_32 = OpConstant %uint 32
  702. %float = OpTypeFloat 32
  703. %_ptr_Input_float = OpTypePointer Input %float
  704. %void = OpTypeVoid
  705. %27 = OpTypeFunction %void
  706. %_ptr_Function_float = OpTypePointer Function %float
  707. %in_var_COLOR = OpVariable %_ptr_Input_float Input
  708. %13 = OpExtInst %void %1 DebugExpression
  709. %15 = OpExtInst %void %1 DebugSource %5 %14
  710. %16 = OpExtInst %void %1 DebugCompilationUnit 1 4 %15 HLSL
  711. %18 = OpExtInst %void %1 DebugTypeBasic %17 %uint_32 Float
  712. %20 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %18 %18
  713. %22 = OpExtInst %void %1 DebugFunction %21 %20 %15 1 1 %16 %21 FlagIsProtected|FlagIsPrivate 1 %main
  714. %12 = OpExtInst %void %1 DebugInfoNone
  715. %25 = OpExtInst %void %1 DebugLocalVariable %24 %18 %15 1 20 %22 FlagIsLocal 0
  716. %main = OpFunction %void None %27
  717. %28 = OpLabel
  718. %100 = OpVariable %_ptr_Function_float Function
  719. %31 = OpLoad %float %in_var_COLOR
  720. %101 = OpExtInst %void %1 DebugScope %22
  721. OpLine %5 13 7
  722. OpStore %100 %31
  723. OpNoLine
  724. %102 = OpExtInst %void %1 DebugNoScope
  725. %36 = OpExtInst %void %1 DebugDeclare %25 %100 %13
  726. OpReturn
  727. OpFunctionEnd
  728. )";
  729. std::unique_ptr<IRContext> context =
  730. BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
  731. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  732. auto* def_use_mgr = context->get_def_use_mgr();
  733. auto* dbg_decl = def_use_mgr->GetDef(36);
  734. EXPECT_EQ(dbg_decl->GetOpenCL100DebugOpcode(),
  735. OpenCLDebugInfo100DebugDeclare);
  736. auto* dbg_info_mgr = context->get_debug_info_mgr();
  737. Instruction* store = dbg_decl->PreviousNode();
  738. auto* dbg_value =
  739. dbg_info_mgr->AddDebugValueForDecl(dbg_decl, 100, dbg_decl, store);
  740. EXPECT_EQ(dbg_value->GetOpenCL100DebugOpcode(), OpenCLDebugInfo100DebugValue);
  741. EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
  742. kOpLineInOperandFileIndex),
  743. 5);
  744. EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
  745. kOpLineInOperandLineIndex),
  746. 13);
  747. EXPECT_EQ(dbg_value->dbg_line_inst()->GetSingleWordInOperand(
  748. kOpLineInOperandColumnIndex),
  749. 7);
  750. }
  751. } // namespace
  752. } // namespace analysis
  753. } // namespace opt
  754. } // namespace spvtools