(root)/
gcc-13.2.0/
gcc/
testsuite/
jit.dg/
test-dot-product.c
       1  #include <stdlib.h>
       2  #include <stdio.h>
       3  #include <string.h>
       4  
       5  #include "libgccjit.h"
       6  
       7  #include "harness.h"
       8  
       9  void
      10  create_code (gcc_jit_context *ctxt, void *user_data)
      11  {
      12    /* Let's try to inject the equivalent of:
      13  
      14  	double
      15  	my_dot_product (int n, double *a, double *b)
      16  	{
      17  	  double result = 0.;
      18  	  for (int i = 0; i < n; i++)
      19  	    result += a[i] * b[i];
      20  	  return result
      21  	}
      22  
      23       and see what the optimizer can do.  */
      24    gcc_jit_type *val_type =
      25      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
      26    gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (val_type);
      27    gcc_jit_type *int_type =
      28      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
      29  
      30    gcc_jit_type *return_type = val_type;
      31    gcc_jit_param *param_n =
      32      gcc_jit_context_new_param (ctxt, NULL, int_type, "n");
      33    gcc_jit_param *param_a =
      34      gcc_jit_context_new_param (ctxt, NULL, ptr_type, "a");
      35    gcc_jit_param *param_b =
      36      gcc_jit_context_new_param (ctxt, NULL, ptr_type, "b");
      37    gcc_jit_param *params[3] = {param_n, param_a, param_b};
      38    gcc_jit_function *func =
      39      gcc_jit_context_new_function (ctxt, NULL,
      40  				  GCC_JIT_FUNCTION_EXPORTED,
      41  				  return_type,
      42  				  "my_dot_product",
      43  				  3, params, 0);
      44  
      45    gcc_jit_block *initial = gcc_jit_function_new_block (func, "initial");
      46    gcc_jit_block *loop_test = gcc_jit_function_new_block (func, "loop_test");
      47    gcc_jit_block *loop_body = gcc_jit_function_new_block (func, "loop_body");
      48    gcc_jit_block *final = gcc_jit_function_new_block (func, "final");
      49  
      50    /* Build: "double result = 0.;" */
      51    gcc_jit_lvalue *result =
      52      gcc_jit_function_new_local (func, NULL, val_type, "result");
      53  
      54    gcc_jit_block_add_assignment (initial, NULL,
      55      result, gcc_jit_context_zero (ctxt, val_type));
      56  
      57    /* Build: "for (int i = 0; i < n; i++)" */
      58    gcc_jit_lvalue *i =
      59      gcc_jit_function_new_local (func, NULL, int_type, "i");
      60    gcc_jit_block_add_assignment (initial, NULL,
      61      i, gcc_jit_context_zero (ctxt, int_type));
      62  
      63    gcc_jit_block_end_with_jump (initial, NULL, loop_test);
      64  
      65    gcc_jit_block_end_with_conditional (
      66      loop_test, NULL,
      67  
      68      /* (i < n) */
      69      gcc_jit_context_new_comparison (
      70        ctxt, NULL,
      71        GCC_JIT_COMPARISON_LT,
      72        gcc_jit_lvalue_as_rvalue (i),
      73        gcc_jit_param_as_rvalue (param_n)),
      74  
      75      loop_body,
      76      final);
      77  
      78    /* Build: "result += a[i] * b[i];" */
      79    gcc_jit_block_add_assignment_op (
      80      loop_body, NULL,
      81      result,
      82      GCC_JIT_BINARY_OP_PLUS,
      83      gcc_jit_context_new_binary_op (
      84        ctxt, NULL,
      85        GCC_JIT_BINARY_OP_MULT,
      86        val_type,
      87        gcc_jit_lvalue_as_rvalue (
      88  	gcc_jit_context_new_array_access (
      89            ctxt, NULL,
      90  	  gcc_jit_param_as_rvalue (param_a),
      91  	  gcc_jit_lvalue_as_rvalue (i))),
      92        gcc_jit_lvalue_as_rvalue (
      93  	gcc_jit_context_new_array_access (
      94            ctxt, NULL,
      95  	  gcc_jit_param_as_rvalue (param_b),
      96  	  gcc_jit_lvalue_as_rvalue (i)))));
      97  
      98    /* Build: "i++" */
      99    gcc_jit_block_add_assignment_op (
     100      loop_body, NULL,
     101      i,
     102      GCC_JIT_BINARY_OP_PLUS,
     103      gcc_jit_context_one (ctxt, int_type));
     104  
     105    gcc_jit_block_end_with_jump (loop_body, NULL, loop_test);
     106  
     107    /* Build: "return result;" */
     108    gcc_jit_block_end_with_return (
     109      final,
     110      NULL,
     111      gcc_jit_lvalue_as_rvalue (result));
     112  }
     113  
     114  void
     115  verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
     116  {
     117    typedef double (*my_dot_product_fn_type) (int n, double *a, double *b);
     118    CHECK_NON_NULL (result);
     119  
     120    my_dot_product_fn_type my_dot_product =
     121      (my_dot_product_fn_type)gcc_jit_result_get_code (result,
     122  						     "my_dot_product");
     123    CHECK_NON_NULL (my_dot_product);
     124    double test_array[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
     125    double val = my_dot_product (10, test_array, test_array);
     126    note ("my_dot_product returned: %f", val);
     127    CHECK_VALUE (val, 385.0);
     128  }
     129