forked from enlightenment/efl
ler-plugin: initial gcc plugin harness to be used in our build
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.
This commit is contained in:
parent
7ea924a991
commit
9bcd901ae5
|
@ -248,6 +248,11 @@ if get_option('tslib') == true
|
|||
config_h.set('HAVE_TSLIB', '1')
|
||||
endif
|
||||
|
||||
#if get_option('compiler-plugins') == true
|
||||
#gcc_plugin = dependency('gcc-plugin')
|
||||
subdir(join_paths('src', 'compiler-plugins'))
|
||||
#endif
|
||||
|
||||
subdir('header_checks')
|
||||
subdir('po')
|
||||
|
||||
|
@ -313,7 +318,7 @@ subprojects = [
|
|||
['evil' ,[] , false, true, false, false, false, false, true, [], []],
|
||||
['eina' ,[] , false, true, true, true, true, true, true, [], []],
|
||||
['eolian' ,[] , false, true, true, false, true, false, false, ['eina'], []],
|
||||
['eo' ,[] , false, true, false, true, true, false, true, ['eina'], []],
|
||||
['eo' ,[] , false, true, false, true, true, false, true, ['eina', 'compiler_plugin'], []],
|
||||
['efl' ,[] , false, true, false, false, true, false, true, ['eo'], []],
|
||||
['emile' ,[] , false, true, false, false, true, true, true, ['eina', 'efl'], ['lz4', 'rg_etc']],
|
||||
['eet' ,[] , false, true, true, false, true, true, true, ['eina', 'emile', 'efl'], []],
|
||||
|
@ -420,6 +425,8 @@ foreach package : subprojects
|
|||
'-DNEED_RUN_IN_TREE=1',
|
||||
'-DEFL_BUILD=1',
|
||||
]
|
||||
# '-fdump-passes',
|
||||
#'-fdump-tree-gimple',
|
||||
if (package[3])
|
||||
subdir(join_paths(local_lib, package_name))
|
||||
set_variable(package_name + '_eo_files', pub_eo_files)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
cc = meson.get_compiler('c')
|
||||
plugin_dev_path_result = run_command(cc.cmd_array(), '-print-file-name=plugin')
|
||||
plugin_dev_path = plugin_dev_path_result.stdout().strip()
|
||||
plugin_inc = include_directories([join_paths(plugin_dev_path, 'include')])
|
||||
|
||||
myplugin = shared_module('myplugin',
|
||||
'myplugin.cc',
|
||||
cpp_args: [ '-fno-rtti' ],
|
||||
include_directories: plugin_inc
|
||||
)
|
||||
|
||||
myplugin_dep = custom_target('myplugin',
|
||||
input: myplugin,
|
||||
output: 'myplugin_dep.h',
|
||||
command: ['echo'],
|
||||
capture: true
|
||||
)
|
||||
|
||||
compiler_plugin = declare_dependency()
|
||||
|
||||
test_1 = executable('test-1', 'test-1.c', myplugin_dep,
|
||||
c_args: [ '-fdump-passes', '-fplugin=' + myplugin.full_path() ],
|
||||
native: true,
|
||||
)
|
||||
test('test_1', test_1)
|
|
@ -0,0 +1,104 @@
|
|||
#include <stdio.h>
|
||||
#include "gcc-common.h"
|
||||
|
||||
/* TODO:
|
||||
* Find all efl_super calls
|
||||
* Traverse back to find function calling it (foo)
|
||||
* Calculate the private data pointer diff
|
||||
* Replace foo(efl_super(obj, MY_CLASS),...) calls with the next lower level function for foo and
|
||||
* adjust private data with diff
|
||||
* Make eolian more expressive (We need the implemented methods of classes, accross the tree)
|
||||
*/
|
||||
|
||||
__visible int plugin_is_GPL_compatible;
|
||||
|
||||
static const char super2_function[] = "efl_super2";
|
||||
static GTY(()) tree super2_function_decl;
|
||||
|
||||
static void super2_add(gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt;
|
||||
gcall *super2_func;
|
||||
cgraph_node_ptr node;
|
||||
int frequency;
|
||||
basic_block bb;
|
||||
|
||||
stmt = gimple_build_call(super2_function_decl, 0);
|
||||
super2_func = as_a_gcall(stmt);
|
||||
gsi_insert_after(gsi, super2_func, GSI_CONTINUE_LINKING);
|
||||
|
||||
/* Update the cgraph */
|
||||
bb = gimple_bb(super2_func);
|
||||
node = cgraph_get_create_node(super2_function_decl);
|
||||
gcc_assert(node);
|
||||
frequency = compute_call_stmt_bb_frequency(current_function_decl, bb);
|
||||
cgraph_create_edge(cgraph_get_node(current_function_decl), node,
|
||||
super2_func, bb->count, frequency);
|
||||
}
|
||||
|
||||
static unsigned int eo_execute(void)
|
||||
{
|
||||
basic_block bb, entry_bb;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
//fprintf(stderr, "Function %s called\n", get_name(cfun->decl));
|
||||
|
||||
gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
|
||||
entry_bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
|
||||
|
||||
FOR_EACH_BB_FN(bb, cfun) {
|
||||
const_gimple stmt;
|
||||
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
|
||||
{
|
||||
stmt = gsi_stmt(gsi);
|
||||
if (is_gimple_call(stmt)){
|
||||
tree current_fn_decl = gimple_call_fndecl(stmt);
|
||||
if (!current_fn_decl)
|
||||
continue;
|
||||
const char* name = IDENTIFIER_POINTER(DECL_NAME(current_fn_decl));
|
||||
if (!strncmp(name, "efl_super", 9)) {
|
||||
fprintf(stderr, "Found function %s\n", name);
|
||||
super2_add(&gsi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void super2_start_unit(void *gcc_data __unused,
|
||||
void *user_data __unused)
|
||||
{
|
||||
/* void efl_super2(void) */
|
||||
tree fntype = build_function_type_list(void_type_node, NULL_TREE);
|
||||
super2_function_decl = build_fn_decl(super2_function, fntype);
|
||||
DECL_ASSEMBLER_NAME(super2_function_decl); /* for LTO */
|
||||
TREE_PUBLIC(super2_function_decl) = 1;
|
||||
TREE_USED(super2_function_decl) = 1;
|
||||
DECL_EXTERNAL(super2_function_decl) = 1;
|
||||
DECL_ARTIFICIAL(super2_function_decl) = 1;
|
||||
DECL_PRESERVE_P(super2_function_decl) = 1;
|
||||
}
|
||||
|
||||
#define PASS_NAME eo
|
||||
#define NO_GATE
|
||||
#include "gcc-generate-gimple-pass.h"
|
||||
|
||||
__visible int plugin_init(struct plugin_name_args *plugin_info,
|
||||
struct plugin_gcc_version *version)
|
||||
{
|
||||
const char *plugin_name = plugin_info->base_name;
|
||||
|
||||
if (!plugin_default_version_check (version, &gcc_version))
|
||||
return 1;
|
||||
|
||||
PASS_INFO(eo, "cfg", 1, PASS_POS_INSERT_AFTER);
|
||||
|
||||
/* Register to be called before processing a translation unit */
|
||||
register_callback(plugin_name, PLUGIN_START_UNIT,
|
||||
&super2_start_unit, NULL);
|
||||
|
||||
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &eo_pass_info);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
void efl_super2(void){}
|
||||
|
||||
int efl_super(void) {
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
efl_super();
|
||||
return 0;
|
||||
}
|
|
@ -1458,6 +1458,7 @@ EAPI Eo * _efl_add_end(Eo *obj, Eina_Bool is_ref, Eina_Bool is_fallback);
|
|||
* @see efl_cast
|
||||
*/
|
||||
EAPI Eo *efl_super(const Eo *obj, const Efl_Class *cur_klass);
|
||||
EAPI void efl_super2(void);
|
||||
|
||||
/**
|
||||
* @brief Prepare a call to cast to a parent class implementation of a function.
|
||||
|
|
|
@ -529,6 +529,10 @@ efl_super(const Eo *eo_id, const Efl_Class *cur_klass)
|
|||
{
|
||||
return _efl_super_cast(eo_id, cur_klass, EINA_TRUE);
|
||||
}
|
||||
EAPI void
|
||||
efl_super2(void)
|
||||
{
|
||||
}
|
||||
|
||||
EAPI Eo *
|
||||
efl_cast(const Eo *eo_id, const Efl_Class *cur_klass)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
eo_deps = []
|
||||
eo_deps = [compiler_plugin]
|
||||
eo_pub_deps = [eina]
|
||||
eo_ext_deps = [valgrind, dl, execinfo]
|
||||
|
||||
|
|
Loading…
Reference in New Issue