Skip to content

Commit d931e8d

Browse files
authored
Merge pull request #26 from GuillaumeGomez/restrict
Add support for `restrict` attribute on function parameters
2 parents 95a2c9c + 840bab3 commit d931e8d

9 files changed

+196
-3
lines changed

gcc/jit/jit-playback.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -3812,7 +3812,7 @@ if (t) \
38123812
NAME_TYPE (complex_float_type_node, "complex float");
38133813
NAME_TYPE (complex_double_type_node, "complex double");
38143814
NAME_TYPE (complex_long_double_type_node, "complex long double");
3815-
3815+
38163816
m_const_char_ptr = build_pointer_type(
38173817
build_qualified_type (char_type_node, TYPE_QUAL_CONST));
38183818

gcc/jit/jit-playback.h

+5
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,11 @@ class type : public wrapper
490490
return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
491491
}
492492

493+
type *get_restrict () const
494+
{
495+
return new type (build_qualified_type (m_inner, TYPE_QUAL_RESTRICT));
496+
}
497+
493498
type *get_aligned (size_t alignment_in_bytes) const;
494499
type *get_vector (size_t num_units) const;
495500

gcc/jit/jit-recording.cc

+47
Original file line numberDiff line numberDiff line change
@@ -2380,6 +2380,19 @@ recording::type::get_const ()
23802380
return result;
23812381
}
23822382

2383+
/* Given a type T, get the type restrict T.
2384+
2385+
Implements the post-error-checking part of
2386+
gcc_jit_type_get_restrict. */
2387+
2388+
recording::type *
2389+
recording::type::get_restrict ()
2390+
{
2391+
recording::type *result = new memento_of_get_restrict (this);
2392+
m_ctxt->record (result);
2393+
return result;
2394+
}
2395+
23832396
/* Given a type T, get the type volatile T.
23842397
23852398
Implements the post-error-checking part of
@@ -3090,6 +3103,40 @@ recording::memento_of_get_volatile::write_reproducer (reproducer &r)
30903103
r.get_identifier_as_type (m_other_type));
30913104
}
30923105

3106+
/* The implementation of class gcc::jit::recording::memento_of_get_restrict. */
3107+
3108+
/* Implementation of pure virtual hook recording::memento::replay_into
3109+
for recording::memento_of_get_restrict. */
3110+
3111+
void
3112+
recording::memento_of_get_restrict::replay_into (replayer *)
3113+
{
3114+
set_playback_obj (m_other_type->playback_type ()->get_restrict ());
3115+
}
3116+
3117+
/* Implementation of recording::memento::make_debug_string for
3118+
results of get_restrict, prepending "restrict ". */
3119+
3120+
recording::string *
3121+
recording::memento_of_get_restrict::make_debug_string ()
3122+
{
3123+
return string::from_printf (m_ctxt,
3124+
"restrict %s", m_other_type->get_debug_string ());
3125+
}
3126+
3127+
/* Implementation of recording::memento::write_reproducer for restrict
3128+
types. */
3129+
3130+
void
3131+
recording::memento_of_get_restrict::write_reproducer (reproducer &r)
3132+
{
3133+
const char *id = r.make_identifier (this, "type");
3134+
r.write (" gcc_jit_type *%s =\n"
3135+
" gcc_jit_type_get_restrict (%s);\n",
3136+
id,
3137+
r.get_identifier_as_type (m_other_type));
3138+
}
3139+
30933140
/* The implementation of class gcc::jit::recording::memento_of_get_aligned. */
30943141

30953142
/* Implementation of pure virtual hook recording::memento::replay_into

gcc/jit/jit-recording.h

+37-2
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ class type : public memento
555555
type *get_pointer ();
556556
type *get_const ();
557557
type *get_volatile ();
558+
type *get_restrict ();
558559
type *get_aligned (size_t alignment_in_bytes);
559560
type *get_vector (size_t num_units);
560561

@@ -603,6 +604,7 @@ class type : public memento
603604
virtual bool is_bool () const = 0;
604605
virtual type *is_pointer () = 0;
605606
virtual type *is_volatile () { return NULL; }
607+
virtual type *is_restrict () { return NULL; }
606608
virtual type *is_const () { return NULL; }
607609
virtual type *is_array () = 0;
608610
virtual struct_ *is_struct () { return NULL; }
@@ -737,7 +739,7 @@ class memento_of_get_pointer : public type
737739
};
738740

739741
/* A decorated version of a type, for get_const, get_volatile,
740-
get_aligned, and get_vector. */
742+
get_aligned, get_restrict, and get_vector. */
741743

742744
class decorated_type : public type
743745
{
@@ -810,7 +812,7 @@ class memento_of_get_volatile : public decorated_type
810812
return m_other_type->is_same_type_as (other->is_volatile ());
811813
}
812814

813-
type* copy(context* ctxt) final override
815+
type* copy (context* ctxt) final override
814816
{
815817
type* result = new memento_of_get_volatile (m_other_type->copy (ctxt));
816818
ctxt->record (result);
@@ -829,6 +831,39 @@ class memento_of_get_volatile : public decorated_type
829831
void write_reproducer (reproducer &r) final override;
830832
};
831833

834+
/* Result of "gcc_jit_type_get_restrict". */
835+
class memento_of_get_restrict : public decorated_type
836+
{
837+
public:
838+
memento_of_get_restrict (type *other_type)
839+
: decorated_type (other_type) {}
840+
841+
bool is_same_type_as (type *other) final override
842+
{
843+
if (!other->is_restrict ())
844+
return false;
845+
return m_other_type->is_same_type_as (other->is_restrict ());
846+
}
847+
848+
type* copy (context* ctxt) final override
849+
{
850+
type* result = new memento_of_get_restrict (m_other_type->copy (ctxt));
851+
ctxt->record (result);
852+
return result;
853+
}
854+
855+
/* Strip off the "restrict", giving the underlying type. */
856+
type *unqualified () final override { return m_other_type; }
857+
858+
type *is_restrict () final override { return m_other_type; }
859+
860+
void replay_into (replayer *) final override;
861+
862+
private:
863+
string * make_debug_string () final override;
864+
void write_reproducer (reproducer &r) final override;
865+
};
866+
832867
/* Result of "gcc_jit_type_get_aligned". */
833868
class memento_of_get_aligned : public decorated_type
834869
{

gcc/jit/libgccjit++.h

+6
Original file line numberDiff line numberDiff line change
@@ -1410,6 +1410,12 @@ type::get_const ()
14101410
return type (gcc_jit_type_get_const (get_inner_type ()));
14111411
}
14121412

1413+
inline type
1414+
type::get_restrict ()
1415+
{
1416+
return type (gcc_jit_type_get_restrict (get_inner_type ()));
1417+
}
1418+
14131419
inline type
14141420
type::get_volatile ()
14151421
{

gcc/jit/libgccjit.cc

+14
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,20 @@ gcc_jit_type_get_volatile (gcc_jit_type *type)
539539
return (gcc_jit_type *)type->get_volatile ();
540540
}
541541

542+
/* Public entrypoint. See description in libgccjit.h.
543+
544+
After error-checking, the real work is done by the
545+
gcc::jit::recording::type::get_restrict method, in
546+
jit-recording.cc. */
547+
548+
gcc_jit_type *
549+
gcc_jit_type_get_restrict (gcc_jit_type *type)
550+
{
551+
RETURN_NULL_IF_FAIL (type, NULL, NULL, "NULL type");
552+
553+
return (gcc_jit_type *)type->get_restrict ();
554+
}
555+
542556
/* Public entrypoint. See description in libgccjit.h.
543557
544558
After error-checking, the real work is done by the

gcc/jit/libgccjit.h

+4
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,10 @@ gcc_jit_type_get_const (gcc_jit_type *type);
635635
extern gcc_jit_type *
636636
gcc_jit_type_get_volatile (gcc_jit_type *type);
637637

638+
/* Given type "T", get type "restrict T". */
639+
extern gcc_jit_type *
640+
gcc_jit_type_get_restrict (gcc_jit_type *type);
641+
638642
#define LIBGCCJIT_HAVE_SIZED_INTEGERS
639643

640644
/* Given types LTYPE and RTYPE, return non-zero if they are compatible.

gcc/jit/libgccjit.map

+5
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,8 @@ LIBGCCJIT_ABI_33 {
326326
gcc_jit_target_info_arch;
327327
gcc_jit_target_info_supports_128bit_int;
328328
} LIBGCCJIT_ABI_32;
329+
330+
LIBGCCJIT_ABI_34 {
331+
global:
332+
gcc_jit_type_get_restrict;
333+
} LIBGCCJIT_ABI_33;

gcc/testsuite/jit.dg/test-restrict.c

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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 cold
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-restrict.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+
void t(int *__restrict__ a, int *__restrict__ b, char *__restrict__ c) {
27+
*a += *c;
28+
*b += *c;
29+
}
30+
*/
31+
gcc_jit_type *int_type =
32+
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
33+
gcc_jit_type *pint_type = gcc_jit_type_get_pointer(int_type);
34+
gcc_jit_type *pint_restrict_type = gcc_jit_type_get_restrict(pint_type);
35+
36+
gcc_jit_type *void_type =
37+
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
38+
39+
gcc_jit_param *a =
40+
gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "a");
41+
gcc_jit_param *b =
42+
gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "b");
43+
gcc_jit_param *c =
44+
gcc_jit_context_new_param (ctxt, NULL, pint_restrict_type, "c");
45+
gcc_jit_param *params[3] = {a, b, c};
46+
47+
gcc_jit_function *func_t =
48+
gcc_jit_context_new_function (ctxt, NULL,
49+
GCC_JIT_FUNCTION_EXPORTED,
50+
void_type,
51+
"t",
52+
3, params,
53+
0);
54+
55+
gcc_jit_block *block = gcc_jit_function_new_block (func_t, NULL);
56+
57+
/* *a += *c; */
58+
gcc_jit_block_add_assignment_op (
59+
block, NULL,
60+
gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (a), NULL),
61+
GCC_JIT_BINARY_OP_PLUS,
62+
gcc_jit_lvalue_as_rvalue (
63+
gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (c), NULL)));
64+
/* *b += *c; */
65+
gcc_jit_block_add_assignment_op (
66+
block, NULL,
67+
gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (b), NULL),
68+
GCC_JIT_BINARY_OP_PLUS,
69+
gcc_jit_lvalue_as_rvalue (
70+
gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (c), NULL)));
71+
72+
gcc_jit_block_end_with_void_return (block, NULL);
73+
}
74+
75+
/* { dg-final { jit-verify-output-file-was-created "" } } */
76+
/* { dg-final { jit-verify-assembler-output "addl %eax, (%rdi)
77+
addl %eax, (%rsi)" } } */

0 commit comments

Comments
 (0)