test-arrays.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stddef.h>
  4. #include "libgccjit.h"
  5. #include "harness.h"
  6. #define ARRAY_SIZE (4)
  7. /* Verify that struct layout works properly when adding an array field. */
  8. struct array_holder
  9. {
  10. float m_before;
  11. int m_ints[ARRAY_SIZE];
  12. float m_after;
  13. };
  14. void
  15. create_code (gcc_jit_context *ctxt, void *user_data)
  16. {
  17. /* Let's try to inject the equivalent of:
  18. void
  19. test_array (struct array_holder *ah)
  20. {
  21. ah->m_before = 4.0f;
  22. for i in 0 to (ARRAY_SIZE - 1):
  23. ah->m_ints[i] = (i * i);
  24. ah->m_after = 2.0f;
  25. }
  26. */
  27. gcc_jit_type *void_type =
  28. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  29. gcc_jit_type *float_type =
  30. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
  31. gcc_jit_type *int_type =
  32. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  33. gcc_jit_field *field_m_before =
  34. gcc_jit_context_new_field (ctxt, NULL, float_type, "m_before");
  35. gcc_jit_field *field_m_ints =
  36. gcc_jit_context_new_field (
  37. ctxt, NULL,
  38. gcc_jit_context_new_array_type (ctxt, NULL, int_type, ARRAY_SIZE),
  39. "m_ints");
  40. gcc_jit_field *field_m_after =
  41. gcc_jit_context_new_field (ctxt, NULL, float_type, "m_after");
  42. gcc_jit_field *fields[] = {
  43. field_m_before,
  44. field_m_ints,
  45. field_m_after,
  46. };
  47. gcc_jit_struct *struct_type =
  48. gcc_jit_context_new_struct_type (
  49. ctxt,
  50. NULL,
  51. "array_holder",
  52. 3, fields);
  53. gcc_jit_type *struct_ptr_type =
  54. gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type));
  55. /* Build the test_fn. */
  56. gcc_jit_param *param_ah =
  57. gcc_jit_context_new_param (ctxt, NULL, struct_ptr_type, "ah");
  58. gcc_jit_function *func =
  59. gcc_jit_context_new_function (ctxt, NULL,
  60. GCC_JIT_FUNCTION_EXPORTED,
  61. void_type,
  62. "test_array",
  63. 1, &param_ah,
  64. 0);
  65. gcc_jit_block *initial = gcc_jit_function_new_block (func, "initial");
  66. gcc_jit_block *loop_test = gcc_jit_function_new_block (func, "loop_test");
  67. gcc_jit_block *loop_body = gcc_jit_function_new_block (func, "loop_body");
  68. gcc_jit_block *final = gcc_jit_function_new_block (func, "final");
  69. /* "ah->m_before = 4.0f;" */
  70. gcc_jit_block_add_assignment (
  71. initial, NULL,
  72. gcc_jit_rvalue_dereference_field (
  73. gcc_jit_param_as_rvalue (param_ah), NULL, field_m_before),
  74. gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 4));
  75. gcc_jit_block_add_comment (initial, NULL,
  76. "for i in 0 to (ARRAY_SIZE - 1):");
  77. gcc_jit_lvalue *i =
  78. gcc_jit_function_new_local (func, NULL, int_type, "i");
  79. gcc_jit_block_add_assignment (initial, NULL,
  80. i,
  81. gcc_jit_context_zero (ctxt, int_type));
  82. gcc_jit_block_end_with_jump (initial, NULL, loop_test);
  83. gcc_jit_block_end_with_conditional (loop_test, NULL,
  84. gcc_jit_context_new_comparison (
  85. ctxt, NULL,
  86. GCC_JIT_COMPARISON_LT,
  87. gcc_jit_lvalue_as_rvalue (i),
  88. gcc_jit_context_new_rvalue_from_int (ctxt, int_type, ARRAY_SIZE)),
  89. loop_body,
  90. final);
  91. gcc_jit_block_add_comment (loop_body, NULL, "ah->m_ints[i] = (i * i);");
  92. gcc_jit_block_add_assignment (
  93. loop_body, NULL,
  94. gcc_jit_context_new_array_access (
  95. ctxt, NULL,
  96. gcc_jit_lvalue_as_rvalue (gcc_jit_rvalue_dereference_field (
  97. gcc_jit_param_as_rvalue (param_ah),
  98. NULL,
  99. field_m_ints)),
  100. gcc_jit_lvalue_as_rvalue (i)),
  101. gcc_jit_context_new_binary_op (
  102. ctxt, NULL,
  103. GCC_JIT_BINARY_OP_MULT,
  104. int_type,
  105. gcc_jit_lvalue_as_rvalue (i),
  106. gcc_jit_lvalue_as_rvalue (i)));
  107. /* "i++" */
  108. gcc_jit_block_add_assignment_op (
  109. loop_body, NULL,
  110. i,
  111. GCC_JIT_BINARY_OP_PLUS,
  112. gcc_jit_context_one (ctxt, int_type));
  113. gcc_jit_block_end_with_jump (loop_body, NULL, loop_test);
  114. /* ah->m_after = 2.0f; */
  115. gcc_jit_block_add_assignment (
  116. final, NULL,
  117. gcc_jit_rvalue_dereference_field (
  118. gcc_jit_param_as_rvalue (param_ah), NULL, field_m_after),
  119. gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 2));
  120. gcc_jit_block_end_with_void_return (final, NULL);
  121. }
  122. void
  123. verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
  124. {
  125. typedef void (*fn_type) (struct array_holder *ah);
  126. CHECK_NON_NULL (result);
  127. fn_type test_array =
  128. (fn_type)gcc_jit_result_get_code (result, "test_array");
  129. CHECK_NON_NULL (test_array);
  130. struct array_holder ah;
  131. memset (&ah, 0xf0, sizeof (ah));
  132. test_array (&ah);
  133. CHECK_VALUE (ah.m_before, 4.0f);
  134. CHECK_VALUE (ah.m_ints[0], 0);
  135. CHECK_VALUE (ah.m_ints[1], 1);
  136. CHECK_VALUE (ah.m_ints[2], 4);
  137. CHECK_VALUE (ah.m_ints[3], 9);
  138. CHECK_VALUE (ah.m_after, 2.0f);
  139. }