From b2cbbfbb63b7d62b58a9523db6121f4672396d9e Mon Sep 17 00:00:00 2001 From: Sebastian Hack Date: Tue, 14 Sep 2004 09:06:03 +0000 Subject: [PATCH] Added basic reflaction functionality for firm operators [r3858] --- ir/ir/Makefile.in | 4 +- ir/ir/irop.h | 3 +- ir/ir/irreflect.c | 367 +++++++++++++++++++++++++++++++++++ ir/ir/irreflect.def | 456 ++++++++++++++++++++++++++++++++++++++++++++ ir/ir/irreflect.h | 150 +++++++++++++++ ir/ir/irreflect_t.h | 15 ++ 6 files changed, 992 insertions(+), 3 deletions(-) create mode 100644 ir/ir/irreflect.c create mode 100644 ir/ir/irreflect.def create mode 100644 ir/ir/irreflect.h create mode 100644 ir/ir/irreflect_t.h diff --git a/ir/ir/Makefile.in b/ir/ir/Makefile.in index efbc7bd0b..049a99820 100644 --- a/ir/ir/Makefile.in +++ b/ir/ir/Makefile.in @@ -17,7 +17,7 @@ subdir := ir/ir INSTALL_HEADERS = irprog.h irgraph.h irnode.h irmode.h irop.h ircons.h \ irflag.h irvrfy.h irgwalk.h irgmod.h iropt.h irdump.h \ - irgopt.h ircgcons.h ircgopt.h + irgopt.h ircgcons.h ircgopt.h irreflect.h SOURCES = $(INSTALL_HEADERS) @@ -25,7 +25,7 @@ SOURCES += Makefile.in \ ircons.c ircons_t.h irgmod.c irgraph_t.h irnode.c iropt.c iropt_t.h irvrfy.c \ irgwalk.c irgwalk_blk.c irdump.c irdumptxt.c irgopt.c irnode_t.h \ irmode.c irop.c irprog.c irflag.c irflag_t.h irgraph.c \ - irmode_t.h irop_t.h irprog_t.h ircgcons.c ircgopt.c + irmode_t.h irop_t.h irprog_t.h ircgcons.c ircgopt.c irreflect.c include $(topdir)/MakeRules diff --git a/ir/ir/irop.h b/ir/ir/irop.h index ca73cbd87..d08e2d1c9 100644 --- a/ir/ir/irop.h +++ b/ir/ir/irop.h @@ -40,7 +40,8 @@ typedef enum { iro_Load, iro_Store, iro_Alloc, iro_Free, iro_Sync, iro_Proj, iro_Tuple, iro_Id, iro_Bad, iro_Confirm, iro_Unknown, iro_Filter, iro_Break, iro_CallBegin, iro_EndReg, iro_EndExcept, - iro_FuncCall + iro_FuncCall, + iro_MaxOpcode } opcode; typedef struct ir_op ir_op; diff --git a/ir/ir/irreflect.c b/ir/ir/irreflect.c new file mode 100644 index 000000000..0b1ce6621 --- /dev/null +++ b/ir/ir/irreflect.c @@ -0,0 +1,367 @@ +/** + * @file irreflect.c + * @date 9.9.2004 + * @author Sebastian Hack + * @brief Reflection for Firm operands. + * + * $Id$ + */ + +#include +#include +#include + +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free +#include + +#include "irmode.h" +#include "irreflect.h" + +#define obstack_grow_str(obst,s) obstack_grow((obst), (s), strlen((s))) +#define obstack_grow_str_const(obst,s) obstack_grow((obst), (s), sizeof((s))) + +extern int obstack_printf(struct obstack *obst, const char *fmt, ...); + +/** + * Get the number of bits set in a word. + */ +static inline int pop(int i) { + unsigned x = (unsigned) i; + x = ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x = x + (x >> 8); + x = x + (x >> 16); + return (int) (x & 0x3f); +} + +/** + * Get the number of bits differing in two variables. + */ +static inline int dist(int x, int y) { + return pop(x ^ y); +} + + +#define MAX_SIG_COUNT 8 +#define MAX_ARG_COUNT 10 + +typedef struct { + int num; /**< A sequential number (one opcode can have multiple signatures. */ + rflct_arg_t args[]; /**< The signature. */ +} rflct_args_t; + +typedef struct { + opcode opc; + const char *name; + bool commutative; + int sig_count; + const rflct_arg_t *sigs[MAX_SIG_COUNT]; +} rflct_opcode_t; + +static struct obstack obst; + +static const rflct_opcode_t *opcodes[iro_MaxOpcode]; + +#define OPCODES_COUNT (sizeof(opcodes) / sizeof(opcodes[0])) + +// #define MODE_IS(mode,mask) (((mode) & (mask)) != 0) + +rflct_mode_class_t rflct_get_mode_class(const ir_mode *mode) { + mode_sort sort = get_mode_sort(mode); + + switch(sort) { + case irms_auxiliary: + case irms_control_flow: + if(mode == mode_BB) + return RFLCT_MC(BB); + else if(mode == mode_X) + return RFLCT_MC(X); + case irms_memory: + return RFLCT_MC(Mem); + case irms_internal_boolean: + return RFLCT_MC(Bool); + case irms_int_number: + return mode_is_signed(mode) ? RFLCT_MC(IntS) : RFLCT_MC(IntU); + case irms_float_number: + return RFLCT_MC(Float); + case irms_reference: + return RFLCT_MC(Ref); + case irms_character: + return RFLCT_MC(Char); + } + + return RFLCT_MC(None); +} + +static inline const rflct_opcode_t *get_opcode(opcode opc) { + assert(opc >= 0 && opc < OPCODES_COUNT && "Invalid opcode"); + return opcodes[opc]; +} + +static inline const rflct_arg_t *get_args(opcode opc, int sig) { + const rflct_opcode_t *opcode = get_opcode(opc); + assert(sig >= 0 && sig < opcode->sig_count + && "Invalid signature"); + return opcode->sigs[sig]; +} + +#define GET_OPCODE(opc) get_opcode(opc) +#define GET_ARGS(opc,args) get_args(opc, args) + +int rflct_get_signature_count(opcode opc) { + const rflct_opcode_t *opcode = GET_OPCODE(opc); + return opcode->sig_count; +} + +int rflct_get_in_args_count(opcode opc, int sig) { + const rflct_arg_t *args = GET_ARGS(opc, sig); + int res = 0, i = 0; + + for(i = 0; args[i].name != NULL; i++); + for(res = 0, i += 1; args[i].name != NULL; res++, i++); + return res; +} + +int rflct_get_out_args_count(opcode opc, int sig) { + const rflct_arg_t *args = GET_ARGS(opc, sig); + int i = 0; + for(i = 0; args[i].name != NULL; i++); + return i; +} + + +const rflct_arg_t *rflct_get_in_args(opcode opc, int sig) { + const rflct_arg_t *args = GET_ARGS(opc, sig); + int i; + + for(i = 0; args[i].name != NULL; i++); + return &args[i + 1]; +} + +const rflct_arg_t *rflct_get_out_args(opcode opc, int sig) { + return GET_ARGS(opc, sig); +} + +int rflct_signature_match(ir_node *irn, int sig) { + opcode op = get_irn_opcode(irn); + const rflct_arg_t *args = rflct_get_in_args(op, sig); + int dst = 0; + int i, j; + + for(i = 0, j = -1; RFLCT_ARG_VALID(&args[i]) + && j < get_irn_arity(irn); j++) { + + ir_node *child = get_irn_n(irn, j); + const rflct_arg_t *arg = &args[i]; + rflct_mode_class_t mc = rflct_get_mode_class(get_irn_mode(child)); + + if(arg->accepted_modes & mc) + dst += dist(arg->accepted_modes, mc); + else + return INT_MAX; + + if(!arg->is_variadic) + i++; + } + + return dst; +} + +int rflct_get_signature(ir_node *irn) { + const rflct_opcode_t *opc = GET_OPCODE(get_irn_opcode(irn)); + int min_dist = INT_MAX; + int min_sig = INT_MAX; + int i; + + for(i = 0; i < opc->sig_count; i++) { + int dist = rflct_signature_match(irn, i); + if(dist < min_dist) { + min_dist = dist; + min_sig = i; + } + } + + return min_sig; +} + +static const char *rflct_mode_class_atomic_name(rflct_mode_class_t mc) { +#define XXX(_mc) case RFLCT_MC(_mc): return #_mc + switch(mc) { + XXX(None); + XXX(Mem); + XXX(Bool); + XXX(IntS); + XXX(IntU); + XXX(Float); + XXX(Ref); + XXX(Char); + XXX(X); + XXX(BB); + XXX(Int); + XXX(Intb); + XXX(Num); + XXX(NumP); + XXX(Data); + XXX(Datab); + XXX(DataM); + XXX(DataMX); + XXX(Lh); + default: + return ""; + } +#undef XXX +} + +static void rflct_mode_class_comb_name_obst(struct obstack *obst, + rflct_mode_class_t mc) { + const char *res = rflct_mode_class_atomic_name(mc); + + if(strlen(res) == 0) { + const char *prefix = ""; + int mask; + + obstack_1grow(obst, '{'); + for(mask = 1; mask != 0; mask <<= 1) { + if(mask & mc) { + const char *s = rflct_mode_class_atomic_name(mask); + obstack_grow_str(obst, s); + obstack_grow_str(obst, prefix); + prefix = "|"; + } + } + obstack_1grow(obst, '}'); + + } else + obstack_grow(obst, res, strlen(res)); +} + +char *rflct_mode_class_name(char *str, int n, rflct_mode_class_t mc) { + struct obstack obst; + const char *res; + + obstack_init(&obst); + + rflct_mode_class_comb_name_obst(&obst, mc); + obstack_1grow(&obst, 0); + res = obstack_finish(&obst); + + strncpy(str, res, n); + + obstack_free(&obst, NULL); + + return str; +} + +static void rflct_obstack_grow_args(struct obstack *obst, + const rflct_arg_t *args) { + const rflct_arg_t *arg; + const char *prefix = ""; + + for(arg = args; RFLCT_ARG_VALID(arg); arg++) { + obstack_grow_str(obst, prefix); + obstack_grow_str(obst, arg->name); + if(arg->is_variadic) + obstack_1grow(obst, '*'); + obstack_1grow(obst, ':'); + rflct_mode_class_comb_name_obst(obst, arg->accepted_modes); + prefix = ", "; + } + +} + +char *rflct_to_string(char *buf, int n, opcode opc, int sig) { + struct obstack obst; + char *s; + const rflct_opcode_t *opcode = GET_OPCODE(opc); + + obstack_init(&obst); + + obstack_1grow(&obst, '('); + rflct_obstack_grow_args(&obst, rflct_get_out_args(opc, sig)); + + obstack_grow_str(&obst, ") = "); + obstack_grow_str(&obst, opcode->name); + obstack_1grow(&obst, '('); + + rflct_obstack_grow_args(&obst, rflct_get_in_args(opc, sig)); + + obstack_1grow(&obst, ')'); + obstack_1grow(&obst, 0); + s = obstack_finish(&obst); + strncpy(buf, s, n); + obstack_free(&obst, NULL); + + return buf; +} + +#define ARG(name,modes) \ + _ARG(name, modes, false, -1) + +#define ARG_SAME(name,modes,mode_same) \ + _ARG(name, modes, false, mode_same) + +#define VARG(name,modes) \ + _ARG(name, modes, true, 0) + +#define VARG_SAME(name,modes) \ + _ARG(name, modes, true, 1) + +#define MARK \ + _ARG(NULL, None, false, -1) + +#define BLOCK ARG("Block", BB) + +static void init_ops(void) { + + int curr_sig; + rflct_opcode_t *opcode; + + obstack_init(&obst); + + +#define BEGIN_OP(op) \ + curr_sig = 0; \ + opcode = obstack_alloc(&obst, sizeof(*opcode)); \ + opcode->opc = iro_ ## op; \ + opcode->name = #op; \ + opcodes[opcode->opc] = opcode; + + +#define BEGIN_ARGS + +#define _ARG(_name,_modes,_variadic,_mode_equals) \ + { \ + rflct_arg_t args; \ + args.name = _name; \ + args.accepted_modes = RFLCT_MC(_modes); \ + args.is_variadic = _variadic; \ + args.mode_equals = _mode_equals; \ + obstack_grow(&obst, &args, sizeof(args)); \ + } + +#define END_ARGS \ + { \ + _ARG(NULL, None, false, 0) \ + assert(curr_sig < MAX_SIG_COUNT && "Mind the maximum number of signatures"); \ + opcode->sigs[curr_sig++] = obstack_finish(&obst); \ + opcode->sig_count = curr_sig; \ + } + +#define END_OP + +#include "irreflect.def" + +#undef BEGIN_ARGS +#undef END_ARGS +#undef BEGIN_OP +#undef END_OP +} + + + + +void init_rflct(void) { + init_ops(); +} diff --git a/ir/ir/irreflect.def b/ir/ir/irreflect.def new file mode 100644 index 000000000..dab4d1ffb --- /dev/null +++ b/ir/ir/irreflect.def @@ -0,0 +1,456 @@ + +BEGIN_OP(Block) + BEGIN_ARGS + ARG("Block", BB) + MARK + ARG("predecessors", X) + END_ARGS +END_OP + +BEGIN_OP(Start) + BEGIN_ARGS + ARG("Execution", X) + ARG("Memory", Mem) + ARG("Stack", Ref) + ARG("Global", Ref) + VARG("Arguments", Data) + ARG("Call By Value", Ref) + MARK + BLOCK + END_ARGS +END_OP + +BEGIN_OP(End) + BEGIN_ARGS + MARK + BLOCK + VARG("Memory & Preds", Lh) + END_ARGS +END_OP + +/* + * EndReg + */ + +/* + * EndExcept + */ + +/* + * Jmp + */ + +BEGIN_OP(Jmp) + BEGIN_ARGS + ARG("Target", X) + MARK + BLOCK + END_ARGS +END_OP + +BEGIN_OP(Break) + BEGIN_ARGS + ARG("Target", X) + MARK + BLOCK + END_ARGS +END_ARGS + +BEGIN_OP(Cond) + BEGIN_ARGS + ARG("False Branch", X) + ARG("True Branch", X) + MARK + BLOCK + ARG("Condition", Bool) + END_ARGS + + BEGIN_ARGS + VARG("Cases", X) + MARK + BLOCK + ARG("Switch", Int) + END_ARGS +END_OP + +BEGIN_OP(Return) + BEGIN_ARGS + ARG("CF", X) + MARK + BLOCK + ARG("Memory", Mem) + VARG("Args", Data) + END_ARGS +END_OP + +BEGIN_OP(CallBegin) + BEGIN_ARGS + VARG("CF", X) + MARK + BLOCK + ARG("Addr", Ref) + END_ARGS +END_OP + +BEGIN_OP(Const) + BEGIN_ARGS + ARG("Value", Data) + MARK + BLOCK + END_ARGS +END_OP + +BEGIN_OP(SymConst) + BEGIN_ARGS + ARG("Value", Int) + MARK + BLOCK + END_ARGS + + BEGIN_ARGS + ARG("Value", Ref) + MARK + BLOCK + END_ARGS +END_OP + +BEGIN_OP(Unknown) + BEGIN_ARGS + ARG("Value", Any) + MARK + BLOCK + END_ARGS +END_OP + +BEGIN_OP(Sel) + BEGIN_ARGS + ARG("Addr", Ref) + MARK + BLOCK + ARG("Memory", Mem) + ARG("Base", Ref) + VARG_SAME("Indices", Int) + END_ARGS +END_OP + +BEGIN_OP(Call) + BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + VARG("Results", Data) + ARG("Exception Memory", Mem) + ARG("Stack", Ref) + MARK + BLOCK + ARG("Memory", Mem) + ARG("Addr", Ref) + VARG("Parameters", Data) + END_ARGS +END_OP + +BEGIN_OP(Add) + BEGIN_ARGS + ARG("Result", NumP) + MARK + BLOCK + ARG_SAME("Op 1", NumP, 0) + ARG_SAME("Op 2", NumP, 0) + END_ARGS + + BEGIN_ARGS + ARG("Result", Ref) + MARK + BLOCK + ARG("Op 1", Ref) + ARG("Op 2", Num) + END_ARGS + + BEGIN_ARGS + ARG("Result", Ref) + MARK + BLOCK + ARG("Op 1", Num) + ARG("Op 2", Ref) + END_ARGS +END_OP + +BEGIN_OP(Sub) + BEGIN_ARGS + ARG("Result", NumP) + MARK + BLOCK + ARG_SAME("Op 1", NumP, 0) + ARG_SAME("Op 2", NumP, 0) + END_ARGS + + BEGIN_ARGS + ARG("Result", Ref) + MARK + BLOCK + ARG("Op 1", NumP) + ARG("Op 2", Ref) + END_ARGS + + BEGIN_ARGS + ARG("Result", Ref) + MARK + BLOCK + ARG("Op 1", Ref) + ARG("Op 2", NumP) + END_ARGS + + BEGIN_ARGS + ARG("Result", Num) + MARK + BLOCK + ARG("Op 1", Ref) + ARG("Op 2", Ref) + END_ARGS +END_OP + +BEGIN_OP(Minus) + BEGIN_ARGS + ARG("Result", Float) + MARK + BLOCK + ARG_SAME("Op 0", Float, 0) + END_ARGS +END_OP + +BEGIN_OP(Mul) + BEGIN_ARGS + ARG("Result", Int) + MARK + BLOCK + ARG("Op 0", Int) + ARG_SAME("Op 1", Int, 3) + END_ARGS + + BEGIN_ARGS + ARG("Result", Float) + MARK + BLOCK + ARG_SAME("Op 0", Float, 0) + ARG_SAME("Op 1", Float, 0) + END_ARGS +END_OP + +BEGIN_OP(Quot) + BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + ARG("Op 0", Float) + MARK + BLOCK + ARG("Memory", Mem) + ARG_SAME("Op 0", Float, 2) + ARG_SAME("Op 1", Float, 2) + END_ARGS +END_OP + +BEGIN_OP(DivMod) + BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + ARG("Res 0", Int) + ARG_SAME("Res 1", Int, 2) + MARK + BLOCK + ARG("Memory", Mem) + ARG_SAME("Op 0", Int, 2) + ARG_SAME("Op 1", Int, 2) + END_ARGS +END_OP + +BEGIN_OP(Div) +BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + ARG("Result", Int) + MARK + BLOCK + ARG("Memory", Mem) + ARG_SAME("Op 0", Int, 2) + ARG_SAME("Op 1", Int, 2) +END_ARGS +END_OP + +BEGIN_OP(Abs) +BEGIN_ARGS + ARG("Res", Num) + MARK + BLOCK + ARG_SAME("Op", Num, 0) +END_ARGS +END_OP + +BEGIN_OP(And) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG_SAME("Op 1", Int, 0) +END_ARGS +END_OP + +BEGIN_OP(Or) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG_SAME("Op 1", Int, 0) +END_ARGS +END_OP + +BEGIN_OP(Eor) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG_SAME("Op 1", Int, 0) +END_ARGS +END_OP + +BEGIN_OP(Not) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op", Int, 0) +END_ARGS +END_OP + +BEGIN_OP(Shl) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG("Op 1", IntU) +END_ARGS +END_OP + +BEGIN_OP(Shr) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG("Op 1", IntU) +END_ARGS +END_OP + +BEGIN_OP(Shrs) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG("Op 1", IntU) +END_ARGS +END_OP + +BEGIN_OP(Rot) +BEGIN_ARGS + ARG("Res", Int) + MARK + BLOCK + ARG_SAME("Op 0", Int, 0) + ARG("Op 1", Int) +END_ARGS +END_OP + +BEGIN_OP(Cmp) +BEGIN_ARGS + VARG("Res", Bool) + MARK + BLOCK + ARG("Op 0", Datab) + ARG_SAME("Op 1", Datab, 3) +END_ARGS +END_OP + +BEGIN_OP(Conv) +BEGIN_ARGS + VARG("Res", Datab) + MARK + BLOCK + ARG("Op 0", Datab) +END_ARGS +END_OP + +BEGIN_OP(Phi) +BEGIN_ARGS + ARG_SAME("Res", DataM, 3) + MARK + BLOCK + VARG("Op 0", DataM) +END_ARGS +END_OP + +BEGIN_OP(Filter) +BEGIN_ARGS + ARG_SAME("Res", DataM, 3) + MARK + BLOCK + VARG("Op 0", DataM) +END_ARGS +END_OP + +BEGIN_OP(Load) +BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + ARG("Data", Data) + MARK + BLOCK + ARG("Memory", Mem) + ARG("Addr", Ref) +END_ARGS +END_OP + +BEGIN_OP(Store) +BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + MARK + BLOCK + ARG("Memory", Mem) + ARG("Addr", Ref) + ARG("Data", Data) +END_ARGS +END_OP + +BEGIN_OP(Alloc) +BEGIN_ARGS + ARG("Memory", Mem) + ARG("CF", X) + ARG("Addr", Ref) + MARK + BLOCK + ARG("Memory", Mem) + ARG("Size", IntU) +END_ARGS +END_OP + +BEGIN_OP(Free) +BEGIN_ARGS + ARG("Memory", Mem) + MARK + BLOCK + ARG("Memory", Mem) + ARG("Addr", Ref) +END_ARGS +END_OP + +BEGIN_OP(Sync) +BEGIN_ARGS + ARG("Memory", Mem) + MARK + BLOCK + VARG_SAME("Memory", Mem) +END_ARGS +END_OP diff --git a/ir/ir/irreflect.h b/ir/ir/irreflect.h new file mode 100644 index 000000000..f8cf44b22 --- /dev/null +++ b/ir/ir/irreflect.h @@ -0,0 +1,150 @@ +/** + * @file reflect.h + * @date 9.9.2004 + * @author Sebastian Hack + * @brief Reflection for Firm operations. + * + * $Id$ + */ + +#ifndef __REFLECT_H +#define __REFLECT_H + +#include +#include + +#include "irop.h" +#include "irnode.h" + +#define RFLCT_MC(m) rflct_ms_ ## m +typedef enum { + RFLCT_MC(None) = 0, + RFLCT_MC(Mem) = 2, + RFLCT_MC(Bool) = 4, + RFLCT_MC(IntS) = 8, + RFLCT_MC(IntU) = 16, + RFLCT_MC(Float) = 32, + RFLCT_MC(Ref) = 64, + RFLCT_MC(Char) = 128, + RFLCT_MC(X) = 256, + RFLCT_MC(BB) = 512, + RFLCT_MC(Cf) = RFLCT_MC(X) | RFLCT_MC(BB), + + RFLCT_MC(Int) = RFLCT_MC(IntS) | RFLCT_MC(IntU), + RFLCT_MC(Intb) = RFLCT_MC(Int) | RFLCT_MC(Bool), + RFLCT_MC(Num) = RFLCT_MC(Int) | RFLCT_MC(Float), + RFLCT_MC(NumP) = RFLCT_MC(Num) | RFLCT_MC(Ref), + RFLCT_MC(Data) = RFLCT_MC(NumP) | RFLCT_MC(Char), + RFLCT_MC(Datab) = RFLCT_MC(Data) | RFLCT_MC(Bool), + RFLCT_MC(DataM) = RFLCT_MC(Data) | RFLCT_MC(Mem), + RFLCT_MC(DataMX) = RFLCT_MC(Data) | RFLCT_MC(Mem) | RFLCT_MC(X), + RFLCT_MC(Lh) = RFLCT_MC(Mem) | RFLCT_MC(BB), + + RFLCT_MC(Any) = -1 + +} rflct_mode_class_t; + +typedef struct { + const char *name; /**< The name of the argument (just a description). */ + + bool is_variadic; /**< True, if this argument can have multiple parameters. */ + rflct_mode_class_t accepted_modes; /**< The set of accepted modes. */ + + int mode_equals; /**< If not variadic: You can specify the index of + another argument meaning, that the mode of the + operand binding at this argument must be the same + as the mode of the operand binding to the argument + at index. If you don't want to express such a + dependency, just give -1 here. + + If variadic: If true, the modes of all + variadic operands binding to this argument + must be the same. If false, they can differ. */ +} rflct_arg_t; + +typedef unsigned int rflct_mode_set_t; + +#define rflct_modeset_contains(mode_set,modecode) \ + (((mode_set) & (1 << modecode)) != 0) + +#define rflct_modeset_issubset(s1,s2) \ + (((s1) & (s2)) == (s1)) + +#define rflct_modeset_union(s1,s2) \ + ((s1) | (s2)) + +#define rflct_modeset_intersect(s1,s2) \ + ((s1) & (s2)) + +#define rflct_modeset_diff(s1,s2) \ + ((s1) & ~(s2)) + +#define RFLCT_ARG_VALID(arg) ((arg)->name != NULL) + +/** + * Get the mode class for an IR mode. + * @param mode An IR mode. + * @return The corresponding smallest reflection mode class. + */ +rflct_mode_class_t rflct_get_mode_class(const ir_mode *mode); + +/** + * Get the number of signatures for a Firm opcode. + * @param opc The opcode. + * @return The number of signatures for this opcode. + */ +int rflct_get_signature_count(opcode opc); + +/** + * Try to get the signature, that matches to a given instance + * of a Firm node. + * @param irn The node. + * @return The first matching signature or -1, if no signature matches. + */ +int rflct_get_signature(ir_node *irn); + +/** + * Get the number of in arguments. + * An in argument is a use of a value. + * @param opc The opcode. + * @param sig The signature you are refering to. + * @return The number of arguments. + */ +int rflct_get_in_args_count(opcode opc, int sig); + +/** + * Get the number of out arguments. + * An out argument is a def of a value. + * @param opc The opcode. + * @param sig The signature you are refering to. + * @return The number of arguments. + */ +int rflct_get_out_args_count(opcode opc, int sig); + +/** + * Get the array of use args. + * The array is terminated with an entry for which + * RFLCT_ARG_VALID is 0. + * @param opc The opcode. + * @param sig The signature you are referring to (Must be between + * 0 and the signature count). + * @return The array. + */ +const rflct_arg_t *rflct_get_in_args(opcode opc, int sig); + +/** + * Get the array of def args. + * The array is terminated with an entry for which + * RFLCT_ARG_VALID is 0. + * @param opc The opcode. + * @param sig The signature you are referring to (Must be between + * 0 and the signature count). + * @return The array. + */ +const rflct_arg_t *rflct_get_out_args(opcode opc, int sig); + +char *rflct_to_string(char *buf, int n, opcode opc, int sig); + +char *rflct_mode_class_name(char *str, int n, rflct_mode_class_t mc); + +#endif diff --git a/ir/ir/irreflect_t.h b/ir/ir/irreflect_t.h new file mode 100644 index 000000000..76aba3c51 --- /dev/null +++ b/ir/ir/irreflect_t.h @@ -0,0 +1,15 @@ +/** + * @file reflect_t.h + * @date 10.9.2004 + * @author Sebastian Hack + * @brief Basic (private) data structures for reflection. + * + * $Id$ + */ + +#ifndef __REFLECT_T_H +#define __REFLECT_T_H + +void init_rflct(void); + +#endif -- 2.20.1