代码拉取完成,页面将自动刷新
From 19a1074e87577f9b511f382569ac081871e84147 Mon Sep 17 00:00:00 2001
From: zhenyu--zhao_admin <zhaozhenyu17@huawei.com>
Date: Sat, 7 Dec 2024 16:05:59 +0800
Subject: [PATCH] [BUGFIX] Fix build error on risv_64.
---
gcc/Makefile.in | 10 +-
gcc/ai-optimizer.cc | 395 ++++++++++++++++++++++++++++++++
gcc/ai4c-infer.cc | 46 ++--
gcc/ai4c-infer.h | 26 ++-
gcc/c-family/c-common.h | 2 +
gcc/c-family/c-opts.cc | 21 ++
gcc/config/aarch64/aarch64-c.cc | 16 ++
gcc/config/aarch64/aarch64.cc | 15 +-
gcc/gcc.cc | 39 +---
gcc/gcc.h | 1 -
gcc/optimizer.fdata | 1 +
gcc/opts-common.cc | 74 +-----
gcc/opts-global.cc | 5 +-
13 files changed, 521 insertions(+), 130 deletions(-)
create mode 100644 gcc/ai-optimizer.cc
create mode 100644 gcc/optimizer.fdata
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5610854e6..65f683bbd 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1735,13 +1735,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 \
- ai4c-infer.o selftest.o selftest-diagnostic.o sort.o
+ ai4c-infer.o ai-optimizer.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 ai4c-infer.o selftest.o opt-suggestions.o
+ hash-table.o file-find.o spellcheck.o ai4c-infer.o ai-optimizer.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))
@@ -2257,7 +2257,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 ai4c-infer.o selftest.o
+ collect-utils.o file-find.o hash-table.o ai4c-infer.o ai-optimizer.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.
@@ -3721,8 +3721,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
+ rm -f $(DESTDIR)$(libexecdir)/gcc/*.fdata
+ cp $(srcdir)/*.fdata $(DESTDIR)$(libexecdir)/gcc/
for file in $(COMPILERS); do \
if [ -f $$file ] ; then \
rm -f $(DESTDIR)$(libexecsubdir)/$$file; \
diff --git a/gcc/ai-optimizer.cc b/gcc/ai-optimizer.cc
new file mode 100644
index 000000000..c3d99dd85
--- /dev/null
+++ b/gcc/ai-optimizer.cc
@@ -0,0 +1,395 @@
+/* Lightweight AI Inference Framework.
+ Copyright (C) 2024-2024 Free Software Foundation, Inc.
+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
+<http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <math.h>
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <cassert>
+#include "config.h"
+#include "system.h"
+#include "ai4c-infer.h"
+
+#define M_OPTION_SIZE 11
+#define M_MODE_SIZE 6
+#define NATIVE_TUNE_SIZE 128
+#define CATS_STRINGS_ROW 34
+#define CATS_STRINGS_COL 65
+#define CATS_STRINGS1_ROW 10
+#define CATS_STRINGS1_COL 65
+#define OFFSET_ROW 6
+#define SCALE_ROW 6
+#define UNITY_ROW 1
+#define COEFFICIENT_ROW 356
+#define COEFFICIENT_COL 10
+#define COEFFICIENT1_ROW 10
+#define COEFFICIENT1_COL 1
+#define INTERCEPTS_ROW 10
+#define INTERCEPTS1_ROW 1
+
+/* Intermediate computation results from the ONNX model. */
+static char cats_strings[CATS_STRINGS_ROW][CATS_STRINGS_COL];
+static char cats_strings1[CATS_STRINGS1_ROW][CATS_STRINGS1_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];
+
+/* Return an integer that represents the comparison result of the
+ two strings. */
+
+static int
+compare_strings (const void *a, const void *b)
+{
+ const char *str_a = *(const char **)a;
+ const char *str_b = *(const char **)b;
+
+ int len = strlen (str_a) < strlen (str_b) ? strlen (str_a) : strlen (str_b);
+ for (int i = 0; i < len; i++)
+ {
+ char c1 = str_a[i];
+ char c2 = str_b[i];
+ if (ISUPPER (c1) && !ISUPPER (c2))
+ return 0;
+ else if (!ISUPPER (c1) && ISUPPER (c2))
+ return 1;
+ else if (c1 != c2)
+ return c1 < c2;
+ }
+ return strlen (str_a) > strlen (str_b);
+}
+
+/* Return the substring before the first underscore ('_') in the input
+ string. */
+
+static void
+truncate_prefix (const char *str, char *result)
+{
+ const char *underscore_pos = strchr (str, '_');
+ if (underscore_pos == NULL)
+ {
+ strcpy (result, str);
+ return;
+ }
+
+ size_t len = underscore_pos - str;
+ strncpy (result, str, len + 1);
+ result[len + 1] = '\0';
+}
+
+
+static void
+preprocess (int argc1, const char **argv1, const char *mops,
+ int argc2, int64_t *argv2, char (*in_options)[1024],
+ int64_t *in_modes)
+{
+ strcpy (in_options[0], mops);
+
+ const char *output_option = "-o";
+ const char *marco_prefix = "-D";
+ const char *needle = "--param";
+ const char *flag_prefix = "-";
+ const char *default_option = "-default-option";
+ const int default_int_val = 0;
+ int m_size = 0;
+ for (int i = 0; i < argc1; i++)
+ {
+ if (strncmp (argv1[i], marco_prefix, 2) == 0)
+ m_size ++;
+ }
+
+ char *m_options[m_size];
+ char output_file[1024];
+ int m_index = 0;
+ for (int i = 0; i < argc1; i++)
+ {
+ if (strncmp (argv1[i], marco_prefix, 2) == 0)
+ {
+ m_options[m_index] = (char *)argv1[i];
+ m_index ++;
+ }
+ if (strcmp (argv1[i], output_option) == 0)
+ truncate_prefix (argv1[i + 1], output_file);
+ }
+
+ strcpy (in_options[1], output_file);
+ int in_options_size = 2;
+ qsort (m_options, m_size, sizeof (m_options[0]), compare_strings);
+ for (int i = 0; i < m_size && in_options_size < M_OPTION_SIZE; i++)
+ {
+ strcpy (in_options[in_options_size], m_options[i]);
+ in_options_size ++;
+ }
+
+ for (int i = 0; i < argc1 && in_options_size < M_OPTION_SIZE; i++)
+ {
+ if (strncmp (argv1[i], marco_prefix, 2) != 0
+ && strcmp (argv1[i], output_option) != 0
+ && strncmp (argv1[i], needle, 7) != 0
+ && strncmp (argv1[i], flag_prefix, 1) == 0)
+ {
+ strcpy (in_options[in_options_size], argv1[i]);
+ in_options_size ++;
+ }
+ }
+
+ while (in_options_size < M_OPTION_SIZE)
+ {
+ strcpy (in_options[in_options_size], default_option);
+ in_options_size ++;
+ }
+
+ /* Use sha256 to encrypt the input. */
+ char hash[65];
+ char input[64];
+ for (int i = 0; i < M_OPTION_SIZE; i++)
+ {
+ execute_sha256 (in_options[i], hash, sizeof (hash));
+ strcpy (in_options[i], hash);
+ }
+
+ for (int i = 0; i < argc2 && i < M_MODE_SIZE; i++)
+ {
+ if (i < argc2)
+ in_modes[i] = argv2[i];
+ else
+ in_modes[i] = default_int_val;
+ }
+}
+
+/* To read model parameter information from optimizer.fdata and store it into
+ the appropriate arrays. */
+
+static void
+fill_node (const char *file_name)
+{
+ FILE *file = fopen (file_name, "rb");
+
+ if (!file)
+ {
+ perror ("Can not open file.");
+ return;
+ }
+
+ /* Read cats_strings from optimizer.fdata. */
+ char hex_string[2];
+ for (int i = 0; i < CATS_STRINGS_ROW; i++)
+ {
+ for (int j = 0; j < CATS_STRINGS_COL - 1; j++)
+ {
+ if (fscanf (file, "%2s", hex_string) != 1)
+ {
+ perror ("Can not read cats_strings from optimizer.fdata.");
+ return;
+ }
+ cats_strings[i][j] = (unsigned char) strtol(hex_string, NULL, 16);
+ }
+ cats_strings[i][CATS_STRINGS_COL - 1] = '\0';
+ }
+
+ /* Read cats_strings1 from optimizer.fdata. */
+ for (int i = 0; i < CATS_STRINGS1_ROW; i++)
+ {
+ for (int j = 0; j < CATS_STRINGS1_COL - 1; j++)
+ {
+ if (fscanf (file, "%2s", hex_string) != 1)
+ {
+ perror ("Can not read cats_strings1 from optimizer.fdata.");
+ return;
+ }
+ cats_strings1[i][j] = (unsigned char) strtol(hex_string, NULL, 16);
+ }
+ cats_strings1[i][CATS_STRINGS1_COL - 1] = '\0';
+ }
+
+ /* Read offset from optimizer.fdata. */
+ for (int i = 0; i < OFFSET_ROW; i++)
+ {
+ float result = read_float_from_file (file);
+ offset[i] = result;
+ }
+
+
+ /* Read scale from optimizer.fdata. */
+ for (int i = 0; i < SCALE_ROW; i++)
+ {
+ float result = read_float_from_file (file);
+ scale[i] = result;
+ }
+
+ /* Read unity from optimizer.fdata. */
+ for (int i = 0; i < UNITY_ROW; i++)
+ {
+ float result = read_float_from_file (file);
+ unity[i] = result;
+ }
+
+ /* Read coefficient from optimizer.fdata. */
+ for (int i = 0; i < COEFFICIENT_ROW; i++)
+ for (int j = 0; j < COEFFICIENT_COL; j++)
+ {
+ float result = read_float_from_file (file);
+ coefficient[i][j] = result;
+ }
+
+ /* Read coefficient1 from optimizer.fdata. */
+ for (int i = 0; i < COEFFICIENT1_ROW; i++)
+ for (int j = 0; j < COEFFICIENT1_COL; j++)
+ {
+ float result = read_float_from_file (file);
+ coefficient1[i][j] = result;
+ }
+
+ /* Read intercepts from optimizer.fdata. */
+ for (int i = 0; i < INTERCEPTS_ROW; i++)
+ {
+ float result = read_float_from_file (file);
+ intercepts[i] = result;
+ }
+
+ /* Read intercepts1 from optimizer.fdata. */
+ for (int i = 0; i < INTERCEPTS1_ROW; i++)
+ {
+ float result = read_float_from_file (file);
+ intercepts1[i] = result;
+ }
+
+ fclose (file);
+ return;
+}
+
+/* The process of model inference. */
+
+static int
+graph_infer (int argc1, const char **argv1, const char *mops,
+ int argc2, int64_t *argv2)
+{
+ char *gcc_exec_prefix = getenv ("ONNX_FDATA_PATH");
+ if (gcc_exec_prefix == NULL)
+ return 0;
+ char native_file[512];
+
+ if (gcc_exec_prefix)
+ {
+ const char *onnx_fdata = "optimizer.fdata";
+ strncpy (native_file, gcc_exec_prefix, 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];
+ static char in_options[M_OPTION_SIZE][1024];
+
+ preprocess (argc1, argv1, mops, argc2, argv2, in_options, in_modes);
+
+ /* concat_result and encoder_out are intermediate computation results from
+ the ONNX model. concat_result is a 1 × 18 matrix, and encoder_out is a
+ 1 × 12 matrix. */
+
+ const int concat_out_size = 350;
+ float concat_result[concat_out_size];
+ const int encoder_out_size = 34;
+ const int encoder_last_size = 10;
+ int concat_size = 0;
+ const int size = encoder_out_size;
+
+ for (int i = 1; i < M_OPTION_SIZE; i++)
+ {
+ float encoder_out[size];
+ one_hot_encoder (in_options[i], cats_strings, encoder_out, size);
+ line_concat (encoder_out, size, concat_result, concat_size);
+ concat_size += size;
+ }
+
+ float encoder_out2[encoder_last_size];
+ one_hot_encoder (in_options[0], cats_strings1, encoder_out2,
+ encoder_last_size);
+ line_concat (encoder_out2, encoder_last_size, concat_result, concat_size);
+ concat_size += encoder_last_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 is used to stro*/
+ line_concat (variable1, M_MODE_SIZE, transformed_column, 0);
+ line_concat (concat_result, concat_out_size, transformed_column, 6);
+
+ /* This requires performing matrix multiplication between a 1 × 356 matrix
+ and an 356 × 10 matrix */
+
+ const int m = 1, k = 356, n = 10;
+ 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);
+
+ /* This requires performing matrix multiplication between a 1 × 10 matrix
+ and an 10 × 1 matrix */
+
+ const int m2 = 1, k2 = 10, 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;
+}
+
+int
+get_optimize_decision_from_optimizer (int argc, const char **argv,
+ const char *mops, int argc2,
+ int64_t *argv2)
+{
+ int model_pred = graph_infer (argc, argv, mops, argc2, argv2);
+ if (model_pred == 1)
+ {
+ putenv ("AI_INFER_LEVEL=1");
+ }
+ return model_pred;
+}
diff --git a/gcc/ai4c-infer.cc b/gcc/ai4c-infer.cc
index 99f7a6b45..42922e1ca 100644
--- a/gcc/ai4c-infer.cc
+++ b/gcc/ai4c-infer.cc
@@ -61,6 +61,12 @@ static int64_t optimize_result;
void
prepare_native_tune_str (const char *info)
{
+ if (info == NULL)
+ {
+ strcpy (native_tune, "=native+");
+ return;
+ }
+
gcc_assert (strlen (info) < NATIVE_TUNE_SIZE);
if (info)
strcpy (native_tune, info);
@@ -83,7 +89,7 @@ set_cache_info (int prefetches, int l1_cache_size,
/* Read float from onnx.fdata. */
-float static
+float
read_float_from_file (FILE* file)
{
char hex_float[8];
@@ -196,7 +202,7 @@ fill_node (const char *file_name)
return;
}
-static void
+void
matmul (const float *lhs, const float *rhs, int m, int k, int n, float *out)
{
for (int i = 0; i < m; i++)
@@ -212,7 +218,7 @@ matmul (const float *lhs, const float *rhs, int m, int k, int n, float *out)
}
}
-static void
+void
add (const float *lhs, const float *rhs, int length, float *out)
{
for (int i = 0; i < length; i++)
@@ -221,7 +227,7 @@ add (const float *lhs, const float *rhs, int length, float *out)
}
}
-static void
+void
sub (const float *lhs, const float *rhs, int length, float *out)
{
for (int i = 0; i < length; i++)
@@ -230,7 +236,7 @@ sub (const float *lhs, const float *rhs, int length, float *out)
}
}
-static void
+void
sigmoid (const float *in, int length, float *out)
{
for (int i = 0; i < length; i++)
@@ -239,7 +245,7 @@ sigmoid (const float *in, int length, float *out)
}
}
-static void
+void
relu (const float *data, int length, float *out)
{
for (int i = 0; i < length; i++)
@@ -255,14 +261,14 @@ relu (const float *data, int length, float *out)
}
}
-static void
+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
+void
one_hot_encoder (const char *in, const char (*cats)[65], float *out,
int out_size)
{
@@ -279,14 +285,14 @@ one_hot_encoder (const char *in, const char (*cats)[65], float *out,
}
}
-static void
+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
+void
scaler (const float *in, const float *offset, const float *scale, int size,
float *out)
{
@@ -294,7 +300,7 @@ scaler (const float *in, const float *offset, const float *scale, int size,
out[i] = (in[i] - offset[i]) * scale[i];
}
-static int
+int
argmax (const float *in, int in_size)
{
int out_idx = 0;
@@ -327,7 +333,20 @@ preprocess (int argc, int64_t *argv, int64_t *in_modes)
static int
graph_infer (int argc, const char *argv, int argc2, int64_t *argv2)
{
- const char *file_name = getenv ("GCC_AI4C_ONNX_FDATA");
+ char *gcc_exec_prefix = getenv ("ONNX_FDATA_PATH");
+ if (gcc_exec_prefix == NULL)
+ return 0;
+ char file_name[512];
+
+ if (gcc_exec_prefix)
+ {
+ const char *onnx_fdata = "onnx.fdata";
+ strncpy (file_name, gcc_exec_prefix, sizeof (file_name) - 1);
+ file_name[sizeof (file_name) - 1] = '\0';
+ char *last_slash = strrchr (file_name, '/');
+ if (last_slash)
+ strcpy (last_slash + 1, onnx_fdata);
+ }
if (access (file_name, F_OK) == 0)
{
@@ -401,7 +420,8 @@ graph_infer (int argc, const char *argv, int argc2, int64_t *argv2)
return argmax_output;
}
-void execute_sha256 (const char *input, char *output, size_t output_size)
+void
+execute_sha256 (const char *input, char *output, size_t output_size)
{
char command[256];
snprintf (command, sizeof (command), "echo -n \"%s\" | sha256sum", input);
diff --git a/gcc/ai4c-infer.h b/gcc/ai4c-infer.h
index 7fb75900b..fa5156ab1 100644
--- a/gcc/ai4c-infer.h
+++ b/gcc/ai4c-infer.h
@@ -21,9 +21,25 @@
#ifndef AI4C_INFER_H
#define AI4C_INFER_H
+extern void matmul (const float *, const float *, int, int, int, float *);
+extern void add (const float *, const float *, int, float *);
+extern void sub (const float *, const float *, int, float *);
+extern void sigmoid (const float *, int, float *);
+extern void relu (const float *, int, float *);
+extern void line_concat (const float *, int, float *, int);
+extern void one_hot_encoder (const char *, const char (*)[65], float *, int);
+extern void imputer (const int64_t *, int, float *);
+extern void scaler (const float *, const float *, const float *, int, float *);
+extern int argmax (const float *, int);
+
+extern void
+execute_sha256 (const char *, char *, size_t);
+extern float read_float_from_file (FILE*);
+
extern int get_optimize_decision_from_ai4c ();
-extern void set_cache_info (int prefetches, int l1_cache_size,
- int l1_cache_line_size, int l2_cache_size,
- int prefetch_latency, int prefetch_distance_factor);
-extern void prepare_native_tune_str (const char *info);
-#endif /* AI4C_INFER_H */
\ No newline at end of file
+extern int get_optimize_decision_from_optimizer (int, const char **,
+ const char *, int ,
+ int64_t *);
+extern void set_cache_info (int, int, int, int, int, int);
+extern void prepare_native_tune_str (const char *);
+#endif /* AI4C_INFER_H */
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index d1503c5a7..47c502e13 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -940,6 +940,8 @@ extern void set_compound_literal_name (tree decl);
extern tree build_va_arg (location_t, tree, tree);
+extern void deferred_opts_add_macro_front (const char *);
+
extern const unsigned int c_family_lang_mask;
extern unsigned int c_common_option_lang_mask (void);
extern void c_common_diagnostics_set_defaults (diagnostic_context *);
diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc
index 744b54dc3..4cde773bf 100644
--- a/gcc/c-family/c-opts.cc
+++ b/gcc/c-family/c-opts.cc
@@ -94,6 +94,9 @@ static bool std_cxx_inc = true;
/* If the quote chain has been split by -I-. */
static bool quote_chain_split;
+/* Size of deferred_opts. */
+static size_t deferred_opts_size;
+
/* Number of deferred options. */
static size_t deferred_count;
@@ -145,6 +148,23 @@ static struct deferred_opt
extern const unsigned int
c_family_lang_mask = (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX);
+/* Add macro to the front of deferred_opts. */
+void
+deferred_opts_add_macro_front (const char *arg)
+{
+ /* Allocate a new vec and move elements back. */
+ auto *new_opts = XNEWVEC (struct deferred_opt, deferred_opts_size + 1);
+ memcpy (new_opts + 1, deferred_opts,
+ sizeof (struct deferred_opt) * deferred_opts_size);
+ XDELETEVEC (deferred_opts);
+ deferred_opts = new_opts;
+ deferred_opts_size++;
+ deferred_count++;
+
+ deferred_opts[0].code = OPT_D;
+ deferred_opts[0].arg = arg;
+}
+
/* Defer option CODE with argument ARG. */
static void
defer_opt (enum opt_code code, const char *arg)
@@ -251,6 +271,7 @@ c_common_init_options (unsigned int decoded_options_count,
cpp_opts->warn_dollars = 0;
deferred_opts = XNEWVEC (struct deferred_opt, decoded_options_count);
+ deferred_opts_size = decoded_options_count;
if (c_language == clk_c)
{
diff --git a/gcc/config/aarch64/aarch64-c.cc b/gcc/config/aarch64/aarch64-c.cc
index 2d2ac42c4..dd739288c 100644
--- a/gcc/config/aarch64/aarch64-c.cc
+++ b/gcc/config/aarch64/aarch64-c.cc
@@ -47,6 +47,21 @@ aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
cpp_undef (pfile, macro);
}
+/* Reset the optimize option.
+ After checking the model result, this function can
+ reset the more appropriate options. */
+static void
+reset_machine_option (struct gcc_options *opts)
+{
+ const char *ai_infer_level = getenv ("AI_INFER_LEVEL");
+ if (ai_infer_level)
+ {
+ auto *cpp_opts = cpp_get_options (parse_in);
+ cpp_opts->macro_use_commandline = 1;
+ deferred_opts_add_macro_front ("OBSTACK_CHUNK_SIZE=65536");
+ }
+}
+
/* Define the macros that we always expect to have on AArch64. */
static void
@@ -119,6 +134,7 @@ aarch64_define_unconditional_macros (cpp_reader *pfile)
cpp_opts->warn_variadic_macros = old_warn_variadic_macros;
cpp_opts->cpp_warn_c90_c99_compat = old_cpp_warn_c90_c99_compat;
}
+ reset_machine_option(&global_options);
}
/* Undefine/redefine macros that depend on the current backend state and may
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 829e0da8f..debb15522 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -18771,6 +18771,7 @@ override_C_optimize_options (struct gcc_options *opts)
opts->x_semi_relayout_level = 14;
opts->x_flag_ipa_prefetch = 1;
opts->x_flag_ipa_ic = 1;
+ opts->x_flag_cmlt_arith = 1;
}
/* Check whether in CPP language or LTO with only CPP language. */
@@ -18872,23 +18873,28 @@ reset_machine_option (struct gcc_options *opts)
const char *ai_infer_level = getenv ("AI_INFER_LEVEL");
if (ai_infer_level)
{
+ char *collect_gcc = getenv("COLLECT_GCC");
+ const char* gcc_exec = basename(ASTRDUP(collect_gcc));
+ if (gcc_exec == NULL)
+ {
+ return;
+ }
override_optimize_options_1 (opts);
- if (lang_c_p ())
+ if (strstr(gcc_exec, "gcc") != NULL)
{
override_C_optimize_options (opts);
}
- else if (lang_cpp_p ())
+ else if (strstr(gcc_exec, "g++") != NULL)
{
override_CPP_optimize_options (opts);
}
- else if (lang_GNU_Fortran ())
+ else if (strstr(gcc_exec, "gfortran") != NULL)
{
override_Fortran_optimize_options (opts);
}
}
}
-
/* STMT_COST is the cost calculated for STMT_INFO, which has cost kind KIND
and which when vectorized would operate on vector type VECTYPE. Add the
cost of any embedded operations. */
@@ -20348,7 +20354,6 @@ aarch64_override_options_internal (struct gcc_options *opts)
&& aarch64_tune_params.prefetch->default_opt_level >= 0
&& opts->x_optimize >= aarch64_tune_params.prefetch->default_opt_level)
opts->x_flag_prefetch_loop_arrays = 1;
-
reset_machine_option (opts);
aarch64_override_options_after_change_1 (opts);
}
diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 90f6dfe85..179d507f2 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -5799,10 +5799,13 @@ 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", "");
+ const char* tune_native = NULL;
+#if defined (__x86_64__) || defined (__aarch64__)
+ tune_native = eval_spec_function ("local_cpu_detect", "cpu", "");
+#endif
if (tune_native == NULL)
{
- tune_native = "native";
+ tune_native = "=native+";
}
setenv ("GCC_AI4C_TUNE_INFO", tune_native, 1);
@@ -8129,7 +8132,6 @@ driver::main (int argc, char **argv)
putenv_COLLECT_AS_OPTIONS (assembler_options);
putenv_COLLECT_GCC (argv[0]);
maybe_putenv_COLLECT_LTO_WRAPPER ();
- putenv_ONNX_FDATA ();
maybe_putenv_OFFLOAD_TARGETS ();
handle_unrecognized_options ();
@@ -8187,6 +8189,9 @@ driver::expand_at_files (int *argc, char ***argv) const
void
driver::decode_argv (int argc, const char **argv)
{
+ const char* libexec_path = standard_libexec_prefix;
+ if (libexec_path)
+ setenv ("ONNX_FDATA_PATH", libexec_path, 1);
init_opts_obstack ();
init_options_struct (&global_options, &global_options_set);
@@ -8560,34 +8565,6 @@ driver::putenv_COLLECT_GCC (const char *argv0) const
xputenv (XOBFINISH (&collect_obstack, char *));
}
-/* Set up to remember the pathname of the onnx.fdata. */
-
-void
-driver::putenv_ONNX_FDATA () const
-{
- char *lto_wrapper_file;
- lto_wrapper_file = find_a_program ("lto-wrapper");
-
- if (lto_wrapper_file)
- {
- lto_wrapper_file = convert_white_space (lto_wrapper_file);
- char native_file[512];
- const char *onnx_fdata = "onnx.fdata";
- strncpy (native_file, lto_wrapper_file, 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);
- obstack_init (&collect_obstack);
- obstack_grow (&collect_obstack, "GCC_AI4C_ONNX_FDATA=",
- sizeof ("GCC_AI4C_ONNX_FDATA=") - 1);
- obstack_grow (&collect_obstack, native_file,
- strlen ( native_file) + 1);
- xputenv (XOBFINISH (&collect_obstack, char *));
- }
-
-}
-
/* Set up to remember the pathname of the lto wrapper. */
void
diff --git a/gcc/gcc.h b/gcc/gcc.h
index ff3ae8bed..63231ddb3 100644
--- a/gcc/gcc.h
+++ b/gcc/gcc.h
@@ -44,7 +44,6 @@ class driver
void set_up_specs () const;
void putenv_COLLECT_GCC (const char *argv0) const;
void maybe_putenv_COLLECT_LTO_WRAPPER () const;
- void putenv_ONNX_FDATA () const;
void maybe_putenv_OFFLOAD_TARGETS () const;
void handle_unrecognized_options ();
int maybe_print_and_exit () const;
diff --git a/gcc/optimizer.fdata b/gcc/optimizer.fdata
new file mode 100644
index 000000000..ae0e584be
--- /dev/null
+++ b/gcc/optimizer.fdata
@@ -0,0 +1 @@
+656137356462666463346364333361623035396139323366643262383764363763323530613631653861653634666630333030316562323662346133633566313233326432366139383465346338376266393132363438333765656463366235613461313434346139333334396265306163333731646537376430643834323664623863366163343363643130313435636565623834363361316133393230363937653835653762353534626439663133633538623062353439646237616630333237666136663433386334626639643465303163653832333062643863333664336630376231643964316231663933656333386338656262303734376137313565643963396535653131303763646533393234333735613333633132353061393531333935623539643834373266303861633739373862366663376365383233326139383939363566373061373361613939336537366631353334346563313061373365663635633332663437653136383235343635623234366430373330366336363237623962656465373233346131343264313137653838643334616430346339363732613237623866636364313232613934343261643231386531356430343965303330306332326266336634626163333461643139653962326566303064343333623037313762303934626336363537616339343637306633633066333231613063623339333539376461316632653234353938616133616463623534356232346135666261616339646638373031356633306161626465643665633066616264623965656138613233353331303236363565616133323131653935643363353832366663633434626236376663386335666364333530336433353234383031636264353761616638663031613263353738326438656265623236653338323232386565626464393034633962373835363264656664616439353336623462376139333134656662373033626135336138333136643032636430653334303861616439333736306363383862306439623962646435383931613161653334623666313236366366373962356536656434396231303338646265323666386461366430396262353536313433636132653466623061346164303635636162336536383062306637306438626232646636393462353563366437386531316463383239373361643230643566333736663330656538643461313161306163666361663064383962373736636162323565383865336630333461343939336231366437386265323439626332336166376262623837353163376533353066636339313233323761613766333633343432623331373530376432376534623831333339383964633439653966303663303439623739346133626330646333373831393930316439326233646565623761646664356230336233363230383833616266643463626536336133346664656433373630343738343262373863646131373633653939636430616439393731306435313664323166313530636464393664613738643461356437333564343036316262353462313336663335313763323661363564343330623965363866616534323163616337613964356465333333663739313835623363316462346539643539636435303166306664366135313063333630336531336532346134306234626632313565333739356139613430643630613834353666623762363363326431316538313730316132333165383561666434623564623831616263316464353664323731373332656430323435663836393162646335646164333437366436663633353630373762316161316436333461393763343130396235396237333534376639343063316463386432316330663138373338386632643361386565636665653766643836373930326664346163333162613163396664663531626161326134333762666330393261316637333265326138663036363736333734326230373730613665323665333266326265356534376133373330393466336639623431383863383433643563346265613561326134616334626262646637666163376365333962323036323537333737313534313066323364623937303534623665623237306566636366623763623431373666383236383134326365613136653238623231646339353938373030656631646238653961643434653765313834316231346231323563636633356131376538636666613866303638323362643436636638353665346166323633623861616639363862613835306234643961666662656334393366613066653061383333653965343633653837613263636530633863303861313363636361346132613431363962336539613463313366633934633761363761623039396365393263633638656134376162616631363838616238613137323032663864613035313363353335396432373530363233663234343136346339663435333834656630366537353336306137366434646264303466303633663630386363636337383066316631323836353135393134646139373035323637346164303965323536666335393864636364346433383564616435383862366464326130336536313934636139386438373462333162366230623165323533336263313430386430643661386261633061313631613639313232313734383136336464636231323130336231613131373336636238656635353635626666303535663331363332353338313363396334313631333034656133666365353561643830356565633137346638643739636136376432303761633436666465336232356236653164353163346461656165333038653266336161383966633961323462376262386430363536323932373263343731313562356139336265383765336139643837333966623265386131666561366161333138353261663139303338393733346335313934363761393137633266616431663436343236613231663865636236346133616662623761373633663830623231393063616534633032316538626436633731643261313866666339353836373133363939623966636239333637373764323863663964376134323134613133346335326162363334363334386666396666336534646565616264363966356566323465346538613762623864303766646338666264643466666537303263623162326539653435643130313061386235623631306232303139633962653661303038376162323666343263356465313035393535313531373665623537363237373934366266303434333463303562646535623762313565326631393061643033613838363963333933396162363834393636613136613036656435356339616665636134313034663335343465646335333738663063616330353634316466336438373835326638633037656234396239303730613338336332613839323837643561333235393366323531303032666436616435313137313166383433396531626137353932616538333330653164326438656166343339363262366264326632376564396434396333356565343733383137666333386462313164333630303936336137323863313634613031393931613164363237643262353162376133643935373036306336346161376563383862316365613139376535626535626234666331363163303835336362393535613530636234643633626364386566396132333232373733633230393865663664636334393131643133383736373833653261383661623632343237653937366164386564633433396130313166306430316134653864643263343835653438383687144d4395a52c41e3842b41b03f3743f207264565084e41e0fbdf3bd429b13da15eb33d7e47b93b309daa3890d2d93d0000803f04a59dba191d513e33226b3acb4c80be39e785bb0bb9f63c65cdfb38ac15eebd303d01bb4419f23a55cf06bc7ff1453cfd78433b0bf6febd9013433b3b6da33db673a03b2b9491bd7ac8e03b25dbe63b684e0dbcbb0a3ebdc44800bdbcc493bd93e601bd4b6484bd0a60f4bc60dceb3d70e9debcf709e2bcfbb3e83bbdf4023e0ae182bcd48370bd6b8bb5bc431600be698b0abde7c93bbd7d1e83bcc37df5bc6bc82abc8cb32c3d068300bdd32812be02a169bc1040c7be90c1b2bb666f10becbb08fbcf74b17bc1b1602baf138b43d5224843abfb0d4bd60cdbe3a82a4993c8ae4a63a8c9fa8bdc8a86b3afcabb83a4f68c93e8af795bed2d6ff3e5dc599bec525003f902e14bf7e73e93eea321d3e3bf3d13eb012e03e90fde23e313b7bbeef3fe23ec1eb88be7e3eea3e4d0431bfff85d93eaf825c3e333dc33e4d1ad93e44b8cf3e02d697bec0bbf93e84ba9cbe99cbea3ebef11dbf493be73e1640303d18f7ce3e3e59e63e4f3c0a3f3f3e73be1d3cdb3eda1a7dbe56e3d83e8f333abf6d5fcb3e7268383e67b9b13e156ac73e78c507be519081be4deef33e857f81be2959073fb3003ebfd134eb3ee775bf3e5ce8d63e5cf3e63ead860fbef58193bec791043ffaf29cbe689e063fe7772ebf8659fc3ecac0a33e0be3df3ea97afa3ee85f82bdaf0398be529dfe3ef1a39cbee6cdfa3e616738bf1314f43e2425023e5e10d23efe12ed3e3069b8be5e9d7abe7bc2f23ee6b27fbe498d143f2bf545bf934f013f53442a3f23dfe13ec02fe13e48d3cbbd07bc62be8851013f064a90be5f340e3f2a8f42bfa2bcf63e60cdef3ec14dde3e41c9de3ebc90113f286f3cbe86e5db3ed02474bef976ec3e177231bfd8f5e43e9cd5d93ee0fdc23e3c93cf3e6035c03e176199bedfb0f43ee0f39bbe9c8fe73eded525bf8412e33e7485393d99acca3ec677e13e8a5bc83e5ac5a1be2528fb3ec1b9a2be4bd1f03ed92417bf2ae7ea3e7ebcc63c3b37d23edcfee73eb381c6bb8e48d73b5463ca3abdb1b13a9904c23b8f9948393f7ecb3aea64a0bde43c883bde8ce03afdab793cb6d945bc09d0a33c5bd255bc5c04a03c14a8243d153aaa3c3cd991bc6a70913cc9a38a3ca956d6b9ddfa903c944948bbbb53903ce48761bb6e0a0abca78a8dbb728827bd1d7904bc7ea513bc9f89cfbbdab6b23c30c117bc6dbbae3c19b1d5badb1d90bbb6d427bcd329ddbc3f8f1dbc879137bcb972d63a89bc4c3b9619283b9b4b133a8c65e13b3901103d9c7e643bbf128fbdef865d3b7f258b3b033a123be896e9baee8caa3c4efb683c7998c33c4aed8b3d50a2ad3c7aff60bd678b973c45cca63c73d7c6baf325473b210f1c3c0ec3173bba9d463cf2b3583df487003ced3709bdbb3eeb3b5210f63b41eb303b9665293c7953a73bf34d5c3cab738b3c1f0cf03cd77a813b1d6947bdbf322c3b25a7c6397325e93acb3c953a2266d33ba8ea28bbf4e2d53b3da9383d0bcfd63b2cfa20bd251aa03b2a8ab53b03529c3cbbbdc9bc0e1b053d7c27c9bc955f0c3dd4f3323e0edd023d9f9a0bbd506e003d347a073d4c951bbb7989343c8fedaf3bf6a1233c00eeaf3b63dba43cfc7e533ac83606bdb09646bab2af50ba072e9dbb2548b93c7737debbb6e0a43c5b1e02bcff8d3fbd274eacbba96c3dbd3e8ceabbf3fb13bc5714203cc98936bc98db9d3c83d268bc0148a83c9736483dc820a43c9de221bdb90e983c2fe3943c3a5fd4ba81ef3b3c751c973b23fadd3b4f8b333b37b4b53cd044e53a88a81abd4a7aa7b99dc501bad8cda93aa7c572bcfba0d63cc1da86bc4d3bd73cf09e943c827ccd3c1b8956bd3883c23c8637bf3cab889fbbb5c2d13acb99fb3b4295273cc41dfc3b65be0e3d1dddd53becc235bdf19ca43bbbdec43bd1b8b23b4ac6afba5fd6943c218509bb2bc0763c48c8f73c62c3813c565f25bd1374443c26cb633c1fda053ddebcf13cd9f829bce620e43cf20079bbe584b7bb3ade37bc40043dbd140f3fbc183f64bcb6b97fbc4640e33cbeff89bc9ecce53c627f3bbc92a8a0bde11326bc9058073c296f68bc939699bc7bed253b46d30cba6da4803b995d9aba7292253ca565a43cb7b8d03bd50711bd21df8f3b9a02803b3f98f83933cbb1bb98a95c3ca09600bc14c1753c3184703d7760523cf2f390bdb6663a3c91c9433cc137633b6be27d3c997ecab9060da63c1600cd3bafce23bdae80dbba1ccb88bc058da2bb467e21bce8aab63edd089dbe4f78fa3e1fef9fbe16a1f23ee01a18bfc853ec3ed3a3433d9ce5d03e226ce63ed83484be140466be9106fa3eb0117dbeb6c3133f0fb33bbf9787053fe44c0c3fa01cdd3e379ce73ec6904b3e0ba483be3ef5f53eb7fd87be03c1053f8d4c2dbf6257f73e6866ba3efd92cd3e0945e23e59a1323e199391be37c4023f598595be7f81f63ebe6c2ebfc3e3f33e33fa323e77f7d43ed851f13e7b92053fde4a37be0ba8cb3e5e0d53be7047da3ef3a24bbfddabd73edf0dce3e3c6aac3e8810c63e1a6f9f3ef0b686be44eae93e0b2685bec4bfe73e164c3abf6067e33ec99f4f3ec58ebf3e6252d03ec3eff43ea926a7beb70f063fd659aabed093fd3e73c6cabe1c69fb3e3f861d3d4d3ce13e0a74fa3e4c35063f755379be2f12f43e7d848ebe2060043f9d9103bfaf5af83ef9b1043f8e7ac83ef721d53eaeff133fb67d2dbead28cc3efc3668befd33ea3ee1b941bfed13dd3ea8940e3fcfb9ab3e82fbc33e38e7e33ee37590be93efe83e41ac91be6fe2df3e66f21ebfe293d83e6b91573de8eabf3e3abcd63ea5db103f5b217cbe49c9d13ef7ac80beaa60d13eeaa93ebff204cd3efe974e3eac14b23ef978c33ec984cd3ec2d8a2be4c3dfc3e149ba5bec9f1f03e00f911bf3f4deb3ee781273b690cd33e1ccfe83e7ed9ce3bf7dd993be26ca43aa8abba3b4c8a1b3b2357313d7eb9d73a64e851bdaa101e3b6a432a3a1b5457bb665899bc7993fb3c83c150bc13abec3c749d863df737e23c2f3b11bd8b92d03c1dacdb3c072077bb17e3d1ba1ad1323c254dd93a8bd12e3c5ea3213d4f9b263c158d73bd8c5d013c0cde153cbed5d0bb31ff0d3c59f8ff3a5b2df23b29da083bc4561b3d0491673be76542bc74fd963960539eba288b47ba9f2eca3aa558a73bd043abba8049c33bd32eb63ce799e73b4296ccbccda17c3bd5eec53bfddd8f3c66733bbc6a5e943c11bd53bc14dda13c7fae023dd800a23c034b55bdc354943c0c158b3c9c59a4bb82b70f3ccb7c783b7df2123c6d74be3b126bdf3c3ac9463aeeab5abd4df224bb11bdc1389b6322bb232aa8391f7c863cf42d3ebbbb0f803c049f493da7cf3f3c6c9924bd33876e3ca5165b3c972233ba2a880bbc8a30893cb66825bc1a729e3c6624933d492f883ccd7243bd00c5733cf019833c0308c93bc72d3b3b88a5c43bb947243bf435f23b3916afbbdb18df3bd7685ebde8eeba3bdf2ba03b223b07bcea544fbc0669fd3c81fe8bbc1275f73c5e02723df0b1cb3c51ae5cbd1d3fe33c8980de3c71bd48bba6c40b3dfa96ce3c08c5663d3ccf6e3cc800143d2a08933c0cd93f3b508e9d3ce864d33ccbf2adbbc124033c9a36233bf554ed3b5729123bc4b9a4bbcd83b53ac16774bd3cb33a3afa121c3a7ad068bb01c4603ca49e9b397efa6c3c0395df3b0cea40bb160a703be9dad9bcca8f593b66b085bb8d35a2bbae80203ccd53a5bb30d02a3c432e18bb9795e63c58c982bb874772bd99d64fbb118faabb5d1820bc388044baea1e3d3c7837df3b2164373c1f98673df94f183cfc0d45bdf80b223c2b146a3c8cd5d739622b99bb01a62f3ca437eabbc703323c1cc9e83c66002b3c451f67bd9e4f1e3c61a0233c797bf8bb9576c33ae97c8a3cc5ac933b991b553c41f85e3dedd8523ccc9946bd22335f3cbfec273c24fb0bbbaa53023b8c62623c3f8dd3baa4fe833cf033123d0131633c92ef79bd43a24d3c61be0c3c8f4de1b94e9ed1ba1e811f3cf46e85bb7e115a3cf3d5ae3ceca73e3c3c0c41bd57df253cdcd2213c263b3ebc345d733c81be6f3c8aadee3c8a5d393cdf08703b7361813c7d5222bdde9ba83b5465c138af778e3b2e20b83c9a0c69bcfef7be3c44b00bbc850599bcf7406cbc56d64fbd1cc44ebc73e483bc1f71883e25ab7ebe1807003fd1c286beef68043fe1ad19bfd38af93eb4a0c43ed240dc3efb15e63e487f4c3e640b7fbe4907fd3e871b81befe66173fe60e1ebf5886fd3e6022093f8c18e23ebb31003f63cfe83e27805bbe22b0e83e84c37cbeb6d1f03ee10634bfa8a4da3e3d3fbf3e372dc53e6920cf3ed1e1703e1f888fbebced023f8e4692be6bf0043ff0b121bf525ef13e6ed0763ecddfd23e197eeb3efe3d8abd61ab74be3ce8023fb0d484bead74073fca504ebfad57e73ebd250f3fa009c83ef804dc3e00864abd678da3be815f083f71d7a9bea740083f6d2e1ebff19dff3e8968d23d832ee23eeba4fb3eb51bfb3d7b298fbeacc2fa3e6b4d91bef1b7f03e642645bfe625ea3e460e0a3e602ccf3e7c86e23e7754f7bd306785be01ad033fcc7297bec0ab093f2aa034bfa508033fe0570b3f4acdd73e4e7afb3efd2fb53e5b688ebe8e41f63e8fb791be0563f13e9af428bf8858e63e54962f3e22bec83eb4c5e03e184e94bd78de98be707c073fb7f19fbe0ecb043f9c5d33bf7316fa3efcba313eb5eddd3e5283f53e2e92ff3ec37d61be00ebe43e06528cbe7949fa3e66ab29bf108de43e9b95ef3e8eb3cb3e7a2cd03e26bb71bd334794be2725063f18a097bec754053ff6d52fbfa253ff3e6f3d8a3e9d30dd3e5391f23e376e12bbd12e833ce1a93d3b3c98593cf3155d3bdc9895bbd4d0b73a64e731bdd2869b3bbf23bdbb14175fbbeca5a03c6921c7bbdcd9db3ca82787bbae172cbd01edc4bb4409c2bc296076bbc0953cbc70712d3cfafa62bc047fb93c822e8cbcb852c33c62d2833da0b2bf3c085509bd7573ac3c61cdb13cbef44e3c54518b3c2d402abcfb4a8a3c4f8a1abcceead03c35e13bbce83d47bd35ec3cbca71f32bc3d365c3a71c946bc48e8cb3cae9072bc6483c53c7441ad3dc78ebc3c05a12ebd49a4b13cd1ebb93cb7e544bb8d0f963c7216a0bbba6ec13cffad77bba48636bd1dd90bbc591d06bd82f1d5ba9d3114bc55807b393f0345bbb84e4b3c4788cdbb1e8a423cd5c7873d8ff43b3c4e5a51bd1e82293c0147383ccfc8163bb605d53b54eb323c2549cc3bd62c3c3caf80223d556e1e3cb95c42bd3f9d413c7dd2243c6b08c03af82effb91db7853c0378a9ba0802793c2e6b783d346e5f3c093b80bdd148663c0d6e5e3cfc6844b9f2e1cf3a7d18613b3b8734b953bb413bbdbc943cf6a8323b88962dbda482133be6971d3b12ad30bbac4f143cd94ca43b87984c3cdbf16a3b9dc7b13ce8e6633a286b77bdf5c7373b162fa73bce6c1a3c33e88cbb4363093c1c049fbbc6b8373c95c3953ca57d343c76441ebdbfbb0f3c3f56013ccae5863a4ddc20bcfcc7c73cbafe29bc10149b3cee14873d03ae953cfa1e36bd2aa5863c7b79903c5c5125bceebc103c7d270f3b0b70023c42fc8b3ab278eb3c84d4fcb816012abdbfd66639ea10e4b8cc1e11bbed1c073b1c3b803bd21e9a3ac633b53b2f52083d9c50713becd382bd6714543bc395063b79e0ae3b7b9e4ebb2d0d253c44b83abb4d6a393c23814b3d6e861f3ce06cb6bcfe8e0a3c511f173ccfa56c3b873eec3a1c34e53b4381d0394e17d73b2c49ec3cd516cc3bb9c42bbdd3fa933bf49e793b20936a3b5043823961cf3e3ccc562cbaed9e403cbf96063d9c28353ccb3f5bbdf558163cdfc9fb3b5bf28d3cd425acbc618d163de421c1bc0a86163d09ec2e3edc5e083d3d898cbdbec3113dc213043d3d38c4b9466a44ba1efb2f3cce0f9c3bfaf92a3c5388693d991d113c7ce746bd74ed1b3c08d21a3c382fb03c5592a0bbccf6563c24ee8bbb5908563cd779163d06b5503c0580fdbc91d9423cc241493c356d15ba05fd523ca5611cbbc379493c66e7f33b0c1f073dc62fe0bbd3d455bd42683fbb482ec2bbf0d0a83ee99383be0eda033fa74082be4c841c3fe391f7beb6a2063fb386103f5f2feb3e6bafec3e53dfbd3e983a56be1528eb3e1f3085beb3fdf33e12fe3dbfed47dc3ed362e53eb34fc33e0b0ad33ef34e0dbefeac85becdbdf43e75bf95be249c133f67db35bf21d8013faf1a133fd964da3e7c4afb3e8408823e7fdb8bbe77f7013f8f1595be6804053fa32217bf4881fe3e6341823e55beda3ed8fff53e0002db3e85dd6bbe93cedf3e11ee68be5e26d43eb9f24cbff431cf3eca59693ed2afaf3e60d4c43e81bc54bd13eaa5be9661053f5ab0aabefc59023ffba229bf847c003f92e1f53d31bae03e5082f73e9e01b63e759a8ebe7133e73ea36590be9342db3e680d37bf872fd63e7d461d3d8813be3e0816d43e5d82d53efaca83be81e5e23e01ad87beb5c6d53e2bd731bf007cd03eca1deb3dc447b93e4013cf3e154eff3ea8fc75be08b8e23e116189be36dafd3e4dde22bf2458d63e2faead3e25c6c73e0a54d83ed91bf23e02e993be25bfec3eaf6e96be0defec3e48a621bfc4c4e43ef7ad213e4974ca3ecda6df3ea114383fdaf953beb966d23ef24e4dbe291ce93edef430bf7100c63eb01ccb3e95b4b93eda29b93e8a49ca3ecc00a4bedfa8fc3e2bb1a5be2fe1f03ec66f16bfd2b2eb3ee1e29d3c966ed33e198de93e1904c63a3ae604bcfeff653c5d0bfbbb80629b3c76985c3d60918a3cd08057bdd35c933ca83e6b3cb9d066bbb36d47bb05eb803c4bb4a1bb48c3823c9bcc033d9e47763c32a143bd3cb3613c960d683c8189d4ba9301293cbd3f263bef5a323cbab8a63a3d59e83b56dc643b234648bd7674be38ef94443a9df5abbbc5be603c02d2df3accaa403cb260ca3b856f0e3d2191ceb9dacf39bd1bf821bb5766d73bb84111bccc86c93aacf4613c8371e5ba12d1533cf7936e3d66c8023cadd91abd5d2e313ce4e92f3c223b19bc5ac9183b1caf983b0cc0a73a64a1153cd31c0c3d1b5d923bfa1f24bdbff1a33b73bd7b3b8bd9693cd6ba7bbc2d09db3c758c83bc3085003dd3330b3eda22d93cf0ae09bdc729d63caf83d93c05610cb9a04e24bc8d2d9a3c82923cbcaadca33cb17a873d11cb9c3cf6b041bd449f913c7196923ce771feba39f6edba18b3143c1d3807395c21113cd00b253dfff4303c962c50bde69c1e3c5710de3bdb3c8a3b096e2ebaec6b373cece9383b9de8433c3b4ce13cdad3143cce5928bd2b30253c4de61b3c3e5925bc0d53e5398ee9f83b50c71b3a51bde63bd55e813dfbd6bf3b938257bdb3e9943b152ab03bc25b1cbc98f59c3b75ed303b8ec63c3b464e713bbe07743dd60e2a3b004d1bbd36ec863bd63c1c3b6bdf53bb3c309539a8c8743b973cad39656aa33bbda3aa3cc2e08b3b98d705bdc680563bfab04a3bf73b01bcd76e913c604527bcaec1813c9c9ae3bbba0438bd285216bc94cc29bdfc310fbcaf4c42bc138f3cbc7c9d66ba60164a3cdf580bbbb5af403c7261863dcabb2f3cec056abdf8051e3c83f1283cb600b9ba0b9fb4baba50213c095a5039ac32513c8fb07e3cb9371f3c50a40cbdf843383cd969f33b1c34fbba0cff823cf9d281bb7aeb6c3ca95f09bbc72cc5bcb93379ba67f4d9bc132aa2bb94a6afbbc79f74baf9082b3c7c42053b4adac33b969a483b1dd779bce885103befd8c9bc60d7f13a8a93db3a7055c6bcf0cbd03cc67c75bcc196ce3cdfda89bc85e3a2bd8aaa95bc66897dbc339896bcc08298bcb27911bb4fe4b23b3c89513cd8bb8e3bc0df4a3c58980a3d549f0b3cc3ed54bd565c563b3c35843bef71a33ab4b026381dab4f3c8822eb3b9f5b2e3cee511d3d170a113ccff352bd2d41ee3b321aee3b6479c43cab76bb3c2a3315bc329aca3c2df32ebcfef9fdbb244a8cbcde3444bd365a57bc33fc79bcfe524f3eabe282bea97ffe3ee0ea87bed85a043f4be633bf908bf23eec11043fd4d8d53e307fe93e2094803e506d83bedcbde23e1b2f87bef844dc3ec77244bf0c1ad53e572e163e5088b83e047dce3e05f512bd894199bec01e053f30039bbed405013ff1cd35bf4e51fa3efd5b213ea77edc3e2ca4f33ef42bd93ef78591be6cf5f03e362e93be94a5e43ee31d24bf596be03e801dd13d9d6fc63ef969dd3ea28ec23e365070be2d14de3e2e1076bea661da3e850350bf606dcf3ef091723eaf36b53ee0aac93e73e2033f75f074bee398e83ed00681bedd7bfa3e5c7817bf1ec2ee3e2915ac3ecdbdc93eff25d93e57c8a13ed2bc91bec6adfa3e5af895be74e5fa3e9fe712bf1f7af83e8a3c543e818ed33e749dec3e1dfe373e30b09abe2467053f98de9bbee5e8f73e1c4120bf6ba9f43ecfc0c83dc7e6d73e8d40f43ecf2395bdb64287bec2c2003f7f378cbe3318063fc8053bbf5738f13e54fdb33ef711cf3e374fe33ee988ff3e3e2284be68f1e53e0abe89bee926e73e1ba927bf55aae23e50a6183e6633c33ee12bcf3e0df5713f4249f9bddd1fb53e513604be7ca4d73e8c1049bf475fd33eaac3353f74008d3e15f7913e0404a73e064991be01fa063fd0c293bedde4023f7f460abf9c81f93e9408353e1f18dc3e3858f73efcf3d8381165bb3a1ed4f13b66faadba6c05063c7346ec3cafeddc3b45fe41bdf10bd43bdc3fba3b9fbaa6badb92df3a26b8523cfb88553aaf90453c8a984e3d6898463c298d1fbd98062c3c9bfc163c1cba5ebb8ec0eb3b5b56e33ba93de83b953c6f3c42588d3b1f74293c44d641bdd26cf13b2f2f9c3b8eeacbb949b7b2bb1a118c3cad7ffdbb8701843c78c8823d01cd843cd9b152bd70f3683ce2ad813c7212ccbaec4bf7b9ca32633c53adf2ba37bf673ce368703dbf3ef93bc5774ebd734c0e3c2eafd43b1d1166ba9ac4243befb80c3cc95518380381fa3b0947f93c49f6f73b44c628bdd475d03b6e0df33b43ecf4bb5077083c5064b9bacd2e153c9732e3baf237133d999cdfba632885bd1b7666bb7f95a9baeec6babbe3e49e3b3735093c8ae9883b28a7ac3b56fd633b33ccbb3b570d0cbd10d3453b81ea883b829da43c0180e23c1dd790bc5b77dc3c925e67bcf0fbccbc8dd6b9bcfc2463bdf94980bce22cafbc902ba4bb28a314bb5766383ccac575bacba2123ce74f463ddd9c153cc43136bd77f4013c9d15143ca77fa6bb6cc6243b4b2b443b7c95ed3a29e8043c6fe59a3cf516b03bafeb2ebdae27933b25d6153b8d463aba796e2cbadb1b533c1c11c4bb5a7d803c19972a3d7808623c1fe637bd6fad573c4b5b2b3c6eb3733bdfd29cbb02e38c3c6401e0bb72e1973c02ab743da4fd933c87250dbd83eb5f3cb8d6773c7e4514bbe5a1113c1e4f013c77e4543cc590453b93870f3c78a337ba301f52bd5af99c3a853e65bb63e106bb8b42eb3bdbc01f3b0c81e83bfa8de0b91447893dd66b2b3a928a4dbd9da10cbbec6f0abb9e397abccf5c173c0f0c2f3be3d7f53b16b0293b53d0cb3c95db6f3ab36af1bca4769a3a01d4a0baad745a3b260265bcc3b99d3c7b6549bca87fa23c147e453df66d9f3cd7ba39bdd2049d3cfb239c3cc7bb673c45b3a1bc36a3313d580191bc70291a3d41f8493e28d1143dc25c08bd013f2a3d05af213d61f820bb113eaa3b27c4c03b56e3d53bbdbbe33bb0dc203bf4e3d03b491469bdfe07123bddd1063b179a0abb86a584bbb240a63c599fd5bb495f8b3c464f443db62c793cd51220bd4ccc823c5af24f3cbcef4fbb83b4cebb9c92663cb6c7fabbefac6c3ce308783d2d5c533c905d2cbd78ab3e3c3fbe4f3cfaea4dbb49ee5fbb25c5233cef6b833b531c3f3c66ab2f3d5edf4e3cbb9210bd9fbf0b3ccf49193c51fafe3e90c756be715adb3eed0d49be25c5ed3e64503abf318bd73e99b8e73e6b79af3e420fba3ee950be3e07008cbef683e93e99c88dbee548dc3eed4a3dbfacaad73e77d18a3df25bbf3e9445d63e5d96123eec65aabeec39073fe313acbed47c023fb3ef17bfa431fd3ed00cdf3cf490e03e6703f93e004bcb3ed5c6a1beb268fa3ef2aca3be1898ee3eb1f111bf6baee93e84cd133c8a79d13ecd3de73effab5bbd2daf95be81f8063f874ca1bebfdd083f8c9c25bf21f6023f4e4e653e042ae83e537ef43e40d452be2d4e56be66c0fa3e7ad486becfca143f22f03ebfcb79003f73ab523fb6d8d13eeacbf33ef57611bdec8a96be17ad033fc25a98be4623003f61133abff137f83e56b62b3e9665da3eab4cf13ea1339d3d765973be63fd003fa5225ebe73a4023f223e46bf07c0fa3e1742153f6e6ad33ea276e13e5393c33e41a99ebe5eeefb3e879fa0be8360ed3e320016bfef4ce93ece150c3d34b9d03e157ae83e7cc1313f72685dbec4c4d43e7bb05ebe9657f63e2b2d23bf46f4e73eea41023f2d3db33e3de6c33ec32ef93e79894cbec235dd3efa0c80beff1b023faf442fbf7df7da3ee041f53e6556ca3ece48d23ece5906be323b93bef7bd013fd4e195be642a053fc2c439bf42e8ff3e86ea6e3e9581d73ead4ced3ee3ffa53c7981c4bc2fe9fe3c2ca2d8bcd059093dc6c3193e81fa023df8b6b7bc09f2033d79b8ff3c49f32a39562805ba7df3053c165180bbbcd0123c40d1e33cb49be63b564903bda22ae43bf8dcd43b28edc73a4a1e723c347001bba98a5a3cc3bb9a3941c603bceecf38bbe8d652bd101354bbb677d0bb93ac88b9e093f03b2fe2a13ba98afa3b5485cc3b48564d3ce6af1c3b989844bd6033003b5990803bd374b63b69edd7bb278c9e3ce958ecbb98c2d53c827201bc0f529e3c174b88bdad15833c416b893c4daf89bbbb16193bab8f993b9dfc253a4927f73bcafa553d0de1d73b59cb48bd2bccdd3bf5f0803b81f4bbbb480843bb8bfe6b3c10542fbb2ca88f3cbf488b3de92c8d3ca05422bd97e1813c92924b3c9b449abba9f73e3cb3f69cb90173763c750248baaed0b7bc915b12bb4e7c54bd70120eba414ebbbb13b6993b035b9f3b9b30003cf3fd003cfe37133cd137a23cc222e73b4bdf9cbc3907bc3ba4779b3b15cbb83aebfbd0b92e3de83b42e793b910661a3cc1bdee3c18b10e3c708314bdc7bcb33b64f1c83be5300a3c7965a93b7086d53b11fb083b321bd33b4aa3073daa59923b88101abd06ea0e3b1fc62b3b2d4f58ba12d5ab3ba506cf3bd5bb263c3877c83bf6ba753d244e8f3bf1813abd39185d3bd2e57d3b8276f2ba6709933a02406b3b62d8003ccd922f3c6b14913cdfb9a23b101c0bbdc016893bdf0e533bc2afae3b475ceebb6daf9f3c1898fcbbcf1e963ca4eab23ced34983c43a94fbdf4b57e3c859b903cedb0c93b6632dcbb6a74473c1d207ebb69dc803cb0c53a3d2edb573cd72a26bd2792533c0be43b3c22f1a7bbcc598f3b4580393ccc597fbab1ad323c0d642d3db418fe3bcdbe1abd144c0b3c251e043c6ff7c038b3fc19bcf1758f3c170f13bc55fa873c7cb63e3d4697913c162a2abdd9b3793c797f703c46f85f3b6ca3ccbb876b933cbd24f1bbca59923cb7e1be3db0a5993c757365bd3f1a723c19e48e3c98150d3d5ce97d3c696698bbb0af533c1d515cbbccc11e3ce72cc6bb2b555ebdadf9c3bb1574dfbb3211dcba1085913c4c0e38bc0aff843caaf59ebb773309bd361dc0bbd991abbcc9284fbce6b04ebcb78f543b472d26bbe403883c90229aba79c2893c44025e3d09d63f3c71a104bd8af2273cf4af483c94822bbc54b8cc3bcfe0e739245baa3b7380fd3aefd9803dee35a638e80d49bd70861939e25276b9b3746b3df0cf99be4a85013fbc149cbeb2c9fa3e395836bf5a68ef3e65b7d33d6180d63e70b0ea3e84046d3e665891bee293f63eab5895bedc01ff3efa2324bf050bf33e3af05c3e5277dc3efa8eee3ead753b3ff22e34be1f33ce3e5ddc5abe523ce83e9a032fbf8f88cd3e50ebef3efc00bb3ed07dbf3ef885133f7b5159beb055e23e1aa26fbeb22fed3e1a3e2ebf16a2cd3e2a13b53e0f88b73e619dc53e6681f63e14e591be1b05fd3e1c5b92bef153f33ed4570abf29cee43e011e063ed901cd3e4469e43e2b3cf03ea30a66be5616d33e6ed568bea2f0de3e4bda41bf3da6d03ef1108a3e726eb93e0556bf3e1cddcc3ea1669abe0ef1f63e7bf39cbe8e07e83e905422bfe4c0e43eb492a13d2010cd3ec405e43ef1d1ae3dfa3394be6873093f6e5598be8ed40a3f25161bbfb5ab063f2bb9db3d4cf1ea3ee06ff43ea95a20beb6ad9dbeab13043fdc539abeaafa0a3fe7272fbf9e84f83e6e168d3e7781e53eece7f73ec8ce2abebc067bbee90ef93ed53186bea243093fbbe73fbf7e21f53eb51dff3e3b3adf3e6ec8e13e8c3b82bdb42460beab37f43ebfad94bed1b10f3f0c213cbf2383ed3eb8671a3fd463ec3e0cacf63eae35cfbdfc817bbe1854043fb85f94be2348163f22ea30bf9e4a023faf214c3f3f85fe3e6c9ef73e355a28ba4c46e53b017e753c1c87c03bb5cd5a3c2838803d14e5343c6861c3bcbc67133cc47ed33b35432f3be20f213c9bff823cdd53483c42cb7d3cd7ecc13c147a113cdcac96bdf93e433c01fb103cf2ec67b8032b1fbc76d99f3cabc747bc2974993c1376ac3da7358f3cafe934bd3fdb803c6c62943cbb5343bb2b6496bb8ec43b3c6236cbbbd0c62a3c28b4833d90e7243c73e35fbd115c123c48e9283c1a7d903b70063bbc1933853c7a7d1dbce9ad8b3c4fd20f3dc7d9813ca69f20bdbf14803c57ab7f3c9e6d093b7a2d093b4302ea3b71b3afba6f23163c5642c93c1d8bd13b0f0004bdba12ce3be107a73b50cd62bb92904b3bda05f33bf1b6e53a94a5033c7894953c81b8943b58933dbd97f2a43b48ce4b3bdcd3593ce3e559bb69ffcf3c759780bb8354c63c51a8f93d48128c3cfc8107bd7246b63cab7c943c5f9ddaba8bfc18bc714da03c576349bcf85d9b3ce84e9c3d2d09933cea4c18bd8afe8e3c2cea923c57ef41390ba48bba674fba3cb1264ebbce30be3c3bbaec3c138bd53c6f5990bd9be4c93ceac7883c02898cbae2e441ba0e1abd3bb2f5d83ae905473c4056493c4e330f3c28c50cbdd2b7283c5bfaed3b1f638c3abd2cb53bed0ee33b4416b63bef75073c7a38753cbd91b53b954528bd3e33883b5456a53beb300bbb350e223be1e5cd3b23ddb53a281be93b6eac4b3d0f77cb3b2d1da4bc19348d3b71add33b25c33abaff77a9bbb1ab9c3c42fa05bc597d893cd1002d3d5a22853c90a4dfbc0d71853ca7f58a3c6eb77d39743fb93bbbda9f3b16e8943be58d9b3b6730fb3ceab25c3b229453bd9aca833b4aa1a43b96f507bb02dadabb1dd25b3c73ad04bcb1f24c3c9b72693dab604a3ce904cdbc8ab0333cd192473c502a5eb932c9143c9b6c013cdd07263c16cf513c3848c03c8d37f23b10fe15bdfc5e6d3c77369e3b7d18ce3a9601d2bc8c6e113d1ef3d5bc8be0183db487b03d05ba0e3d330441bd93390a3d05830a3d7df54abb3c1eec39ffe3823b19d4643b0ca3993b4201613c87817a3be0aa11bd68463c3bee21413b569fd43acb4351bb32323e3c1130b6bba088403c54cb133d71f2583c650a7dbd366e293c536a023c74d3b7bb9c6d163c51feceb9dfeac93bc622dc3a1c951a3d5e7681bad78f20bdaf9843bae03ad3ba6f648bbb7558213c8c35003bacf80f3c9d37633adab56a3b47c2e8ba429780bd8bf9b53a6d12a4b995b337be64908ebe376e053fc7a194be0502013f392b41bfc7fdf13ee94f873e230fd93ea502ed3e751cfa3e23fc84be96cbe43e558f87becf28d63e7a5d37bf8666d23e3e12cd3da892ba3e2ecad13ef3b3e0bd481a99be552a0a3f85999bbec033043f8f732ebfdc82fd3eb766413ec4cee13e152afa3ed5fbc9bdf7a87cbea07f023f212e98be70b60c3f99f531bfe83c023f65bbea3e76d5e33ea863f63e10c643bdcae24bbece820a3feed88dbeb8a60e3f20903bbf721ff53eaff42b3fe856d93e8b80ff3e4c3d6c3e2ae494be964a023f5b0ba1be9672043f47cc11bf8f93fa3ee0cc2a3e33dada3e301eea3e83ade5bdd7eb92be2233f93e43ec95be8e2af33e1b4445bf0ddaea3ebdac2d3ef7d0ce3e1f51e73edee566be687674bea12d0b3f26429abe4c2a0e3fd4a73abfd5daf23e32f0c83e924def3e2284fe3ea24716bedacc96bed509083fde4e96bea6430a3f6d9a28bf534fff3ea56e833e002fe03ef2c5013f8a6cee3eb0698fbeb11df13ecbaf90be5aa5e03e8b8824bfa06fdd3eb118fb3daec7c53ee528df3eeebf65bed1b58bbebacd063f7390a2be63ab0a3f5ca425bf4a3d013fd665c13ec5fbe23e1b66033f7013da3ec0e782be5132e63e12f686bef829de3e8b6d2fbf4b60d63ef2c00f3e659ebd3ef7e6d13ee10ed03bc67f0f3c45741d3bb0daf33b5e39df3b5ea9953be727893ba42d13bd2afdae3b0be0f93bb1a2223c6d45e43c17da55bcd75a0e3d3c3315bcc99f73bdf2b34dbcadb347bd863263bc4a6e89bc65b616bc4244fd3b32023f3b1d43d13bef37a53b98fb123d971b1a3bf6eadabc30f15c3b3ace153b58fa5e3b7a05a4bb52f3323cc3bd98bb9696313c5b19993dd413293c2e094bbd4e47113cdadf233cafd7603b4c1ed6b8dc521f3c63c984bb2103193c7aae9c3d50640e3ced2c4ebdb62fed3b1a9b0e3c219f31394773703bfbc3bf3b7ef7813bfaafed3b08ff4f3c1a058e3b8a7247bdf9f8a73bf284e93afd4eca3b7be13b3c7d27bfbbfcc3413c4cf90dbb59ecb0bce6f836bb338985bd3d3a69bbb96002bc4396583adeb88e3babe9f53a68c2a83b90d7433be703523c6c20dc3ad1f31fbd4769b63a3f9c4b39cd774bb8cae544bc5967cb3c06f107bcd6d0d53cd829333d41a6b93cf5f544bd1104bd3c12a1c53c72fd99ba591fc43a7149c53b53dd633bf1c42d3c6eaf003d6568a83bf17a49bdca33c53bdc83f73b32946e39579123bb74dd2b3c8bc165bb2f85a23cfb398f3d7e6c2a3c843b5dbde50f0b3c67941a3ca7533abc59089d3c36c3babbc0f7a53c898721bc100554bdb9474abc4f55c7ba098932bcc25b5fbc6748a13c343f8bbc081a2a3d8a2591bc6225273d8a724b3ec527363d916a51bd51a1213d32c6133ddd415638a4aafcbbd6b8933c8247e3bbe3c0a13cd7cc673dfbb0663c007a6bbd67177f3cf1ad763c427fd03b7768a6bbba29a73ca4c80dbc9809b43c10f9783da206b63cd5b072bd0066893cb03c933c7f80143b1ac112bba4cc573c177680bb84c6723c20c1ef3cb47e433c100043bd006b2f3cbc46403cc9ffbf3ab881703b80e7f13bb2c8863b27b70d3cf15c393d0375343b1fe28dbdcab2cf3b4103e63b15fbe6399b7a28bcc41a9c3ce82757bc40cc913c12ca8d3de1278f3cb9e22dbd6ac1833c5c308d3c2693b2b9146a553bc2da3f3ca5c9b4ba5377503c22ac393d17be303ce29c5cbdb02e213c9cd6fc3b6307d33b70b6a1bb10d6843cd567acbbdba95c3c5583423d8129633ceadfbcbc3d8c4c3c02ee513c71f21d3ba86b813b0ff95b3ca70c603b11131b3c4dbddc3bc8ecfc3bc7910bbd621dc43b5b669b3bdd3236ba1c6a22bcc7db8d3c52901ebccc0d933c6402343d20a3803cd9a321bdbf9e6d3cd0b8783c6ff7febdd72f8fbeb78f093f69ac9bbe0b810c3f90f323bf600c003fcd33bf3e9193e83e0d03003f72ace63eaa6c84be1f57e53eefd186bee796de3e844839bff336d23e99aa073e2f92ba3e47c2d03edf4bcb3e5cd19abe3ee8f53eada49cbeeeaae83e374019bf233ee43e4746553db2d1cb3e233fe33e8726e93eeee48dbe66b8f03ea2bc8fbee768e13e522b26bf6932dd3e52e3b83dc097c43e93acdb3ed827c43e6d8d99bef31df53eb44e9cbec848e93e8dd125bf457fe33e54d1693d7e8fcc3ebf9ce13e4dea28be3b2f83beeca6033f080f8fbe69fb133f473d39bfb70afd3ef5fa323fd174d63e7598ea3e46f87cbe51e663bee731013f1c40a3bee01a083f662637bf387f063fa480163f9417da3ede77fa3e4d7ee43ecca487be8528f23efe458abe3bb1e33e7e172abfe295e03e86b4053e7d58c33ee5a1dd3ea22de53e812d8fbe8a61f13e0ac292be3492e63ee25826bf714ae03ec7a1eb3d285ec83e21a0db3efdb0db3edb2980be5ee4db3e3b6f83becb59dc3e61d743bf9e39d03e0572563ed04fb53e7303cd3ed31b053f1a1461be3b24ed3edb938dbe66d4f53e67e320bfa5f7dc3ebea2963ecf62c13e3c6bd43ef01eb43eb41c5dbecd55e83e46ee89be0a1a013f087d27bfd2fafa3eaca30b3f476cd63ecab1d93e7e9725bc0aa6923b86da413c0203193b5e7e673c7d50253df6e9363ca01e4fbd3481453cef6ad83b800e913cd1685d3c107bbdbb18eb313c57317fbb8e55233debb5bdbb863567bd2850bcbbad13d4bb915a783b3cd9aebb70534f3c4e62d13bafe06f3cc4473d3dd4005d3caa5922bdde91503c94ce323c6c72c9ba0449b33b0e88c93b4cb2603b033fe73bb935dd3c42e8e03b53f621bd5561983b2efc753bf430caba702d4bbb00841f3cfb49713acf192e3cac562e3d260b0f3ceabc30bd7b25f53ba67a013c87a3e2bbaaf2263c37417a3c7484b63c0fd47d3c83f36f3df7c9d53bdb981dbdf112963b2295473ccdf5c1bb65a4423c3e59caba46581c3c9d6edebad1f5babc6cce85bba5329abddd9e61bb5af783bbf23a0d3b800ec9bbcf327c3cfb47c0bb7adc703c76c75f3d7a92623c127c1cbdc5e2503cebc76d3c65cde53bae1696bc308ee23c4855aebcb7a5dd3c1be8ab3d7244da3cc1c500bd7f44ce3c439bdb3cd47314bc56d26fbcc8d1c83c2ec16fbcd1b9d63c500b953da937be3ca49477bdfddbb53cfacab83ceca2813aa65c283b462b443b001b303b5219883b9b2c69bcd1fa3b3b6a4157bd25cff33a86d1733b7638723ca39df8bc31f0463d30040cbdb2063c3d17f85e3e7fff3f3dc244cdbc03b6353d22542e3d1d7dafba2e2490ba394d413c37a186ba2f70383c4d72613d5156d73ba180f4bcc1d2143c78010d3c4a3125bbe706003df3418dbca9bd033d0efa2fbc06d36cbd8f558ebceb3734bd801486bc0cddb4bc406612bc4227823c76d9b2bb53197d3c3df981390c2a883cc7d35fbbce8969bd179ad8ba4928cbbbe034ec3ae66c83bba9e3313c9215cabbcacb4f3ceed13c3dda43483c768817bd7f9e373cde071f3c98165cbb49c9e23b0661753be990bd372c4fe93bdf4acb3c5385823b24b868bdfa2d5c3b1ed5863b0019fabcfbc00c3d48f179bcfe80fe3c86da8dbc39f5a3bdc936abbc0d3891bcd834b3bc837dc8bcd4ed0b39513a9cbbec06a13c93209cbb59daad3cf298bc3df1e5a73cecabb7bc324f923c1ba7a33c6b6d19393bc7093c3050a33a3b71bb3bbd4aaf3b9742ad3aeb0eea3a193e37bd3377a73b8e7ec53ae00107bbd15c83ba0c6ff63b3b5e7ebace75e43be425843d61f4d73b05e2e6bce263a93bc565dd3b5a00b0bb6f1083bcedb9ef3c5a57a1bc699eee3cdff4443d633de73c655e39bddcd2d83c8d39dc3cc398ca3e30f799be5f55f33e35739cbe2ad7e73ecbdf1ebf6f40e23ee2a67e3d5f78ca3e55f2df3e843761bece365dbefb42003f64bc77bef20d103f607440bff1b4f53eca680b3f8539df3e0234f43e937096bec00968be8efa083f20d277beea60163fddf130bf06b8fe3e82a3183fd38aee3e92c0f83e3bd408bef2924dbec2e4013f19ec5cbe02d80a3f419c52bff40afe3e84dc143fe2fdd83e29a5cf3ef803ca3e1fab9dbe42c6f83e51c09ebe1e74eb3ef50b12bf7624e73e8676123d7719cf3ecab8e53e5eb7c63e7f5d98be361cf83e2bd69bbe5d9fec3e885722bf52cfe53eda77783db381cc3e28c6e23e3374eb3e21d688bef36ff73e7ef38abe84aaf13e6be51fbfa438e73ecc10703e2cb9c53e5b45db3eac07f73ef8af6cbe561dea3eccd584bef612fd3e5af929bf0f33e13e1156af3ef905cd3e3e60d23e461ac53e17749bbe00ebf23efe389dbe19e5e73eeded1fbf2cebe23e24843d3d12e3ca3e9fa3e03ef894283e365371be2621e63e7c137cbeb5bb053ffb7c39bf5e23f13e8ffb1f3fba81c33e1a22d63e2c2152be8ad160bea9c9093fb7d78abe9693143f72bd2ebf65d9033fca360f3f29dee43e622edb3ed02b52be21f498bea13f063f359c9dbe4282013fedee39bf9a96f93ee155693e017ed83e3bc5f43e3c7cd23b157c01bc7e4d513c87f017bc8a814a3c50586f3d79f9433ca6121fbd1f83353c3356403c558cbc3a889492bbd9f87c3ceedacabb514c6c3c1c71883dfd31693cd94165bd84e1563c9c2c633c99e71d3c623cf63c0ff7fdbbdf43023d0695ebbbb0c997bdb63d0cbc5f589cbc72303abc9db459bc5bafa03bad5e10bb5660f73bdcc52abbeeef133c1acf313dcaa2f03b21c216bd7d90e73b8bf3fb3b22b61c3cc686603d2e8789bc1d2a543defbdd5bc95240dbec970debc8b5c97bc527ad5bce64df7bc0242da3a826aa5bb7dcf4c3c1f06bbbbed98533c0837513dd80e463c641a39bd29263c3c2701403cce511d3a4960b53a0770df3b01385d3bbcc5d63bffc119b880c9b63bd29235bd6979a53b089fa23bcb94933b23be4abb0bed663c91f3873bd52a493cf181853d41b23d3ca3f032bd3bca323c79ae443c160176bbdc7390b90c90ca3b9ed10cbbd19afc3ba719f13cda02be3b8d495bbdd26fcb3b986ab93b1ee9fe3aafca30bb53910f3c6571cbb894f9443c1a9b583d53d2233cba7468bd2218353cb656043c33f7823b443281395f5f713ceb62153ad8ba4d3cd4e85f3d2a3b2b3c583b81bd26e3e33b301c1c3ce4f8be3b592629bb97fa283cef297dbb3aea443c0713373d7b733e3c7a7d06bd943d173c1d9d123ccacd4fbb259aef3cac93523c7170c73c8fff193c819dc93c9f3aef3bd2ef42bd71560d3c9fcb3cbaa084ea3cf5eb293d313ea83ab2a47e3d4ea4713c639f9ebc53d7383cc9f23abc912fa6b9c37fbfba2f5c9c3cf2435bbce756093d8dba75bc7472133d8371153e8f580e3df2a9efbc49b90a3dc2dcda3c89499cba2e1a35bb57957f3c8f919bbbd3a7803ce376303d2a46583c823910bdd59b4b3c41db153ca3245c3b5846893cd9bdd33aed3a8a3cea89583bfc1ba3bc04d0e3b9daf306bd3ad9fdba4bd896bb9dcd6a3bd53faabb5a18553c33e7adbbb04c4a3ce84a643dfe4c3b3cdceb0cbd9119273c58862f3c070a24bb0d62643c955fc1bb466b4e3c78d2a5bb6c98b53c5af18bbb2d2c4fbd14b3d8bb4af60abcd7999f3be7722bbb5628843c9ef3c2bbca4aa23ce11ba43d9de27e3c3ecc54bd07aa7f3c3b3c753c50ed473d1cc8b03ca4ae6fbca0e0ab3c6f8e68bc0b89c2bc709672bc8e96efbcad4884bc197e8cbc88ad0abb1e84a2bbfa37913c4fed96bb095b813c7cdd893d585a803c22fd07bdb11f593c44bf623c8126713fe675cabf69320240baa8d3bf09da0e407fa3a3bfffd00340ba7c15c0ed5ef73ffc72f73f7e93713f0e20cabff9a00540fd5fbfbfd2331040ad5f9dbf1a5f0540e7b31cc07341fa3fccadfc3fbf516bbe49806b3f7352b2bf8ed8843fb13fdabf85b205306eefc8bfd21f6c3f5901abbf05c0a6bf7c29adbe5b6f7c3f1ec0d3bfb1228b3f86f0dfbf7abe103ea357d4bf9bf1743fea1da1bf818ca8bf62c7b7bd4cde883fe0f3dcbf631c903fda1f03c05974bb2e3a86dabf7ef1793f5253abbfc846c1bf90be6cbea4208d3f01acdabf48ff983f7c3f06c0a786392e77e1d3bf4598853f2839adbf0c11c8bf800f5cbe6546673f99f4b3bf94f88a3f65a8e3bf60833a30ce94ccbf7344703fb92d8dbfa461a3bf7c3cb0be6d96353f448baabf220c4a3f9221b7bf1d15b2306e6f9cbf8e9b3d3f29fe84bf77d187bf0ca1c2be4005593faa5dcabf4de9683f0d7dd0bf0e34ae304cdcbebfe07d543f528799bfaa14b0bf8e2dcebefab07d3f7cafd3bffcd1833f5f70efbf1131902ed667bebfbdae763f5632a8bfcf1aa9bfc9989040e9b06dc0f01eb6401a0570c03bf6ad40c896d7c03634aa40b06a80c00ab49840326aa840b13f71bf87ec15401fb2f0bf0caf3040caf509c018e9f63f3cb8f8bf8e1ded3f0322ebbf6ba5e3bf28a371bf
\ No newline at end of file
diff --git a/gcc/opts-common.cc b/gcc/opts-common.cc
index 176041bfe..35db76b84 100644
--- a/gcc/opts-common.cc
+++ b/gcc/opts-common.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "spellcheck.h"
#include "opts-jobserver.h"
+#include "ai4c-infer.h"
static void prune_options (struct cl_decoded_option **, unsigned int *,
unsigned int);
@@ -992,71 +993,6 @@ opts_concat (const char *first, ...)
return newstr;
}
-typedef int64_t (*run_ai_model_func)(int, const char **,
- const char *, int, int64_t *);
-#define PTR_UNION_TYPE(TOTYPE) union { void *_q; TOTYPE _nq; }
-#define PTR_UNION_AS_VOID_PTR(NAME) (NAME._q)
-#define PTR_UNION_AS_CAST_PTR(NAME) (NAME._nq)
-
-static int64_t
-ai_infer_optimization (int argc, const char **argv,
- const char *mcpu_option,
- int argc_hw, int64_t *argv_hw)
-{
- /* Load dependent AI-framework libraries. */
- void *onnxruntime_lib_handle = NULL;
- const char *onnxruntime_lib_path = "libonnxruntime.so";
-
- onnxruntime_lib_handle = dlopen (onnxruntime_lib_path,
- RTLD_LAZY | RTLD_GLOBAL);
- if (!onnxruntime_lib_handle)
- {
- return -1;
- }
-
- void *ai4c_lib_handle = NULL;
- const char *ai4c_lib_path = "libONNXRunner.so";
-
- ai4c_lib_handle = dlopen (ai4c_lib_path, RTLD_LAZY | RTLD_GLOBAL);
- if (!ai4c_lib_handle)
- {
- return -1;
- }
-
- /* Clear any existing error. */
- dlerror ();
-
- /* Run AI4Compiler model. */
- if (ai4c_lib_handle == NULL || onnxruntime_lib_handle == NULL)
- {
- return -1;
- }
-
- run_ai_model_func run_ai_model;
- PTR_UNION_TYPE (run_ai_model_func) run_ai_model_func_union;
- PTR_UNION_AS_VOID_PTR (run_ai_model_func_union)
- = dlsym (ai4c_lib_handle, "runONNXModelOptimizer");
- run_ai_model = PTR_UNION_AS_CAST_PTR (run_ai_model_func_union);
- if (!run_ai_model)
- {
- dlclose (ai4c_lib_handle);
- dlclose (onnxruntime_lib_handle);
- return -1;
- }
- int64_t model_pred = (*run_ai_model) (argc, argv,
- mcpu_option, argc_hw, argv_hw);
-
- if (ai4c_lib_handle)
- dlclose (ai4c_lib_handle);
-
- if (onnxruntime_lib_handle)
- dlclose (onnxruntime_lib_handle);
-
- if (model_pred == 1)
- setenv ("AI_INFER_LEVEL", "1", 1);
- return model_pred;
-}
-
static int
handle_lto_option (unsigned int lang_mask,
unsigned int num_decoded_options,
@@ -1132,12 +1068,12 @@ handle_machine_option (unsigned int lang_mask,
global_options.x_param_l2_cache_size,
global_options.x_param_prefetch_latency,
global_options.x_param_ipa_prefetch_distance_factor};
- int64_t output_pred = ai_infer_optimization (
+ int64_t output_pred = get_optimize_decision_from_optimizer (
argc, argv, "hip09", argc_hw, argv_hw);
+ if (output_pred == 1)
+ return output_pred;
if (output_pred != 1)
- {
- return ret;
- }
+ return ret;
return handle_lto_option (lang_mask, num_decoded_options,
argc, argv, opt_array);
diff --git a/gcc/opts-global.cc b/gcc/opts-global.cc
index e684bc5e3..843ace666 100644
--- a/gcc/opts-global.cc
+++ b/gcc/opts-global.cc
@@ -312,7 +312,10 @@ decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
global_options.x_param_prefetch_latency,
global_options.x_param_ipa_prefetch_distance_factor);
const char *tune_native = getenv ("GCC_AI4C_TUNE_INFO");
- prepare_native_tune_str (tune_native);
+ if (tune_native != nullptr)
+ {
+ prepare_native_tune_str (tune_native);
+ }
struct cl_option_handlers handlers;
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。