From c433f42a558477b4a4b5043ce88c824dd4eec2cc Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Thu, 18 Dec 2008 15:31:11 +0000 Subject: [PATCH] - implemented Builtin node to represent builtins ... [r24785] --- include/libfirm/firm_types.h | 9 ++- include/libfirm/ircons.h | 105 ++++++++++++++++++++++++++++++---- include/libfirm/irnode.h | 31 +++++++++- include/libfirm/irop.h | 3 +- ir/be/arm/arm_transform.c | 16 ++---- ir/be/ia32/ia32_transform.c | 10 ++-- ir/be/ppc32/ppc32_transform.c | 16 ++---- ir/ir/ircons.c | 54 ++++++++++++++++- ir/ir/irdump.c | 3 + ir/ir/irnode.c | 94 +++++++++++++++++++++++++----- ir/ir/irnode_t.h | 7 +++ ir/ir/irop.c | 2 + ir/ir/irtypes.h | 10 +++- 13 files changed, 301 insertions(+), 59 deletions(-) diff --git a/include/libfirm/firm_types.h b/include/libfirm/firm_types.h index 90736a77d..2d0da6745 100644 --- a/include/libfirm/firm_types.h +++ b/include/libfirm/firm_types.h @@ -210,11 +210,18 @@ typedef enum { heap_alloc /**< Alloc allocates the object on the heap. */ } ir_where_alloc; -/** A input/output constraint attribute */ +/** A input/output constraint attribute. */ typedef struct { unsigned pos; /**< The inputs/output position for this constraint. */ ident *constraint; /**< The constraint for this input/output. */ ir_mode *mode; /**< The mode of the constraint. */ } ir_asm_constraint; +/** Supported libFirm builtins. */ +typedef enum { + ir_bk_return_address, /**< GCC __builtin_return_address() */ + ir_bk_frame_addess, /**< GCC __builtin_frame_address() */ + ir_bk_prefetch, /**< GCC __builtin_prefetch() */ +} ir_builtin_kind; + #endif diff --git a/include/libfirm/ircons.h b/include/libfirm/ircons.h index 00aa8a018..ac1dd2b05 100644 --- a/include/libfirm/ircons.h +++ b/include/libfirm/ircons.h @@ -271,7 +271,9 @@ * ir_node *new_Sel (ir_node *store, ir_node *objptr, int arity, * ir_node **in, ir_entity *ent); * ir_node *new_Call (ir_node *store, ir_node *callee, int arity, - * ir_node **in, type_method *type); + * ir_node **in, type_method *type); + * ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, + * ir_node **in, type_method *type); * ir_node *new_Add (ir_node *op1, ir_node *op2, ir_mode *mode); * ir_node *new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode); * ir_node *new_Minus (ir_node *op, ir_mode *mode); @@ -658,8 +660,30 @@ * A tuple containing the eventually changed store and the procedure * results. * Attributes: - * attr.call Contains the type information for the procedure. + * attr.call Contains the attributes for the procedure. * + * ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, ir_node **in, + * ----------------------------------------------------------------------------------- + * type_method *type) + * ------------------ + * + * Creates a builtin call. + * + * Parameters + * *store The actual store. + * kind Describes the called builtin. + * arity The number of procedure parameters. + * **in An array with the pointers to the parameters. + * The constructor copies this array. + * *type Type information of the procedure called. + * + * Inputs: + * The store, the kind and the parameters. + * Output: + * A tuple containing the eventually changed store and the procedure + * results. + * Attributes: + * attr.builtin Contains the attributes for the called builtin. * * ir_node *new_Add (ir_node *op1, ir_node *op2, ir_mode *mode) * ------------------------------------------------------------ @@ -1422,7 +1446,7 @@ ir_node *new_rd_Sel (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *st /** Constructor for a Call node. * - * Represents all kinds of method and function calls. + * Represents all kinds of method and function calls. * * @param *db A pointer for debug information. * @param *irg The IR graph the node belongs to. @@ -1436,6 +1460,22 @@ ir_node *new_rd_Sel (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *st ir_node *new_rd_Call (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store, ir_node *callee, int arity, ir_node *in[], ir_type *tp); +/** Constructor for a ´Builtin node. + * + * Represents a call of a backend-specific builtin.. + * + * @param *db A pointer for debug information. + * @param *irg The IR graph the node belongs to. + * @param *block The IR block the node belongs to. + * @param *store The current memory state. + * @param kind The kind of the called builtin. + * @param arity The number of procedure parameters. + * @param *in[] An array with the procedure parameters. The constructor copies this array. + * @param *tp Type information of the procedure called. + */ +ir_node *new_rd_Builtin(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store, + ir_builtin_kind kind, int arity, ir_node *in[], ir_type *tp); + /** Constructor for a Add node. * * @param *db A pointer for debug information. @@ -2250,7 +2290,7 @@ ir_node *new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, /** Constructor for a Call node. * - * Represents all kinds of method and function calls. + * Represents all kinds of method and function calls. * * @param *irg The IR graph the node belongs to. * @param *block The IR block the node belongs to. @@ -2261,8 +2301,22 @@ ir_node *new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, * @param *tp Type information of the procedure called. */ ir_node *new_r_Call (ir_graph *irg, ir_node *block, ir_node *store, - ir_node *callee, int arity, ir_node *in[], - ir_type *tp); + ir_node *callee, int arity, ir_node *in[], ir_type *tp); + +/** Constructor for a Builtin node. + * + * Represents a call of a backend-specific builtin.. + * + * @param *irg The IR graph the node belongs to. + * @param *block The IR block the node belongs to. + * @param *store The actual store. + * @param kind The kind of the called builtin. + * @param arity The number of procedure parameters. + * @param *in[] An array with the pointers to the parameters. The constructor copies this array. + * @param *tp Type information of the procedure called. + */ +ir_node *new_r_Builtin(ir_graph *irg, ir_node *block, ir_node *store, + ir_builtin_kind kind, int arity, ir_node *in[], ir_type *tp); /** Constructor for a Add node. * @@ -3073,8 +3127,8 @@ ir_node *new_d_Sel (dbg_info *db, ir_node *store, ir_node *objptr, int arity, /** Constructor for a Call node. * - * Represents all kinds of method and function calls. - * Adds the node to the block in current_ir_block. + * Represents all kinds of method and function calls. + * Adds the node to the block in current_ir_block. * * @param *db A pointer for debug information. * @param *store The actual store. @@ -3084,7 +3138,22 @@ ir_node *new_d_Sel (dbg_info *db, ir_node *store, ir_node *objptr, int arity, * @param *tp Type information of the procedure called. */ ir_node *new_d_Call (dbg_info *db, ir_node *store, ir_node *callee, int arity, ir_node *in[], - ir_type *tp); + ir_type *tp); + +/** Constructor for a Builtin node. + * + * Represents a call of a backend-specific builtin.. + * Adds the node to the block in current_ir_block. + * + * @param *db A pointer for debug information. + * @param *store The actual store. + * @param kind The kind of the called builtin. + * @param arity The number of procedure parameters. + * @param *in[] An array with the pointers to the parameters. The constructor copies this array. + * @param *tp Type information of the procedure called. + */ +ir_node *new_d_Builtin(dbg_info *db, ir_node *store, ir_builtin_kind kind, int arity, ir_node *in[], + ir_type *tp); /** Constructor for a Add node. * @@ -3884,8 +3953,8 @@ ir_node *new_Sel (ir_node *store, ir_node *objptr, int arity, ir_node *in[], /** Constructor for a Call node. * - * Adds the node to the block in current_ir_block. - * Represents all kinds of method and function calls. + * Adds the node to the block in current_ir_block. + * Represents all kinds of method and function calls. * * @param *store The actual store. * @param *callee A pointer to the called procedure. @@ -3896,6 +3965,20 @@ ir_node *new_Sel (ir_node *store, ir_node *objptr, int arity, ir_node *in[], ir_node *new_Call (ir_node *store, ir_node *callee, int arity, ir_node *in[], ir_type *tp); +/** Constructor for a Builtin node. + * + * Represents a call of a backend-specific builtin.. + * Represents all kinds of method and function calls. + * + * @param *store The actual store. + * @param kind The kind of the called builtin. + * @param arity The number of procedure parameters. + * @param *in[] An array with the pointers to the parameters. The constructor copies this array. + * @param *tp Type information of the procedure called. + */ +ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, ir_node *in[], + ir_type *tp); + /** Constructor for a CallBegin node. * * CallBegin represents control flow depending of the pointer value diff --git a/include/libfirm/irnode.h b/include/libfirm/irnode.h index c24d7775e..14cbdc48b 100644 --- a/include/libfirm/irnode.h +++ b/include/libfirm/irnode.h @@ -620,8 +620,6 @@ void set_Call_param(ir_node *node, int pos, ir_node *param); ir_type *get_Call_type(ir_node *node); /** Sets the type of a call. */ void set_Call_type(ir_node *node, ir_type *tp); -/** Gets the arity of a call. Identical to get_Call_n_params(). */ -int get_Call_arity(const ir_node *node); /** * Returns non-zero if a Call is surely a self-recursive Call. @@ -656,6 +654,33 @@ ir_entity *get_Call_callee(const ir_node *node, int pos); void set_Call_callee_arr(ir_node *node, const int n, ir_entity **arr); void remove_Call_callee_arr(ir_node *node); +/** + * Projection numbers for result of Builtin node: use for Proj nodes! + */ +typedef enum { + pn_Builtin_M = pn_Generic_M_regular, /**< The memory result. */ + pn_Builtin_T_result = pn_Generic_other, /**< The tuple containing all (0, 1, 2, ...) results. */ + pn_Builtin_max /**< number of projections from a Builtin */ +} pn_Builtin; /* Projection numbers for Builtin. */ + +ir_node *get_Builtin_mem(const ir_node *node); +void set_Builtin_mem(ir_node *node, ir_node *mem); +ir_builtin_kind get_Builtin_kind(const ir_node *node); +void set_Builtin_kind(ir_node *node, ir_builtin_kind kind); +ir_node **get_Builtin_param_arr(ir_node *node); +/** Gets the number of parameters of a Builtin. */ +int get_Builtin_n_params(const ir_node *node); +/** Gets the Builtin parameter at position pos. */ +ir_node *get_Builtin_param(const ir_node *node, int pos); +/** Sets the Builtin parameter at position pos. */ +void set_Builtin_param(ir_node *node, int pos, ir_node *param); +/** Gets the type of a builtin. */ +ir_type *get_Builtin_type(ir_node *node); +/** Sets the type of a Builtin. */ +void set_Builtin_type(ir_node *node, ir_type *tp); +/** Returns a human readable string for the ir_builtin_kind. */ +const char *get_builtin_kind_name(ir_builtin_kind kind); + ir_node *get_CallBegin_ptr(const ir_node *node); void set_CallBegin_ptr(ir_node *node, ir_node *ptr); ir_node *get_CallBegin_call(const ir_node *node); @@ -1237,6 +1262,8 @@ int is_Unknown(const ir_node *node); int is_Return(const ir_node *node); /** Returns true if node is a Call node. */ int is_Call(const ir_node *node); +/** Returns true if node is a Builtin node. */ +int is_Builtin(const ir_node *node); /** Returns true if node is a CallBegin node. */ int is_CallBegin(const ir_node *node); /** Returns true if node is a Sel node. */ diff --git a/include/libfirm/irop.h b/include/libfirm/irop.h index 0cca89581..9920c8172 100644 --- a/include/libfirm/irop.h +++ b/include/libfirm/irop.h @@ -95,7 +95,7 @@ typedef enum { iro_NoMem, iro_Mux, iro_Min, iro_Max, iro_CopyB, iro_InstOf, iro_Raise, iro_Bound, iro_Pin, - iro_ASM, + iro_ASM, iro_Builtin, iro_Anchor, /* first not middleend node number */ iro_Last = iro_Anchor, @@ -197,6 +197,7 @@ extern ir_op *op_Bound; ir_op *get_op_Bound (void); extern ir_op *op_Pin; ir_op *get_op_Pin (void); extern ir_op *op_ASM; ir_op *get_op_ASM (void); +extern ir_op *op_Builtin; ir_op *get_op_Builtin (void); extern ir_op *op_Anchor; ir_op *get_op_Anchor (void); diff --git a/ir/be/arm/arm_transform.c b/ir/be/arm/arm_transform.c index 1d7ca7f5a..771943ebe 100644 --- a/ir/be/arm/arm_transform.c +++ b/ir/be/arm/arm_transform.c @@ -1601,8 +1601,6 @@ static inline void set_transformer(ir_op *op, be_transform_func arm_transform_fu * Enters all transform functions into the generic pointer */ static void arm_register_transformers(void) { - ir_op *op_Max, *op_Min, *op_Mulh; - /* first clear the generic function pointer for all ops */ clear_irp_opcodes_generic_func(); @@ -1612,6 +1610,7 @@ static void arm_register_transformers(void) { GEN(Add); GEN(Sub); GEN(Mul); + BAD(Mulh); /* unsupported yet */ GEN(And); GEN(Or); GEN(Eor); @@ -1661,6 +1660,9 @@ static void arm_register_transformers(void) { BAD(EndReg); BAD(EndExcept); + /* handle builtins */ + BAD(Builtin); + /* handle generic backend nodes */ GEN(be_FrameAddr); //GEN(be_Call); @@ -1672,16 +1674,6 @@ static void arm_register_transformers(void) { /* set the register for all Unknown nodes */ GEN(Unknown); - op_Max = get_op_Max(); - if (op_Max) - BAD(Max); /* unsupported yet */ - op_Min = get_op_Min(); - if (op_Min) - BAD(Min); /* unsupported yet */ - op_Mulh = get_op_Mulh(); - if (op_Mulh) - BAD(Mulh); /* unsupported yet */ - #undef GEN #undef BAD } diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 7c8d69ba0..8f2615e41 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -4790,8 +4790,6 @@ static ir_node *gen_Proj(ir_node *node) */ static void register_transformers(void) { - ir_op *op_Mulh; - /* first clear the generic function pointer for all ops */ clear_irp_opcodes_generic_func(); @@ -4801,6 +4799,7 @@ static void register_transformers(void) GEN(Add); GEN(Sub); GEN(Mul); + GEN(Mulh); GEN(And); GEN(Or); GEN(Eor); @@ -4868,6 +4867,9 @@ static void register_transformers(void) BAD(EndReg); BAD(EndExcept); + /* handle builtins */ + BAD(Builtin); + /* handle generic backend nodes */ GEN(be_FrameAddr); GEN(be_Call); @@ -4877,10 +4879,6 @@ static void register_transformers(void) GEN(be_SubSP); GEN(be_Copy); - op_Mulh = get_op_Mulh(); - if (op_Mulh) - GEN(Mulh); - #undef GEN #undef BAD } diff --git a/ir/be/ppc32/ppc32_transform.c b/ir/be/ppc32/ppc32_transform.c index 6c4a6a62d..91d17fa14 100644 --- a/ir/be/ppc32/ppc32_transform.c +++ b/ir/be/ppc32/ppc32_transform.c @@ -1245,8 +1245,6 @@ static ir_node *bad_transform(ppc32_transform_env_t *env) { * Enters all transform functions into the generic pointer */ void ppc32_register_transformers(void) { - ir_op *op_Max, *op_Min, *op_Mulh; - /* first clear the generic function pointer for all ops */ clear_irp_opcodes_generic_func(); @@ -1256,6 +1254,7 @@ void ppc32_register_transformers(void) { FIRM_OP(Add); FIRM_OP(Mul); + FIRM_OP(Mulh); FIRM_OP(And); FIRM_OP(Or); FIRM_OP(Eor); @@ -1315,16 +1314,11 @@ void ppc32_register_transformers(void) { BAD(EndReg); BAD(EndExcept); + /* handle builtins */ + BAD(Builtin); + + /* handle generic backend nodes */ FIRM_OP(be_FrameAddr); - op_Mulh = get_op_Mulh(); - if (op_Mulh) - FIRM_OP(Mulh); - op_Max = get_op_Max(); - if (op_Max) - BAD(Max); - op_Min = get_op_Min(); - if (op_Min) - BAD(Min); } typedef ir_node *(transform_func)(ppc32_transform_env_t *env); diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c index a0aaac55a..4a32134c0 100644 --- a/ir/ir/ircons.c +++ b/ir/ir/ircons.c @@ -479,7 +479,7 @@ new_bd_Call(dbg_info *db, ir_node *block, ir_node *store, int r_arity; ir_graph *irg = current_ir_graph; - r_arity = arity+2; + r_arity = arity + 2; NEW_ARR_A(ir_node *, r_in, r_arity); r_in[0] = store; r_in[1] = callee; @@ -496,6 +496,30 @@ new_bd_Call(dbg_info *db, ir_node *block, ir_node *store, return res; } /* new_bd_Call */ +static ir_node * +new_bd_Builtin(dbg_info *db, ir_node *block, ir_node *store, + ir_builtin_kind kind, int arity, ir_node **in, ir_type *tp) { + ir_node **r_in; + ir_node *res; + int r_arity; + ir_graph *irg = current_ir_graph; + + r_arity = arity + 1; + NEW_ARR_A(ir_node *, r_in, r_arity); + r_in[0] = store; + memcpy(&r_in[1], in, sizeof(ir_node *) * arity); + + res = new_ir_node(db, irg, block, op_Builtin, mode_T, r_arity, r_in); + + assert((get_unknown_type() == tp) || is_Method_type(tp)); + res->attr.builtin.exc.pin_state = op_pin_state_pinned; + res->attr.builtin.kind = kind; + res->attr.builtin.builtin_tp = tp; + res = optimize_node(res); + IRN_VRFY_IRG(res, irg); + return res; +} /* new_bd_Buildin */ + static ir_node * new_bd_Return(dbg_info *db, ir_node *block, ir_node *store, int arity, ir_node **in) { @@ -1125,6 +1149,19 @@ new_rd_Call(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store, return res; } /* new_rd_Call */ +ir_node * +new_rd_Builtin(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store, + ir_builtin_kind kind, int arity, ir_node **in, ir_type *tp) { + ir_node *res; + ir_graph *rem = current_ir_graph; + + current_ir_graph = irg; + res = new_bd_Builtin(db, block, store, kind, arity, in, tp); + current_ir_graph = rem; + + return res; +} /* new_rd_Builtin */ + ir_node * new_rd_Return(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store, int arity, ir_node **in) { @@ -1509,6 +1546,11 @@ ir_node *new_r_Call(ir_graph *irg, ir_node *block, ir_node *store, ir_type *tp) { return new_rd_Call(NULL, irg, block, store, callee, arity, in, tp); } +ir_node *new_r_Builtin(ir_graph *irg, ir_node *block, ir_node *store, + ir_builtin_kind kind, int arity, ir_node **in, + ir_type *tp) { + return new_rd_Builtin(NULL, irg, block, store, kind, arity, in, tp); +} #ifdef USE_ORIGINAL ir_node *new_r_Add(ir_graph *irg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode) { @@ -2497,6 +2539,12 @@ new_d_Call(dbg_info *db, ir_node *store, ir_node *callee, int arity, ir_node **i return res; } /* new_d_Call */ +ir_node * +new_d_Builtin(dbg_info *db, ir_node *store, ir_builtin_kind kind, int arity, ir_node **in, + ir_type *tp) { + return new_bd_Builtin(db, current_ir_graph->current_block, store, kind, arity, in, tp); +} /* new_d_Builtin */ + ir_node * new_d_Return(dbg_info *db, ir_node* store, int arity, ir_node **in) { return new_bd_Return(db, current_ir_graph->current_block, @@ -2943,6 +2991,10 @@ ir_node *new_Call(ir_node *store, ir_node *callee, int arity, ir_node **in, ir_type *tp) { return new_d_Call(NULL, store, callee, arity, in, tp); } +ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, ir_node **in, + ir_type *tp) { + return new_d_Builtin(NULL, store, kind, arity, in, tp); +} #ifdef USE_ORIGINAL ir_node *new_Add(ir_node *op1, ir_node *op2, ir_mode *mode) { return new_d_Add(NULL, op1, op2, mode); diff --git a/ir/ir/irdump.c b/ir/ir/irdump.c index 323f9fd3e..dcc187d59 100644 --- a/ir/ir/irdump.c +++ b/ir/ir/irdump.c @@ -828,6 +828,9 @@ int dump_node_opcode(FILE *F, ir_node *n) case iro_DivMod: fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_DivMod_resmode(n), &bad)); break; + case iro_Builtin: + fprintf(F, "%s[%s]", get_irn_opname(n), get_builtin_kind_name(get_Builtin_kind(n))); + break; default: default_case: diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 0358e4983..497fa3b0c 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -48,7 +48,7 @@ /* some constants fixing the positions of nodes predecessors in the in array */ #define CALL_PARAM_OFFSET 2 -#define FUNCCALL_PARAM_OFFSET 1 +#define BUILDIN_PARAM_OFFSET 1 #define SEL_INDEX_OFFSET 2 #define RETURN_RESULT_OFFSET 1 /* mem is not a result */ #define END_KEEPALIVE_OFFSET 0 @@ -1343,18 +1343,6 @@ get_Call_n_params(const ir_node *node) { return (get_irn_arity(node) - CALL_PARAM_OFFSET); } -int -get_Call_arity(const ir_node *node) { - assert(is_Call(node)); - return get_Call_n_params(node); -} - -/* void -set_Call_arity(ir_node *node, ir_node *arity) { - assert(is_Call(node)); -} -*/ - ir_node * get_Call_param(const ir_node *node, int pos) { assert(is_Call(node)); @@ -1380,6 +1368,80 @@ set_Call_type(ir_node *node, ir_type *tp) { node->attr.call.cld_tp = tp; } +ir_node * +get_Builtin_mem(const ir_node *node) { + assert(is_Builtin(node)); + return get_irn_n(node, 0); +} + +void +set_Builin_mem(ir_node *node, ir_node *mem) { + assert(is_Builtin(node)); + set_irn_n(node, 0, mem); +} + +ir_builtin_kind +get_Builtin_kind(const ir_node *node) { + assert(is_Builtin(node)); + return node->attr.builtin.kind; +} + +void +set_Builtin_kind(ir_node *node, ir_builtin_kind kind) { + assert(is_Builtin(node)); + node->attr.builtin.kind = kind; +} + +ir_node ** +get_Builtin_param_arr(ir_node *node) { + assert(is_Builtin(node)); + return &get_irn_in(node)[BUILDIN_PARAM_OFFSET + 1]; +} + +int +get_Builtin_n_params(const ir_node *node) { + assert(is_Builtin(node)); + return (get_irn_arity(node) - BUILDIN_PARAM_OFFSET); +} + +ir_node * +get_Builtin_param(const ir_node *node, int pos) { + assert(is_Builtin(node)); + return get_irn_n(node, pos + BUILDIN_PARAM_OFFSET); +} + +void +set_Builtin_param(ir_node *node, int pos, ir_node *param) { + assert(is_Builtin(node)); + set_irn_n(node, pos + BUILDIN_PARAM_OFFSET, param); +} + +ir_type * +get_Builtin_type(ir_node *node) { + assert(is_Builtin(node)); + return node->attr.builtin.builtin_tp = skip_tid(node->attr.builtin.builtin_tp); +} + +void +set_Builtin_type(ir_node *node, ir_type *tp) { + assert(is_Builtin(node)); + assert((get_unknown_type() == tp) || is_Method_type(tp)); + node->attr.builtin.builtin_tp = tp; +} + +/* Returns a human readable string for the ir_builtin_kind. */ +const char *get_builtin_kind_name(ir_builtin_kind kind) { +#define X(a) case a: return #a + 6; + switch (kind) { + X(ir_bk_return_address); + X(ir_bk_frame_addess); + X(ir_bk_prefetch); + } + return ""; +#undef X +} + + int Call_has_callees(const ir_node *node) { assert(is_Call(node)); return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) && @@ -2771,6 +2833,12 @@ int return _is_Call(node); } +/* returns true if node is a Builtin node. */ +int +(is_Builtin)(const ir_node *node) { + return _is_Builtin(node); +} + /* returns true if node is a CallBegin node. */ int (is_CallBegin)(const ir_node *node) { diff --git a/ir/ir/irnode_t.h b/ir/ir/irnode_t.h index 51df6b6bf..d65b3aaa2 100644 --- a/ir/ir/irnode_t.h +++ b/ir/ir/irnode_t.h @@ -627,6 +627,12 @@ _is_Call(const ir_node *node) { return (_get_irn_op(node) == op_Call); } +static inline int +_is_Builtin(const ir_node *node) { + assert(node); + return (_get_irn_op(node) == op_Builtin); +} + static inline int _is_CallBegin(const ir_node *node) { assert(node); @@ -1037,6 +1043,7 @@ _is_arg_Proj(const ir_node *node) { #define is_Unknown(node) _is_Unknown(node) #define is_Return(node) _is_Return(node) #define is_Call(node) _is_Call(node) +#define is_Builtin(node) _is_Builtin(node) #define is_CallBegin(node) _is_CallBegin(node) #define is_Sel(node) _is_Sel(node) #define is_Mul(node) _is_Mul(node) diff --git a/ir/ir/irop.c b/ir/ir/irop.c index 6d184853b..98b25af40 100644 --- a/ir/ir/irop.c +++ b/ir/ir/irop.c @@ -57,6 +57,7 @@ ir_op *op_Const; ir_op *get_op_Const (void) { return op_Const; } ir_op *op_SymConst; ir_op *get_op_SymConst (void) { return op_SymConst; } ir_op *op_Call; ir_op *get_op_Call (void) { return op_Call; } +ir_op *op_Builtin; ir_op *get_op_Builtin (void) { return op_Builtin; } ir_op *op_Add; ir_op *get_op_Add (void) { return op_Add; } ir_op *op_Sub; ir_op *get_op_Sub (void) { return op_Sub; } ir_op *op_Minus; ir_op *get_op_Minus (void) { return op_Minus; } @@ -357,6 +358,7 @@ init_op(void) op_Pin = new_ir_op(iro_Pin, "Pin", op_pin_state_pinned, H, oparity_unary, -1, 0, NULL); op_ASM = new_ir_op(iro_ASM, "ASM", op_pin_state_mem_pinned, K|M, oparity_variable, -1, sizeof(asm_attr), NULL); + op_Builtin = new_ir_op(iro_Builtin, "Builtin", op_pin_state_mem_pinned, M, oparity_variable, -1, sizeof(builtin_attr), NULL); op_Anchor = new_ir_op(iro_Anchor, "Anchor", op_pin_state_pinned, N|NB, oparity_variable, -1, 0, NULL); diff --git a/ir/ir/irtypes.h b/ir/ir/irtypes.h index b14a5da91..22110a491 100644 --- a/ir/ir/irtypes.h +++ b/ir/ir/irtypes.h @@ -194,6 +194,13 @@ typedef struct { ir_entity ** callee_arr; /**< result of callee analysis */ } call_attr; +/** Builtin attributes. */ +typedef struct { + except_attr exc; /**< the exception attribute. MUST be the first one. */ + ir_builtin_kind kind; /**< kind of the called builtin procedure */ + ir_type *builtin_tp; /**< type of called builtin procedure */ +} builtin_attr; + /** Alloc attributes. */ typedef struct { except_attr exc; /**< the exception attribute. MUST be the first one. */ @@ -305,7 +312,8 @@ typedef union { const_attr con; /**< For Const: contains the value of the constant and a type */ symconst_attr symc; /**< For SymConst. */ sel_attr sel; /**< For Sel. */ - call_attr call; /**< For Call: pointer to the type of the method to call */ + call_attr call; /**< For Call. */ + builtin_attr builtin; /**< For Builtin. */ callbegin_attr callbegin; /**< For CallBegin. */ alloc_attr alloc; /**< For Alloc. */ free_attr free; /**< For Free. */ -- 2.20.1