Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gcc/jit/jit-playback.cc
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,9 @@ new_function (location *loc,
/* See handle_returns_twice_attribute in gcc/c-family/c-attribs.cc. */
else if (attr == GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE)
DECL_IS_RETURNS_TWICE (fndecl) = 1;
/* See handle_pure_attribute in gcc/c-family/c-attribs.cc. */
else if (attr == GCC_JIT_FN_ATTRIBUTE_PURE)
DECL_PURE_P (fndecl) = 1;

const char* attribute = fn_attribute_to_string (attr);
if (attribute)
Expand Down
4 changes: 2 additions & 2 deletions gcc/jit/libgccjit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3874,7 +3874,7 @@ gcc_jit_target_info_release (gcc_jit_target_info *info)
delete info;
}

bool
int
gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
const char *feature)
{
Expand All @@ -3887,7 +3887,7 @@ gcc_jit_target_info_arch (gcc_jit_target_info *info)
return info->m_arch;
}

bool
int
gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info)
{
return info->m_supports_128bit_int;
Expand Down
5 changes: 3 additions & 2 deletions gcc/jit/libgccjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -2080,14 +2080,14 @@ gcc_jit_context_get_target_info (gcc_jit_context *ctxt);
extern void
gcc_jit_target_info_release (gcc_jit_target_info *info);

extern bool
extern int
gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
const char *feature);

extern const char *
gcc_jit_target_info_arch (gcc_jit_target_info *info);

extern bool
extern int
gcc_jit_target_info_supports_128bit_int (gcc_jit_target_info *info);

/* Given type "T", get type "T __attribute__ ((packed))". */
Expand All @@ -2105,6 +2105,7 @@ enum gcc_jit_fn_attribute
GCC_JIT_FN_ATTRIBUTE_VISIBILITY,
GCC_JIT_FN_ATTRIBUTE_COLD,
GCC_JIT_FN_ATTRIBUTE_RETURNS_TWICE,
GCC_JIT_FN_ATTRIBUTE_PURE,
};

/* Add an attribute to a function. */
Expand Down
33 changes: 33 additions & 0 deletions gcc/testsuite/jit.dg/jit.exp
Original file line number Diff line number Diff line change
Expand Up @@ -895,8 +895,41 @@ proc jit-verify-assembler-output { args } {
pass "${asm_filename} output pattern test, ${dg-output-text}"
verbose "Passed test for output pattern ${dg-output-text}" 3
}
}

# Assuming that a .s file has been written out named
# OUTPUT_FILENAME, check that the argument doesn't match
# the output file.
proc jit-verify-assembler-output-not { args } {
verbose "jit-verify-assembler: $args"

set dg-output-text [lindex $args 0]
verbose "dg-output-text: ${dg-output-text}"

upvar 2 name name
verbose "name: $name"

upvar 2 prog prog
verbose "prog: $prog"
set asm_filename [jit-get-output-filename $prog]
verbose " asm_filename: ${asm_filename}"

# Read the assembly file.
set f [open $asm_filename r]
set content [read $f]
close $f

# Verify that the assembly matches the regex.
if { [regexp ${dg-output-text} $content] } {
fail "${asm_filename} output pattern test, is ${content}, should match ${dg-output-text}"
verbose "Failed test for output pattern ${dg-output-text}" 3
} else {
pass "${asm_filename} output pattern test, ${dg-output-text}"
verbose "Passed test for output pattern ${dg-output-text}" 3
}
}


# Assuming that a .o file has been written out named
# OUTPUT_FILENAME, invoke the driver to try to turn it into
# an executable, and try to run the result.
Expand Down
134 changes: 134 additions & 0 deletions gcc/testsuite/jit.dg/test-pure-attribute.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/* { dg-do compile { target x86_64-*-* } } */

#include <stdlib.h>
#include <stdio.h>

#include "libgccjit.h"

/* We don't want set_options() in harness.h to set -O3 to see that the cold
attribute affects the optimizations. */
#define TEST_ESCHEWS_SET_OPTIONS
static void set_options (gcc_jit_context *ctxt, const char *argv0)
{
// Set "-O3".
gcc_jit_context_set_int_option(ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, 3);
}

#define TEST_COMPILING_TO_FILE
#define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER
#define OUTPUT_FILENAME "output-of-test-pure-attribute.c.s"
#include "harness.h"

void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Let's try to inject the equivalent of:
__attribute__ ((pure))
int foo (int x);
int xxx(void)
{
int x = 45;
int sum = 0;

while (x >>= 1)
sum += foo (x) * 2;
return sum;
}
*/
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

/* Creating the `foo` function. */
gcc_jit_param *n =
gcc_jit_context_new_param (ctxt, NULL, int_type, "x");
gcc_jit_param *params[1] = {n};
gcc_jit_function *foo_func =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_IMPORTED,
int_type,
"foo",
1, params,
0);
gcc_jit_function_add_attribute(foo_func, GCC_JIT_FN_ATTRIBUTE_PURE);

/* Creating the `xxx` function. */
gcc_jit_function *xxx_func =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
int_type,
"xxx",
0, NULL,
0);

gcc_jit_block *block = gcc_jit_function_new_block (xxx_func, NULL);

/* Build locals: */
gcc_jit_lvalue *x =
gcc_jit_function_new_local (xxx_func, NULL, int_type, "x");
gcc_jit_lvalue *sum =
gcc_jit_function_new_local (xxx_func, NULL, int_type, "sum");

/* int x = 45 */
gcc_jit_block_add_assignment (
block, NULL,
x,
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 45));
/* int sum = 0 */
gcc_jit_block_add_assignment (
block, NULL,
sum,
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0));

/* while (x >>= 1) { sum += foo (x) * 2; } */
gcc_jit_block *loop_cond =
gcc_jit_function_new_block (xxx_func, "loop_cond");
gcc_jit_block *loop_body =
gcc_jit_function_new_block (xxx_func, "loop_body");
gcc_jit_block *after_loop =
gcc_jit_function_new_block (xxx_func, "after_loop");

gcc_jit_block_end_with_jump (block, NULL, loop_cond);


/* if (x >>= 1) */
/* Since gccjit doesn't (yet?) have support for `>>=` operator, we will decompose it into:
`if (x = x >> 1)` */
gcc_jit_block_add_assignment_op (
loop_cond, NULL,
x,
GCC_JIT_BINARY_OP_RSHIFT,
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1));
/* The condition itself */
gcc_jit_block_end_with_conditional (
loop_cond, NULL,
gcc_jit_context_new_comparison (
ctxt, NULL,
GCC_JIT_COMPARISON_NE,
gcc_jit_lvalue_as_rvalue (x),
gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)),
after_loop,
loop_body);

/* sum += foo (x) * 2; */
gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue(x);
gcc_jit_block_add_assignment_op (
loop_body, NULL,
x,
GCC_JIT_BINARY_OP_PLUS,
gcc_jit_context_new_binary_op (
ctxt, NULL,
GCC_JIT_BINARY_OP_MULT, int_type,
gcc_jit_context_new_call (ctxt, NULL, foo_func, 1, &arg),
gcc_jit_context_new_rvalue_from_int (
ctxt,
int_type,
2)));
gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond);

/* return sum; */
gcc_jit_block_end_with_return (after_loop, NULL, gcc_jit_lvalue_as_rvalue(sum));
}

/* { dg-final { jit-verify-output-file-was-created "" } } */
/* Check that the loop was optimized away */
/* { dg-final { jit-verify-assembler-output-not "jne" } } */