summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Schmidt <s.schmidt@samsung.com>2020-01-22 14:18:23 +0100
committerStefan Schmidt <s.schmidt@samsung.com>2020-06-10 13:20:40 +0200
commit9bcd901ae58054f4a13efc6bc6e198d56cbdba92 (patch)
tree0aa462366209f149878aade69f82596795026ee3
parent7ea924a99197d3156b02a00687380cd94b823fcd (diff)
ler-plugin: initial gcc plugin harness to be used in our builddevs/stefan/compiler-plugin-infra
Ideas and some code from https://github.com/mesonbuild/meson/issues/5090 This is just an example plugin that cold be used as a starting point. Right now we find efl_super() with GIMPLE and add a efl_super2 call when it was defined and in code before to allow linking.
-rw-r--r--meson.build9
-rw-r--r--src/compiler-plugins/meson.build25
-rw-r--r--src/compiler-plugins/myplugin.cc104
-rw-r--r--src/compiler-plugins/test-1.c11
-rw-r--r--src/lib/eo/Eo.h1
-rw-r--r--src/lib/eo/eo.c4
-rw-r--r--src/lib/eo/meson.build2
7 files changed, 154 insertions, 2 deletions
diff --git a/meson.build b/meson.build
index f820761ade..f0088b47d7 100644
--- a/meson.build
+++ b/meson.build
@@ -248,6 +248,11 @@ if get_option('tslib') == true
248 config_h.set('HAVE_TSLIB', '1') 248 config_h.set('HAVE_TSLIB', '1')
249endif 249endif
250 250
251#if get_option('compiler-plugins') == true
252 #gcc_plugin = dependency('gcc-plugin')
253 subdir(join_paths('src', 'compiler-plugins'))
254#endif
255
251subdir('header_checks') 256subdir('header_checks')
252subdir('po') 257subdir('po')
253 258
@@ -313,7 +318,7 @@ subprojects = [
313['evil' ,[] , false, true, false, false, false, false, true, [], []], 318['evil' ,[] , false, true, false, false, false, false, true, [], []],
314['eina' ,[] , false, true, true, true, true, true, true, [], []], 319['eina' ,[] , false, true, true, true, true, true, true, [], []],
315['eolian' ,[] , false, true, true, false, true, false, false, ['eina'], []], 320['eolian' ,[] , false, true, true, false, true, false, false, ['eina'], []],
316['eo' ,[] , false, true, false, true, true, false, true, ['eina'], []], 321['eo' ,[] , false, true, false, true, true, false, true, ['eina', 'compiler_plugin'], []],
317['efl' ,[] , false, true, false, false, true, false, true, ['eo'], []], 322['efl' ,[] , false, true, false, false, true, false, true, ['eo'], []],
318['emile' ,[] , false, true, false, false, true, true, true, ['eina', 'efl'], ['lz4', 'rg_etc']], 323['emile' ,[] , false, true, false, false, true, true, true, ['eina', 'efl'], ['lz4', 'rg_etc']],
319['eet' ,[] , false, true, true, false, true, true, true, ['eina', 'emile', 'efl'], []], 324['eet' ,[] , false, true, true, false, true, true, true, ['eina', 'emile', 'efl'], []],
@@ -420,6 +425,8 @@ foreach package : subprojects
420 '-DNEED_RUN_IN_TREE=1', 425 '-DNEED_RUN_IN_TREE=1',
421 '-DEFL_BUILD=1', 426 '-DEFL_BUILD=1',
422 ] 427 ]
428# '-fdump-passes',
429#'-fdump-tree-gimple',
423 if (package[3]) 430 if (package[3])
424 subdir(join_paths(local_lib, package_name)) 431 subdir(join_paths(local_lib, package_name))
425 set_variable(package_name + '_eo_files', pub_eo_files) 432 set_variable(package_name + '_eo_files', pub_eo_files)
diff --git a/src/compiler-plugins/meson.build b/src/compiler-plugins/meson.build
new file mode 100644
index 0000000000..8151e0e50e
--- /dev/null
+++ b/src/compiler-plugins/meson.build
@@ -0,0 +1,25 @@
1cc = meson.get_compiler('c')
2plugin_dev_path_result = run_command(cc.cmd_array(), '-print-file-name=plugin')
3plugin_dev_path = plugin_dev_path_result.stdout().strip()
4plugin_inc = include_directories([join_paths(plugin_dev_path, 'include')])
5
6myplugin = shared_module('myplugin',
7 'myplugin.cc',
8 cpp_args: [ '-fno-rtti' ],
9 include_directories: plugin_inc
10)
11
12myplugin_dep = custom_target('myplugin',
13 input: myplugin,
14 output: 'myplugin_dep.h',
15 command: ['echo'],
16 capture: true
17)
18
19compiler_plugin = declare_dependency()
20
21test_1 = executable('test-1', 'test-1.c', myplugin_dep,
22 c_args: [ '-fdump-passes', '-fplugin=' + myplugin.full_path() ],
23 native: true,
24)
25test('test_1', test_1)
diff --git a/src/compiler-plugins/myplugin.cc b/src/compiler-plugins/myplugin.cc
new file mode 100644
index 0000000000..6e67652930
--- /dev/null
+++ b/src/compiler-plugins/myplugin.cc
@@ -0,0 +1,104 @@
1#include <stdio.h>
2#include "gcc-common.h"
3
4/* TODO:
5 * Find all efl_super calls
6 * Traverse back to find function calling it (foo)
7 * Calculate the private data pointer diff
8 * Replace foo(efl_super(obj, MY_CLASS),...) calls with the next lower level function for foo and
9 * adjust private data with diff
10 * Make eolian more expressive (We need the implemented methods of classes, accross the tree)
11 */
12
13__visible int plugin_is_GPL_compatible;
14
15static const char super2_function[] = "efl_super2";
16static GTY(()) tree super2_function_decl;
17
18static void super2_add(gimple_stmt_iterator *gsi)
19{
20 gimple stmt;
21 gcall *super2_func;
22 cgraph_node_ptr node;
23 int frequency;
24 basic_block bb;
25
26 stmt = gimple_build_call(super2_function_decl, 0);
27 super2_func = as_a_gcall(stmt);
28 gsi_insert_after(gsi, super2_func, GSI_CONTINUE_LINKING);
29
30 /* Update the cgraph */
31 bb = gimple_bb(super2_func);
32 node = cgraph_get_create_node(super2_function_decl);
33 gcc_assert(node);
34 frequency = compute_call_stmt_bb_frequency(current_function_decl, bb);
35 cgraph_create_edge(cgraph_get_node(current_function_decl), node,
36 super2_func, bb->count, frequency);
37}
38
39static unsigned int eo_execute(void)
40{
41 basic_block bb, entry_bb;
42 gimple_stmt_iterator gsi;
43
44 //fprintf(stderr, "Function %s called\n", get_name(cfun->decl));
45
46 gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
47 entry_bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
48
49 FOR_EACH_BB_FN(bb, cfun) {
50 const_gimple stmt;
51 for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
52 {
53 stmt = gsi_stmt(gsi);
54 if (is_gimple_call(stmt)){
55 tree current_fn_decl = gimple_call_fndecl(stmt);
56 if (!current_fn_decl)
57 continue;
58 const char* name = IDENTIFIER_POINTER(DECL_NAME(current_fn_decl));
59 if (!strncmp(name, "efl_super", 9)) {
60 fprintf(stderr, "Found function %s\n", name);
61 super2_add(&gsi);
62 }
63 }
64 }
65 }
66 return 0;
67}
68
69static void super2_start_unit(void *gcc_data __unused,
70 void *user_data __unused)
71{
72 /* void efl_super2(void) */
73 tree fntype = build_function_type_list(void_type_node, NULL_TREE);
74 super2_function_decl = build_fn_decl(super2_function, fntype);
75 DECL_ASSEMBLER_NAME(super2_function_decl); /* for LTO */
76 TREE_PUBLIC(super2_function_decl) = 1;
77 TREE_USED(super2_function_decl) = 1;
78 DECL_EXTERNAL(super2_function_decl) = 1;
79 DECL_ARTIFICIAL(super2_function_decl) = 1;
80 DECL_PRESERVE_P(super2_function_decl) = 1;
81}
82
83#define PASS_NAME eo
84#define NO_GATE
85#include "gcc-generate-gimple-pass.h"
86
87__visible int plugin_init(struct plugin_name_args *plugin_info,
88 struct plugin_gcc_version *version)
89{
90 const char *plugin_name = plugin_info->base_name;
91
92 if (!plugin_default_version_check (version, &gcc_version))
93 return 1;
94
95 PASS_INFO(eo, "cfg", 1, PASS_POS_INSERT_AFTER);
96
97 /* Register to be called before processing a translation unit */
98 register_callback(plugin_name, PLUGIN_START_UNIT,
99 &super2_start_unit, NULL);
100
101 register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &eo_pass_info);
102
103 return 0;
104}
diff --git a/src/compiler-plugins/test-1.c b/src/compiler-plugins/test-1.c
new file mode 100644
index 0000000000..a23f7c9c3a
--- /dev/null
+++ b/src/compiler-plugins/test-1.c
@@ -0,0 +1,11 @@
1#include <stdio.h>
2void efl_super2(void){}
3
4int efl_super(void) {
5}
6
7int main(void)
8{
9 efl_super();
10 return 0;
11}
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 0ebbd53e9c..12a29d0555 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -1458,6 +1458,7 @@ EAPI Eo * _efl_add_end(Eo *obj, Eina_Bool is_ref, Eina_Bool is_fallback);
1458 * @see efl_cast 1458 * @see efl_cast
1459 */ 1459 */
1460EAPI Eo *efl_super(const Eo *obj, const Efl_Class *cur_klass); 1460EAPI Eo *efl_super(const Eo *obj, const Efl_Class *cur_klass);
1461EAPI void efl_super2(void);
1461 1462
1462/** 1463/**
1463 * @brief Prepare a call to cast to a parent class implementation of a function. 1464 * @brief Prepare a call to cast to a parent class implementation of a function.
diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c
index f5d880918f..7f21e0c0f3 100644
--- a/src/lib/eo/eo.c
+++ b/src/lib/eo/eo.c
@@ -529,6 +529,10 @@ efl_super(const Eo *eo_id, const Efl_Class *cur_klass)
529{ 529{
530 return _efl_super_cast(eo_id, cur_klass, EINA_TRUE); 530 return _efl_super_cast(eo_id, cur_klass, EINA_TRUE);
531} 531}
532EAPI void
533efl_super2(void)
534{
535}
532 536
533EAPI Eo * 537EAPI Eo *
534efl_cast(const Eo *eo_id, const Efl_Class *cur_klass) 538efl_cast(const Eo *eo_id, const Efl_Class *cur_klass)
diff --git a/src/lib/eo/meson.build b/src/lib/eo/meson.build
index 9cd33775b0..85434b5079 100644
--- a/src/lib/eo/meson.build
+++ b/src/lib/eo/meson.build
@@ -1,4 +1,4 @@
1eo_deps = [] 1eo_deps = [compiler_plugin]
2eo_pub_deps = [eina] 2eo_pub_deps = [eina]
3eo_ext_deps = [valgrind, dl, execinfo] 3eo_ext_deps = [valgrind, dl, execinfo]
4 4