diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index bb6197a8eb377c5caa0aa332398a9eaed010dfd1..6315462aae645392f84d0f11f62ee13030ab8e3e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1734,13 +1734,13 @@ OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \
pretty-print.o intl.o \
sbitmap.o \
vec.o input.o hash-table.o ggc-none.o memory-block.o \
- selftest.o selftest-diagnostic.o sort.o
+ ai4c-infer.o selftest.o selftest-diagnostic.o sort.o
# Objects in libcommon-target.a, used by drivers and by the core
# compiler and containing target-dependent code.
OBJS-libcommon-target = $(common_out_object_file) prefix.o \
opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
- hash-table.o file-find.o spellcheck.o selftest.o opt-suggestions.o
+ hash-table.o file-find.o spellcheck.o ai4c-infer.o selftest.o opt-suggestions.o
# This lists all host objects for the front ends.
ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
@@ -2256,7 +2256,7 @@ gcc-nm.cc: gcc-ar.cc
cp $^ $@
COLLECT2_OBJS = collect2.o collect2-aix.o vec.o ggc-none.o \
- collect-utils.o file-find.o hash-table.o selftest.o
+ collect-utils.o file-find.o hash-table.o ai4c-infer.o selftest.o
COLLECT2_LIBS = @COLLECT2_LIBS@
collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
@@ -3720,6 +3720,8 @@ install-plugin: installdirs lang.install-plugin s-header-vars install-gengtype
# Install the compiler executables built during cross compilation.
install-common: native lang.install-common installdirs
+ rm -f $(DESTDIR)$(libexecdir)/onnx.fdata
+ cp $(srcdir)/onnx.fdata $(DESTDIR)$(libexecsubdir)/onnx.fdata
for file in $(COMPILERS); do \
if [ -f $$file ] ; then \
rm -f $(DESTDIR)$(libexecsubdir)/$$file; \
diff --git a/gcc/ai4c-infer.cc b/gcc/ai4c-infer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4fa7c47708efa1be5bf7cdbf81c1f80ed762409b
--- /dev/null
+++ b/gcc/ai4c-infer.cc
@@ -0,0 +1,402 @@
+/* TODO
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "ai4c-infer.h"
+#include "config.h"
+#include "system.h"
+
+#ifndef _cbmc_
+#define __CPROVER_assume(...) do {} while (0)
+#endif
+
+#define M_OPTION_SIZE 7
+#define M_MODE_SIZE 6
+
+#define CATS_STRINGS_ROW 12
+#define CATS_STRINGS_COL 65
+#define OFFSET_ROW 6
+#define SCALE_ROW 6
+#define UNITY_ROW 1
+#define COEFFICIENT_ROW 18
+#define COEFFICIENT_COL 100
+#define COEFFICIENT1_ROW 100
+#define COEFFICIENT1_COL 1
+#define INTERCEPTS_ROW 100
+#define INTERCEPTS1_ROW 1
+
+/* Model info. */
+static int64_t argv_hw1[argc_hw1];
+static char native_tune[128];
+
+static char cats_strings[CATS_STRINGS_ROW][CATS_STRINGS_COL];
+static float offset[OFFSET_ROW];
+static float scale[SCALE_ROW];
+static float unity[UNITY_ROW];
+static float coefficient[COEFFICIENT_ROW][COEFFICIENT_COL];
+static float coefficient1[COEFFICIENT1_ROW][COEFFICIENT1_COL];
+static float intercepts[INTERCEPTS_ROW];
+static float intercepts1[INTERCEPTS1_ROW];
+
+/* Model result。 */
+int64_t initialize_decision;
+int64_t optmize_result;
+
+void
+set_initialize_decision ()
+ {
+ initialize_decision = 1;
+ }
+void
+set_native_tune (const char *info)
+{
+ if (info)
+ {
+ strcpy(native_tune, info);
+ return;
+ }
+ return;
+}
+
+void
+set_cache_info (int index, int cache_value)
+{
+ argv_hw1[index] = cache_value;
+}
+
+void
+fill_node (char *file_name)
+{
+
+ FILE *file = fopen (file_name, "rb");
+
+ if (!file)
+ {
+ perror ("Can not open file.");
+ fclose (file);
+ return;
+ }
+
+ // parse cats_strings
+ for (int i = 0; i < CATS_STRINGS_ROW; i++)
+ {
+ fread (cats_strings[i], sizeof (char), CATS_STRINGS_COL - 1, file);
+ cats_strings[i][64] = '\0';
+ }
+
+ fread (offset, sizeof (float), OFFSET_ROW, file);
+ fread (scale, sizeof (float), SCALE_ROW, file);
+ fread (coefficient, sizeof (float), COEFFICIENT_ROW * COEFFICIENT_COL, file);
+ fread (coefficient1, sizeof (float), COEFFICIENT1_ROW * COEFFICIENT1_COL, file);
+ fread (intercepts, sizeof (float), INTERCEPTS_ROW, file);
+ fread (intercepts1, sizeof (float), INTERCEPTS1_ROW, file);
+ fread (unity, sizeof (float), UNITY_ROW, file);
+ fclose (file);
+ return;
+}
+
+static void
+matmul (const float *lhs, const float *rhs, int m, int k, int n, float *out)
+{
+ for (int i = 0; i < m; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ out[i * n + j] = 0.0f;
+ for (int p = 0; p < k; p++)
+ {
+ out[i * n + j] += lhs[i * k + p] * rhs[p * n + j];
+ }
+ }
+ }
+}
+
+static void
+add (const float *lhs, const float *rhs, int length, float *out)
+{
+ for (int i = 0; i < length; i++)
+ {
+ out[i] = lhs[i] + rhs[i];
+ }
+}
+
+static void
+sub (const float *lhs, const float *rhs, int length, float *out)
+{
+ for (int i = 0; i < length; i++)
+ {
+ out[i] = lhs[i] - rhs[i];
+ }
+}
+
+static void
+sigmoid (const float *in, int length, float *out)
+{
+ for (int i = 0; i < length; i++)
+ {
+ out[i] = 1.0f / (1.0f + expf (-in[i]));
+ }
+}
+
+static void
+relu (const float *data, int length, float *out)
+{
+ for (int i = 0; i < length; i++)
+ {
+ if (data[i] < 0)
+ {
+ out[i] = 0;
+ }
+ else
+ {
+ out[i] = data[i];
+ }
+ }
+}
+
+static void
+line_concat (const float *in, int in_size, float *out, int out_size)
+{
+ for (int i = 0; i < in_size; i++)
+ {
+ out[out_size + i] = in[i];
+ }
+}
+
+static void
+one_hot_encoder (const char *in, const char (*cats)[65], float *out,
+ int out_size)
+{
+ for (int i = 0; i < out_size; i++)
+ {
+ if (i < out_size && strcmp (cats[i], in) == 0)
+ {
+ out[i] = 1.0f;
+ }
+ else
+ {
+ out[i] = 0.0f;
+ }
+ }
+}
+
+static void
+imputer (const int64_t *in, int size, float *out)
+{
+ for (int i = 0; i < size; i++)
+ {
+ out[i] = in[i] * 1.0f;
+ }
+}
+
+static void
+scaler (const float *in, const float *offset, const float *scale, int size, float *out)
+{
+ for (int i = 0; i < size; i++)
+ {
+ out[i] = (in[i] - offset[i]) * scale[i];
+ }
+}
+
+static int
+argmax (const float *in, int in_size)
+{
+ int out_idx = 0;
+ for (int i = 0; i < in_size; i++)
+ {
+ if (in[i] > in[out_idx])
+ {
+ out_idx = 1;
+ }
+ }
+ return out_idx;
+}
+
+static void
+preprocess (int argc1, const char *argv1, int argc2, int64_t *argv2, int64_t *in_modes)
+{
+ int default_int_val= 0;
+ for (int i = 0; i < argc2; i++)
+ {
+ if (i < argc2)
+ {
+ in_modes[i] = argv2[i];
+ }
+ else
+ {
+ in_modes[i] = default_int_val;
+ }
+ }
+}
+
+static int
+graph_infer (int argc, const char *argv, int argc2, int64_t *argv2)
+{
+
+ const char *file_name = getenv ("COLLECT_LTO_WRAPPER");
+ char native_file [512];
+ if (file_name)
+ {
+ const char *onnx_fdata = "onnx.fdata";
+ strncpy(native_file, file_name, sizeof(native_file) - 1);
+ native_file[sizeof(native_file) - 1] = '\0';
+
+ char *last_slash = strrchr(native_file, '/');
+ if (last_slash)
+ strcpy(last_slash + 1, onnx_fdata);
+ }
+
+ if (access(native_file, F_OK) == 0)
+ {
+ fill_node (native_file);
+ }
+ else
+ {
+ return 0;
+ }
+
+ static int64_t in_modes[M_MODE_SIZE];
+
+ preprocess (argc, argv, argc2, argv2, in_modes);
+
+ const int concat_out_size = 18;
+ float concat_result[concat_out_size];
+ const int encoder_out_size = 12;
+ int concat_size = 0;
+ float encoder_out[encoder_out_size];
+
+ one_hot_encoder (argv, cats_strings, encoder_out, encoder_out_size);
+
+ line_concat (encoder_out, encoder_out_size, concat_result, concat_size);
+ concat_size += encoder_out_size;
+
+ float variable[M_MODE_SIZE];
+ imputer (in_modes, M_MODE_SIZE, variable);
+
+ float variable1[M_MODE_SIZE];
+ scaler (variable, offset, scale, M_MODE_SIZE, variable1);
+ float transformed_column[concat_out_size + M_MODE_SIZE];
+ line_concat (variable1, M_MODE_SIZE, transformed_column, 0);
+ line_concat (concat_result, concat_out_size, transformed_column, 6);
+
+ const int m = 1, k = 18, n = 100;
+ float mul_result[n];
+ matmul (transformed_column, coefficient[0], m, k, n, mul_result);
+
+ float add_result[n];
+ add (mul_result, intercepts, n, add_result);
+
+ float next_activations[n];
+ relu (add_result, n, next_activations);
+
+ const int m2 = 1, k2 = 100, n2 = 1;
+ float mul_result1 [n2];
+ matmul (next_activations, coefficient1[0], m2, k2, n2, mul_result1);
+
+ float add_result1[n2];
+ add (mul_result1, intercepts1, n2, add_result1);
+
+ float out_activations_result[n2];
+ sigmoid (add_result1, n2, out_activations_result);
+
+ float negative_class_proba[n2];
+ sub (unity, out_activations_result, n2, negative_class_proba);
+ const int prob_size = n2 + n2;
+ float probabilities[prob_size];
+ line_concat (negative_class_proba, n2, probabilities, 0);
+ line_concat (out_activations_result, n2, probabilities, n2);
+
+ int argmax_output = argmax (probabilities, prob_size);
+ return argmax_output;
+}
+
+void execute_sha256(const char *input, char *output, size_t output_size)
+{
+ char command[256];
+ snprintf (command, sizeof(command), "echo -n \"%s\" | sha256sum", input);
+
+ FILE *pipe = popen (command, "r");
+ if (pipe == NULL)
+ {
+ perror ("Failed to run command.");
+ }
+
+ if (fgets (output, output_size, pipe) != NULL)
+ {
+ size_t length = strlen (output);
+ if (length > 0 && (output[length - 1] == '\n' || output[length - 1] == ' '))
+ {
+ output[length] = '\0';
+ }
+
+ char *space_pos = strchr (output, ' ');
+ if (space_pos != NULL)
+ {
+ *space_pos = '\0';
+ }
+ }
+ pclose (pipe);
+}
+
+int
+get_optimize_decision ()
+{
+ if (initialize_decision == 1)
+ {
+ return optmize_result;
+ }
+ if (native_tune && (strstr (native_tune, "mcpu=hip09") != NULL
+ || strstr (native_tune, "mcpu=tsv110") != NULL ))
+ {
+ char hash[65];
+ char input[64];
+ const char *prefix = "=";
+ const char *start = strstr(native_tune, prefix);
+ if (start)
+ {
+ start += strlen(prefix);
+ const char *end = strchr(start, '+');
+ if (!end)
+ {
+ end = native_tune + strlen(native_tune);
+ }
+ size_t len = end - start;
+ if (len >= sizeof(input)) len = sizeof(input)- 1;
+ strncpy(input, start, len);
+ input[len] = '\0';
+ }
+ else
+ {
+ input[0] = '\0';
+ }
+ execute_sha256(input, hash, sizeof(hash));
+ optmize_result = graph_infer (1, hash, argc_hw1, argv_hw1);
+ set_initialize_decision ();
+ if (optmize_result == 1)
+ setenv ("AI_GUIDED", "1", 1);
+ }
+ return optmize_result;
+}
\ No newline at end of file
diff --git a/gcc/ai4c-infer.h b/gcc/ai4c-infer.h
new file mode 100644
index 0000000000000000000000000000000000000000..218b2a1510b338a0b9727f3590d25650c9afa685
--- /dev/null
+++ b/gcc/ai4c-infer.h
@@ -0,0 +1,31 @@
+/*
+ Copyright (C) 2008-2022 Free Software Foundation, Inc.
+ Contributed by Zhenyu Zhao (zhaozhenyu17@huawei.com).
+
+This file is part of GCC.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#ifndef AI4C_INFER
+#define AI4C_INFER
+
+extern int64_t initialize_decision;
+extern int64_t optmize_result;
+const int64_t argc_hw1 = 6;
+
+extern int get_optimize_decision ();
+extern void set_cache_info (int index, int cache_value);
+extern void set_native_tune (const char *info);
+extern void set_initialize_decision ();
+#endif /* AI4C_INFERH*/
\ No newline at end of file
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 08a43541ebdac51c066155aae234b83d8bb15151..05e1cc1d8b29528a66eadb339c9a7a468fa4b6cd 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18857,6 +18857,7 @@ static void
reset_machine_option (struct gcc_options *opts)
{
if (!(opts->x_optimize_maximum)
+ || opts->x_aarch64_cpu_string == NULL
|| strstr (opts->x_aarch64_tune_string, "hip09") == NULL)
{
return;
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 32e45adc26486788cf6dc89f47390fb1485f26a8..d8957384633d51d0bf8f6d7d4d67af377e5daf6c 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -5798,6 +5798,9 @@ do_self_spec (const char *spec)
do_spec_2 (spec, NULL);
do_spec_1 (" ", 0, NULL);
+ const char* tune_native = eval_spec_function ("local_cpu_detect", "cpu", "");
+ setenv ("TUNE", tune_native, 1);
+
/* Mark % 0
/* Only enable in lto or whole_program. */
- && (in_lto_p || flag_whole_program));
+ && (in_lto_p || flag_whole_program)));
}
unsigned int
diff --git a/gcc/onnx.fdata b/gcc/onnx.fdata
new file mode 100644
index 0000000000000000000000000000000000000000..3c8610e7f8822e1603ad0ebce5842f5289ab2c73
Binary files /dev/null and b/gcc/onnx.fdata differ
diff --git a/gcc/opts-global.cc b/gcc/opts-global.cc
index a18c76940f971d8ff60ffacaa43ae1e8d41f1ed5..ba91617881b5a695e88e5611dd678235c04b0bac 100644
--- a/gcc/opts-global.cc
+++ b/gcc/opts-global.cc
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "asan.h"
#include "file-prefix-map.h" /* add_*_prefix_map() */
+#include "ai4c-infer.h"
typedef const char *const_char_p; /* For DEF_VEC_P. */
@@ -304,6 +305,15 @@ decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
location_t loc, diagnostic_context *dc,
void (*target_option_override_hook) (void))
{
+ set_cache_info (0, global_options.x_param_simultaneous_prefetches);
+ set_cache_info (1, global_options.x_param_l1_cache_size);
+ set_cache_info (2, global_options.x_param_l1_cache_line_size);
+ set_cache_info (3, global_options.x_param_l2_cache_size);
+ set_cache_info (4, global_options.x_param_prefetch_latency);
+ set_cache_info (5, global_options.x_param_ipa_prefetch_distance_factor);
+ const char *tune_native = getenv ("TUNE");
+ set_native_tune (tune_native);
+
struct cl_option_handlers handlers;
unsigned int lang_mask;