summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2020-07-17 10:52:39 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-07-17 10:52:39 +0200
commit78c929fb325927a103d239e8181abdb0524f9dca (patch)
tree62dbfb03978f0f3ef450caf4c9ce652319074294
parente14bac52709862b111d8c8ae1fbd0f71c797d254 (diff)
downloadefl-78c929fb325927a103d239e8181abdb0524f9dca.tar.gz
wip
-rw-r--r--src/bin/eolian/sources.c72
-rw-r--r--src/compiler-plugins/myplugin.cc143
2 files changed, 142 insertions, 73 deletions
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 0837777440..f4f5185476 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -504,7 +504,7 @@ _emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const char *r
static void
_gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
Eolian_Function_Type ftype, Eina_Strbuf *buf,
- const Eolian_Implement *impl, Eina_Hash *refh)
+ const Eolian_Implement *impl, Eina_Hash *refh, Eina_Bool internal)
{
Eina_Bool is_empty = eolian_implement_is_empty(impl, ftype);
Eina_Bool is_auto = eolian_implement_is_auto(impl, ftype);
@@ -927,6 +927,51 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
if (impl_same_class && eolian_function_is_static(fid))
_emit_class_function(buf, fid, rtpn, params_full, ocnamel, func_suffix, params, eolian_function_full_c_name_get(fid, ftype));
+ if (internal && !eolian_function_is_static(fid) && !eolian_implement_is_pure_virtual(impl, ftype) && !is_empty)
+ {
+ /* T _class_name[_orig_class]_func_name_suffix */
+ eina_strbuf_append(buf, "EAPI ");
+ eina_strbuf_append(buf, rtpn);
+ if (rtpn[strlen(rtpn) - 1] != '*')
+ eina_strbuf_append_char(buf, ' ');
+ eina_strbuf_append(buf, "_NEVA_USE_ME_internal_");
+ eina_strbuf_append(buf, cnamel);
+ if (!impl_same_class)
+ eina_strbuf_append_printf(buf, "_%s", ocnamel);
+ eina_strbuf_append_char(buf, '_');
+ eina_strbuf_append(buf, eolian_function_name_get(fid));
+ eina_strbuf_append(buf, func_suffix);
+ /* ([const ]Eo *obj, Data_Type *pd, impl_full_params); */
+ eina_strbuf_append_char(buf, '(');
+ if ((ftype == EOLIAN_PROP_GET) || eolian_function_object_is_const(fid))
+ eina_strbuf_append(buf, "const ");
+ eina_strbuf_append(buf, "Eo *obj, ");
+ eina_strbuf_append(buf, eolian_class_c_data_type_get(cl));
+ eina_strbuf_append(buf, " *pd");
+ eina_strbuf_append(buf, eina_strbuf_string_get(params_full_imp));
+ if (eina_strbuf_length_get(params_full_imp) == 0 && eolian_function_is_static(fid))
+ eina_strbuf_append(buf, "void");
+ eina_strbuf_append(buf, ") {\n");
+ if (rtp)
+ eina_strbuf_append(buf, " return ");
+ else
+ eina_strbuf_append(buf, " ");
+ eina_strbuf_append(buf, "_");
+ eina_strbuf_append(buf, cnamel);
+ if (!impl_same_class)
+ eina_strbuf_append_printf(buf, "_%s", ocnamel);
+ eina_strbuf_append_char(buf, '_');
+ eina_strbuf_append(buf, eolian_function_name_get(fid));
+ eina_strbuf_append(buf, func_suffix);
+ eina_strbuf_append(buf, "(obj, pd");
+ if (eina_strbuf_length_get(params) > 0)
+ eina_strbuf_append(buf, ", ");
+ eina_strbuf_append_buffer(buf, params);
+ /* params here */
+ eina_strbuf_append(buf, ");\n");
+ eina_strbuf_append(buf, "}\n\n");
+ }
+
free(cname);
free(cnamel);
free(ocnamel);
@@ -1137,10 +1182,8 @@ _is_function_type_compatible(const Eolian_Function_Type t1, const Eolian_Functio
*
*/
static void
-_gen_next_super_implementation_registering(Eina_Array *call_chain, const Eolian_Class *impl_klass, const Eolian_Implement *impl, Eina_Strbuf *buf)
+_gen_next_super_implementation_registering(Eina_Array *call_chain, const Eolian_Class *impl_klass, const Eolian_Implement *impl, const Eolian_Function_Type ftype, const Eolian_Function *fid, Eina_Strbuf *buf)
{
- Eolian_Function_Type ftype;
- const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
const Eolian_Class *next_implemen_class = NULL;
const Eolian_Class *definition_class = eolian_function_class_get(fid);
char *impl_name;
@@ -1183,7 +1226,7 @@ _gen_next_super_implementation_registering(Eina_Array *call_chain, const Eolian_
prefix = "_set";
eina_strbuf_append_printf(buf, "COMPILER_PLUGIN_REGISTER_NEXT(\"%s\", \"%s\", ", eolian_function_full_c_name_get(fid, ftype), class_name);
- eina_strbuf_append_printf(buf, "\"_%s", impl_name);
+ eina_strbuf_append_printf(buf, "\"_NEVA_USE_ME_internal_%s", impl_name);
if (definition_class != next_implemen_class)
eina_strbuf_append_printf(buf, "_%s", defi_name);
eina_strbuf_append_printf(buf, "_%s%s\"", eolian_function_name_get(fid), prefix);
@@ -1281,18 +1324,19 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
{
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
const Eolian_Function *fid = eolian_implement_function_get(imp, &ftype);
+ Eina_Bool internal_redirection = EINA_TRUE; //eolian_function_class_get(fid) != cl;
switch (ftype)
{
case EOLIAN_PROP_GET:
case EOLIAN_PROP_SET:
- _gen_func(cl, fid, ftype, buf, imp, refh);
+ _gen_func(cl, fid, ftype, buf, imp, refh, internal_redirection);
break;
case EOLIAN_PROPERTY:
- _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, refh);
- _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, refh);
+ _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, refh, internal_redirection);
+ _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, refh, internal_redirection);
break;
default:
- _gen_func(cl, fid, EOLIAN_METHOD, buf, imp, refh);
+ _gen_func(cl, fid, EOLIAN_METHOD, buf, imp, refh, internal_redirection);
}
}
eina_iterator_free(itr);
@@ -1391,7 +1435,15 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
if (eolian_function_is_static(fid)) continue;
if (icl == cl) continue;
- _gen_next_super_implementation_registering(call_chain, cl, imp, buf);
+ if (ftype == EOLIAN_PROPERTY)
+ {
+ _gen_next_super_implementation_registering(call_chain, cl, imp, EOLIAN_PROP_SET, fid, buf);
+ _gen_next_super_implementation_registering(call_chain, cl, imp, EOLIAN_PROP_GET, fid, buf);
+ }
+ else
+ {
+ _gen_next_super_implementation_registering(call_chain, cl, imp, ftype, fid, buf);
+ }
}
eina_iterator_free(itr);
diff --git a/src/compiler-plugins/myplugin.cc b/src/compiler-plugins/myplugin.cc
index 339b23e64a..b183432f6e 100644
--- a/src/compiler-plugins/myplugin.cc
+++ b/src/compiler-plugins/myplugin.cc
@@ -35,7 +35,6 @@ static void super2_add(gimple_stmt_iterator *gsi)
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);
@@ -45,7 +44,7 @@ static void super2_add(gimple_stmt_iterator *gsi)
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,
+ cgraph_create_edge(cgraph_node::get(current_function_decl), node,
super2_func, bb->count, frequency);
}
@@ -55,13 +54,16 @@ struct Caller {
const char *klass;
tree klass_decl;
tree called_api_decl;
+ tree klass_call;
+ gimple efl_super_call;
+ gimple class_get_call;
};
typedef struct _Fetch_Result {
bool valid;
const char *api_name;
tree api;
- const_gimple first_argument;
+ gimple first_argument;
} Fetch_Result;
static Fetch_Result
@@ -105,6 +107,7 @@ static Caller fetch_efl_super_class(const_gimple stmt)
if (!first.valid) return ret;
ret.called_api = IDENTIFIER_POINTER(DECL_NAME(called_api_tree));
ret.called_api_decl = called_api_tree;
+ ret.efl_super_call = first.first_argument;
if (!!strncmp(first.api_name, "efl_super", 9)) return ret;
//copy the name we have inside efl_super
@@ -112,16 +115,53 @@ static Caller fetch_efl_super_class(const_gimple stmt)
if (!argument_efl_super.valid) return ret;
ret.klass = argument_efl_super.api_name;
ret.klass_decl = argument_efl_super.api;
+ ret.klass_call = gimple_call_arg(first.first_argument, 0);
+ ret.class_get_call = argument_efl_super.first_argument;
ret.valid = true;
return ret;
}
+struct Registered_Api{
+ bool valid;
+ tree replacement_candidate;
+ tree provider_of_replacement_candidate;
+};
+
+static Registered_Api
+fetch_replacement_api(tree klass_decl, const char* called_api)
+{
+ Registered_Api result = {false, 0, 0};
+ for (tree attribute = DECL_ATTRIBUTES(klass_decl); attribute != NULL_TREE; attribute = TREE_CHAIN(attribute))
+ {
+ tree attribute_name = TREE_PURPOSE(attribute);
+ if (!attribute_name)
+ {
+ fprintf(stderr, "Error, expected name\n");
+ continue;
+ }
+ if (!!strncmp(IDENTIFIER_POINTER(attribute_name), "register_next", strlen("register_next")))
+ continue;
+ //this here assumes a special tree_list structure
+ tree attribute_arguments = TREE_VALUE(attribute);
+ tree call = TREE_VALUE(attribute_arguments);
+ tree providing_class = TREE_VALUE(TREE_CHAIN(attribute_arguments));
+ tree implementation = TREE_VALUE(TREE_CHAIN(TREE_CHAIN(attribute_arguments)));
+ if (!!strncmp(TREE_STRING_POINTER(call), called_api, strlen(called_api))) continue;
+ result.provider_of_replacement_candidate = providing_class;
+ result.replacement_candidate = implementation;
+ result.valid = true;
+ break;
+ }
+ return result;
+}
+
static unsigned int eo_execute(void)
{
basic_block bb, entry_bb;
gimple_stmt_iterator gsi;
+ unsigned int length = 0;
//fprintf(stderr, "Function %s eval\n", get_name(cfun->decl));
@@ -131,47 +171,32 @@ static unsigned int eo_execute(void)
gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun)));
entry_bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
+ for (tree argument = DECL_ARGUMENTS(cfun->decl); argument; argument = DECL_CHAIN(argument))
+ {
+ length ++;
+ }
+ if (length < 2) return 0; //not considering functions that are invalid here
+
FOR_EACH_BB_FN(bb, cfun) {
- const_gimple stmt;
+ gimple stmt;
for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi))
{
stmt = gsi_stmt(gsi);
+
if (!stmt || !is_gimple_call(stmt)) continue;
struct Caller c = fetch_efl_super_class(stmt);
- tree replacement_candidate = NULL;
- tree provider_of_replacement_candidate = NULL;
if (!c.klass)
continue;
- for (tree attribute = DECL_ATTRIBUTES(c.klass_decl); attribute != NULL_TREE; attribute = TREE_CHAIN(attribute))
- {
- tree attribute_name = TREE_PURPOSE(attribute);
- if (!attribute_name)
- {
- fprintf(stderr, "Error, expected name\n");
- continue;
- }
- if (!!strncmp(IDENTIFIER_POINTER(attribute_name), "register_next", strlen("register_next")))
- continue;
-
- //this here assumes a special tree_list structure
- tree attribute_arguments = TREE_VALUE(attribute);
- tree call = TREE_VALUE(attribute_arguments);
- tree providing_class = TREE_VALUE(TREE_CHAIN(attribute_arguments));
- tree implementation = TREE_VALUE(TREE_CHAIN(TREE_CHAIN(attribute_arguments)));
-
- if (!!strncmp(TREE_STRING_POINTER(call), c.called_api, strlen(c.called_api))) continue;
-
- provider_of_replacement_candidate = providing_class;
- replacement_candidate = implementation;
- }
- if (!replacement_candidate) continue;
- fprintf(stderr, "Replace! %s %s\n", c.called_api, TREE_STRING_POINTER(replacement_candidate));
+ Registered_Api api = fetch_replacement_api(c.klass_decl, c.called_api);
- //Create a new call to the found replacement candidate
+ if (!api.valid) continue;
+ fprintf(stderr, "Replace! %s %s\n", c.called_api, TREE_STRING_POINTER(api.replacement_candidate));
+
+ //Create a new call to the found replacement candidate
#if 1
//FIXME we need here:
//add another argument "pd - <my_class>_pd_offset + <providing_class>_pd_offset" (TODO check if these are mixins)
@@ -183,14 +208,9 @@ static unsigned int eo_execute(void)
argument_types.create(10);
for (tree argument = DECL_ARGUMENTS(c.called_api_decl); argument; argument = TREE_CHAIN(argument), i++)
{
- if (!argument_types.space(i + 1))
- argument_types.safe_grow(i + 1);
- if (i == 0) {
- argument_types[i] = argument;
- } else {
- argument_types[i + 1] = argument;
- }
- fprintf(stderr, "COPY\n");
+ argument_types.safe_push(argument);
+ if (i == 0)
+ argument_types.safe_push(void_type_node);
}
tree pd_type = void_type_node;//the pd argument is interpreted as void pointer here.
@@ -198,49 +218,47 @@ static unsigned int eo_execute(void)
tree result = DECL_RESULT(c.called_api_decl);
if (!result)
result = void_type_node;
- fprintf(stderr, "----> %d\n", i);
- tree implementation_function_types = build_function_type_array(result, i + 1, argument_types.address());
- tree implementation_function_declaration = build_fn_decl(TREE_STRING_POINTER(replacement_candidate), implementation_function_types);
-
+ tree implementation_function_types = build_function_type_array(result, i + 1, &argument_types.address()[0]);
+ tree implementation_function_declaration = build_fn_decl(TREE_STRING_POINTER(api.replacement_candidate), implementation_function_types);
/**
* Create function call
*/
vec<tree> new_arguments;
new_arguments.create(gimple_call_num_args(stmt) + 1);
- new_arguments[0] = gimple_call_arg(stmt, 0);
- tree pd_value = new_arguments[0]; //FIXME create calls to second argument of cfun pd + and -
- new_arguments[1] = pd_value;
+ new_arguments.safe_push(DECL_ARGUMENTS(cfun->decl));
+
+ tree field1 = build_decl(UNKNOWN_LOCATION, VAR_DECL, get_identifier("efl_object_pd_offset"), integer_type_node); //FIXME wrong field
+ DECL_EXTERNAL(field1) = 1;
+ TREE_PUBLIC(field1) = 1;
+ tree field2 = build_decl(UNKNOWN_LOCATION, VAR_DECL, get_identifier("efl_loop_consumer_pd_offset"), integer_type_node); //FIXME wrong field
+ DECL_EXTERNAL(field2) = 1;
+ TREE_PUBLIC(field2) = 1;
+ tree tmp1 = build2(MINUS_EXPR, integer_type_node, DECL_CHAIN(DECL_ARGUMENTS(cfun->decl)), field1);
+ tree tmp2 = build2(PLUS_EXPR, integer_type_node, tmp1, field2);
+ new_arguments.safe_push(tmp2);
for (unsigned int i = 1; i < gimple_call_num_args(stmt); ++i)
{
- new_arguments[i + 1] = gimple_call_arg(stmt, i);
- fprintf(stderr, "COPY2\n");
+ new_arguments.safe_push(gimple_call_arg(stmt, i));
}
gcall *new_call = gimple_build_call_vec(implementation_function_declaration, new_arguments);
+
const greturn *ret = as_a <const greturn *> (stmt);
tree return_val = gimple_return_retval(ret);
gimple_return_set_retval(as_a<greturn *>(new_call), return_val);
+
gsi_replace(&gsi, new_call, true);
+
+ auto removal = gsi_for_stmt(c.efl_super_call);
+ gsi_remove(&removal, false);
+ removal = gsi_for_stmt(c.class_get_call);
+ gsi_remove(&removal, false);
#endif
}
}
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;
-}
-
static tree
handle_user_attribute (tree *node, tree name, tree args,
int flags, bool *no_add_attrs)
@@ -287,7 +305,6 @@ __visible int plugin_init(struct plugin_name_args *plugin_info,
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);
register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_next_hop_attribute, NULL);
return 0;