summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohannes Bucher <johannes.bucher2@student.kit.edu>2019-10-18 14:36:16 +0200
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2019-10-18 15:13:36 +0200
commit5f28a187ad4393f4cca61b89c5a108d7de80f4d7 (patch)
tree4b87cc498d5c142f88389ec194407921a57ee7ba
parent7d3271b487626d5e24eb96990c0cd392fac94dbe (diff)
store the index of the first variadic parameter in method types
-rw-r--r--ir/ana/irmemory.c8
-rw-r--r--ir/tr/type.c13
-rw-r--r--ir/tr/type_t.h9
3 files changed, 19 insertions, 11 deletions
diff --git a/ir/ana/irmemory.c b/ir/ana/irmemory.c
index 6769b3b..3e954be 100644
--- a/ir/ana/irmemory.c
+++ b/ir/ana/irmemory.c
@@ -881,12 +881,12 @@ static pmap *mtp_map;
*
* @param tp the type to clone
*/
-static ir_type *clone_type_and_cache(ir_type *const tp, bool const is_variadic)
+static ir_type *clone_type_and_cache(ir_type *const tp, int const variadic_index)
{
ir_type *res = pmap_get(ir_type, mtp_map, tp);
if (res == NULL) {
mtp_additional_properties const props = get_method_additional_properties(tp);
- res = clone_type_method(tp, is_variadic, props | mtp_property_private);
+ res = clone_type_method(tp, variadic_index, props | mtp_property_private);
pmap_insert(mtp_map, tp, res);
}
@@ -912,7 +912,7 @@ static void update_calls_to_private(ir_node *call, void *env)
ir_type *const entity_ctp = get_entity_type(callee);
/* clear mismatches in variadicity that can happen in obscure C
* programs and break when changing to private calling convention. */
- ctp = clone_type_and_cache(ctp, is_method_variadic(entity_ctp));
+ ctp = clone_type_and_cache(ctp, get_method_variadic_index(entity_ctp));
set_Call_type(call, ctp);
DB((dbgcall, LEVEL_1,
"changed call to private method %+F using cloned type %+F\n",
@@ -938,7 +938,7 @@ void mark_private_methods(void)
DB((dbgcall, LEVEL_1, "found private method %+F\n", ent));
if ((get_method_additional_properties(mtp) & mtp_property_private) == 0) {
/* need a new type */
- mtp = clone_type_and_cache(mtp, is_method_variadic(mtp));
+ mtp = clone_type_and_cache(mtp, get_method_variadic_index(mtp));
set_entity_type(ent, mtp);
DB((dbgcall, LEVEL_2, "changed entity type of %+F to %+F\n", ent, mtp));
changed = true;
diff --git a/ir/tr/type.c b/ir/tr/type.c
index 71e9a00..581b3cc 100644
--- a/ir/tr/type.c
+++ b/ir/tr/type.c
@@ -91,7 +91,7 @@ void ir_init_type(ir_prog *irp)
void ir_finish_type(ir_prog *irp)
{
- /** nothing todo. (The code, unknown types are in the global type list
+ /** nothing to do. (The code, unknown types are in the global type list
* and freed there */
(void)irp;
}
@@ -525,7 +525,7 @@ ir_type *new_type_method(size_t const n_param, size_t const n_res, int const is_
res->attr.method.params = XMALLOCNZ(ir_type*, n_param);
res->attr.method.n_res = n_res;
res->attr.method.res_type = XMALLOCNZ(ir_type*, n_res);
- res->attr.method.variadic = is_variadic;
+ res->attr.method.variadic = is_variadic ? (int)n_param : -1;
res->attr.method.irg_calling_conv = cc_mask;
res->attr.method.properties = property_mask;
set_type_alignment(res, 1);
@@ -533,7 +533,7 @@ ir_type *new_type_method(size_t const n_param, size_t const n_res, int const is_
return res;
}
-ir_type *clone_type_method(ir_type *const tp, bool const is_variadic, mtp_additional_properties const property_mask)
+ir_type *clone_type_method(ir_type *const tp, int const variadic_index, mtp_additional_properties const property_mask)
{
assert(is_Method_type(tp));
ir_mode *mode = tp->mode;
@@ -551,7 +551,7 @@ ir_type *clone_type_method(ir_type *const tp, bool const is_variadic, mtp_additi
res->attr.method.n_res = n_res;
res->attr.method.res_type = XMALLOCN(ir_type*, n_res);
MEMCPY(res->attr.method.res_type, tp->attr.method.res_type, n_res);
- res->attr.method.variadic = is_variadic;
+ res->attr.method.variadic = variadic_index;
res->attr.method.properties = property_mask;
res->attr.method.irg_calling_conv = tp->attr.method.irg_calling_conv;
set_type_alignment(res, get_type_alignment(tp));
@@ -609,6 +609,11 @@ void set_method_res_type(ir_type *method, size_t pos, ir_type *tp)
int is_method_variadic(ir_type const *const method)
{
assert(is_Method_type(method));
+ return method->attr.method.variadic > -1;
+}
+
+int get_method_variadic_index(ir_type const *const method) {
+ assert(is_Method_type(method));
return method->attr.method.variadic;
}
diff --git a/ir/tr/type_t.h b/ir/tr/type_t.h
index 007d041..35bfb3f 100644
--- a/ir/tr/type_t.h
+++ b/ir/tr/type_t.h
@@ -66,7 +66,8 @@ typedef struct {
ir_type **params; /**< Array of parameter types. */
size_t n_res; /**< Number of results. */
ir_type **res_type; /**< Array of result types. */
- bool variadic; /**< The variadicity of the method. */
+ int variadic; /**< The variadicity of the method. -1: method is not variadic
+ Values >= 0 represent the index of the first variadic parameter. */
mtp_additional_properties properties; /**< Set of additional method properties. */
unsigned irg_calling_conv; /**< A set of calling convention flags. */
} method_attr;
@@ -153,12 +154,12 @@ void ir_finish_type(ir_prog *irp);
/** Clone an existing method type.
*
* @param tp the method type to clone.
- * @param is_variadic whether the cloned type is variadic
+ * @param variadic_index index of the first variadic parameter, -1 if method is not variadic
* @param property_mask additional method properties for the cloned type
*
* @return the cloned method type.
*/
-ir_type *clone_type_method(ir_type *tp, bool is_variadic, mtp_additional_properties property_mask);
+ir_type *clone_type_method(ir_type *tp, int variadic_index, mtp_additional_properties property_mask);
extern ir_visited_t firm_type_visited;
@@ -315,6 +316,8 @@ static inline size_t get_method_n_ress_(const ir_type *method)
return method->attr.method.n_res;
}
+int get_method_variadic_index(ir_type const *const method);
+
static inline mtp_additional_properties get_method_additional_properties_(const ir_type *method)
{
assert(is_Method_type(method));