Skip to content

Commit 7f2995c

Browse files
authored
Merge pull request #22 from GuillaumeGomez/const-attr
Add support for const attribute in libgccjit
2 parents 03a7071 + 65eb3d5 commit 7f2995c

File tree

4 files changed

+143
-1
lines changed

4 files changed

+143
-1
lines changed

gcc/jit/jit-playback.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ const char* fn_attribute_to_string(gcc_jit_fn_attribute attr)
531531
return "cold";
532532
case GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE:
533533
return "returns_twice";
534+
case GCC_JIT_FN_ATTRIBUTE_PURE:
535+
return "pure";
536+
case GCC_JIT_FN_ATTRIBUTE_CONST:
537+
return "const";
534538
}
535539
return NULL;
536540
}
@@ -675,6 +679,9 @@ new_function (location *loc,
675679
/* See handle_pure_attribute in gcc/c-family/c-attribs.cc. */
676680
else if (attr == GCC_JIT_FN_ATTRIBUTE_PURE)
677681
DECL_PURE_P (fndecl) = 1;
682+
/* See handle_const_attribute in gcc/c-family/c-attribs.cc. */
683+
else if (attr == GCC_JIT_FN_ATTRIBUTE_CONST)
684+
TREE_READONLY (fndecl) = 1;
678685

679686
const char* attribute = fn_attribute_to_string (attr);
680687
if (attribute)

gcc/jit/libgccjit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,6 +2106,7 @@ enum gcc_jit_fn_attribute
21062106
GCC_JIT_FN_ATTRIBUTE_COLD,
21072107
GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE,
21082108
GCC_JIT_FN_ATTRIBUTE_PURE,
2109+
GCC_JIT_FN_ATTRIBUTE_CONST,
21092110
};
21102111

21112112
/* Add an attribute to a function. */
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/* { dg-do compile { target x86_64-*-* } } */
2+
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
6+
#include "libgccjit.h"
7+
8+
/* We don't want set_options() in harness.h to set -O3 to see that the const
9+
attribute affects the optimizations. */
10+
#define TEST_ESCHEWS_SET_OPTIONS
11+
static void set_options (gcc_jit_context *ctxt, const char *argv0)
12+
{
13+
// Set "-O3".
14+
gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
15+
}
16+
17+
#define TEST_COMPILING_TO_FILE
18+
#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER
19+
#define OUTPUT_FILENAME "output-of-test-const-attribute.c.s"
20+
#include "harness.h"
21+
22+
void
23+
create_code (gcc_jit_context *ctxt, void *user_data)
24+
{
25+
/* Let's try to inject the equivalent of:
26+
__attribute__ ((const))
27+
int foo (int x);
28+
int xxx(void)
29+
{
30+
int x = 45;
31+
int sum = 0;
32+
33+
while (x >>= 1)
34+
sum += foo (x) * 2;
35+
return sum;
36+
}
37+
*/
38+
gcc_jit_type *int_type =
39+
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
40+
41+
/* Creating the `foo` function. */
42+
gcc_jit_param *n =
43+
gcc_jit_context_new_param (ctxt, NULL, int_type, "x");
44+
gcc_jit_param *params[1] = {n};
45+
gcc_jit_function *foo_func =
46+
gcc_jit_context_new_function (ctxt, NULL,
47+
GCC_JIT_FUNCTION_IMPORTED,
48+
int_type,
49+
"foo",
50+
1, params,
51+
0);
52+
gcc_jit_function_add_attribute(foo_func, GCC_JIT_FN_ATTRIBUTE_CONST);
53+
54+
/* Creating the `xxx` function. */
55+
gcc_jit_function *xxx_func =
56+
gcc_jit_context_new_function (ctxt, NULL,
57+
GCC_JIT_FUNCTION_EXPORTED,
58+
int_type,
59+
"xxx",
60+
0, NULL,
61+
0);
62+
63+
gcc_jit_block *block = gcc_jit_function_new_block (xxx_func, NULL);
64+
65+
/* Build locals: */
66+
gcc_jit_lvalue *x =
67+
gcc_jit_function_new_local (xxx_func, NULL, int_type, "x");
68+
gcc_jit_lvalue *sum =
69+
gcc_jit_function_new_local (xxx_func, NULL, int_type, "sum");
70+
71+
/* int x = 45 */
72+
gcc_jit_block_add_assignment (
73+
block, NULL,
74+
x,
75+
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 45));
76+
/* int sum = 0 */
77+
gcc_jit_block_add_assignment (
78+
block, NULL,
79+
sum,
80+
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0));
81+
82+
/* while (x >>= 1) { sum += foo (x) * 2; } */
83+
gcc_jit_block *loop_cond =
84+
gcc_jit_function_new_block (xxx_func, "loop_cond");
85+
gcc_jit_block *loop_body =
86+
gcc_jit_function_new_block (xxx_func, "loop_body");
87+
gcc_jit_block *after_loop =
88+
gcc_jit_function_new_block (xxx_func, "after_loop");
89+
90+
gcc_jit_block_end_with_jump (block, NULL, loop_cond);
91+
92+
93+
/* if (x >>= 1) */
94+
/* Since gccjit doesn't (yet?) have support for `>>=` operator, we will decompose it into:
95+
`if (x = x >> 1)` */
96+
gcc_jit_block_add_assignment_op (
97+
loop_cond, NULL,
98+
x,
99+
GCC_JIT_BINARY_OP_RSHIFT,
100+
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1));
101+
/* The condition itself */
102+
gcc_jit_block_end_with_conditional (
103+
loop_cond, NULL,
104+
gcc_jit_context_new_comparison (
105+
ctxt, NULL,
106+
GCC_JIT_COMPARISON_NE,
107+
gcc_jit_lvalue_as_rvalue (x),
108+
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)),
109+
after_loop,
110+
loop_body);
111+
112+
/* sum += foo (x) * 2; */
113+
gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue(x);
114+
gcc_jit_block_add_assignment_op (
115+
loop_body, NULL,
116+
x,
117+
GCC_JIT_BINARY_OP_PLUS,
118+
gcc_jit_context_new_binary_op (
119+
ctxt, NULL,
120+
GCC_JIT_BINARY_OP_MULT, int_type,
121+
gcc_jit_context_new_call (ctxt, NULL, foo_func, 1, &arg),
122+
gcc_jit_context_new_rvalue_from_int (
123+
ctxt,
124+
int_type,
125+
2)));
126+
gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond);
127+
128+
/* return sum; */
129+
gcc_jit_block_end_with_return (after_loop, NULL, gcc_jit_lvalue_as_rvalue(sum));
130+
}
131+
132+
/* { dg-final { jit-verify-output-file-was-created "" } } */
133+
/* Check that the loop was optimized away */
134+
/* { dg-final { jit-verify-assembler-output-not "jne" } } */

gcc/testsuite/jit.dg/test-pure-attribute.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "libgccjit.h"
77

8-
/* We don't want set_options() in harness.h to set -O3 to see that the cold
8+
/* We don't want set_options() in harness.h to set -O3 to see that the pure
99
attribute affects the optimizations. */
1010
#define TEST_ESCHEWS_SET_OPTIONS
1111
static void set_options (gcc_jit_context *ctxt, const char *argv0)

0 commit comments

Comments
 (0)