Commit 814def24 authored by Michael Beck's avatar Michael Beck
Browse files

Added NoMem node that represents a Memory that is Not used

Allows calls to be "unpinned"
Removed FuncCall(), can be emulated by Call(NoMem, ...)

[r4348]
parent 854a5a30
......@@ -853,27 +853,10 @@ new_rd_Filter (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *arg, ir_mod
}
ir_node *
new_rd_FuncCall (dbg_info* db, ir_graph *irg, ir_node *block,
ir_node *callee, int arity, ir_node **in, type *tp)
INLINE ir_node *
new_rd_NoMem (ir_graph *irg)
{
ir_node **r_in;
ir_node *res;
int r_arity;
r_arity = arity+1;
NEW_ARR_A(ir_node *, r_in, r_arity);
r_in[0] = callee;
memcpy(&r_in[1], in, sizeof (ir_node *) * arity);
res = new_ir_node(db, irg, block, op_FuncCall, mode_T, r_arity, r_in);
assert(is_method_type(tp));
set_FuncCall_type(res, tp);
res->attr.call.callee_arr = NULL;
res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
return res;
return irg->no_mem;
}
......@@ -1065,10 +1048,8 @@ INLINE ir_node *new_r_Filter (ir_graph *irg, ir_node *block, ir_node *arg,
ir_mode *mode, long proj) {
return new_rd_Filter(NULL, irg, block, arg, mode, proj);
}
INLINE ir_node *new_r_FuncCall (ir_graph *irg, ir_node *block,
ir_node *callee, int arity, ir_node **in,
type *tp) {
return new_rd_FuncCall(NULL, irg, block, callee, arity, in, tp);
INLINE ir_node *new_r_NoMem (ir_graph *irg) {
return new_rd_NoMem(irg);
}
......@@ -2373,14 +2354,9 @@ new_d_Filter (dbg_info *db, ir_node *arg, ir_mode *mode, long proj)
}
ir_node *
new_d_FuncCall (dbg_info* db, ir_node *callee, int arity, ir_node **in,
type *tp)
(new_d_NoMem)(void)
{
ir_node *res;
res = new_rd_FuncCall (db, current_ir_graph, current_ir_graph->current_block,
callee, arity, in, tp);
return res;
return __new_d_NoMem();
}
/* ********************************************************************* */
......@@ -2688,6 +2664,6 @@ ir_node *new_Break (void) {
ir_node *new_Filter (ir_node *arg, ir_mode *mode, long proj) {
return new_d_Filter(NULL, arg, mode, proj);
}
ir_node *new_FuncCall (ir_node *callee, int arity, ir_node **in, type *tp) {
return new_d_FuncCall(NULL, callee, arity, in, tp);
ir_node *new_NoMem (void) {
return new_d_NoMem();
}
......@@ -359,8 +359,7 @@
* ir_node *new_Free (ir_node *store, ir_node *ptr, ir_node *size,
* type *free_type);
* ir_node *new_Proj (ir_node *arg, ir_mode *mode, long proj);
* ir_node *new_FuncCall (ir_node *store, ir_node *callee, int arity,
* ir_node **in, type_method *type);
* ir_node *new_NoMem (void);
*
* void add_immBlock_pred (ir_node *block, ir_node *jmp);
* void mature_immBlock (ir_node *block);
......@@ -706,26 +705,6 @@
* Attributes:
* attr.call Contains the type information for the procedure.
*
* ir_node *new_FuncCall (ir_node *callee, int arity, ir_node **in, type_method *type)
* -----------------------------------------------------------------------------------
*
* Creates a procedure call to a function WITHOUT memory side effects.
* nodes of this kind are floating in contrast to Call nodes.
* Further, a procedure call with FuncCall cannot raise an exception!
*
* Parameters
* *callee A pointer to the called procedure.
* 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 callee and the parameters.
* Output:
* A tuple containing the procedure results.
* Attributes:
* attr.call Contains the type information for the procedure.
*
* ir_node *new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
* ------------------------------------------------------------
......@@ -997,6 +976,13 @@
* Returns the unique Bad node current_ir_graph->bad.
* This node is used to express results of dead code elimination.
*
* ir_node *new_NoMem (void)
* -----------------------------------------------------------------------------------
*
* Returns the unique NoMem node current_ir_graph->no_mem.
* This node is used as input for operations that need a Memory, but do not
* change it like Div by const != 0, analyzed calls etc.
*
* ir_node *new_Proj (ir_node *arg, ir_mode *mode, long proj)
* ----------------------------------------------------------
*
......@@ -1363,24 +1349,6 @@ ir_node *new_rd_InstOf (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[], type *tp);
/** Constructor for a FuncCall node.
*
* FuncCall is a function Call that has no side effects. Therefore there
* is not memory operand or result.
*
* @param *db A pointer for debug information.
* @param *irg The ir graph the node belong to.
* @param *block The block the node belong to.
* @param *callee A pointer to the called procedure.
* @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_rd_FuncCall (dbg_info *db, ir_graph *irg, ir_node *block,
ir_node *callee, int arity, ir_node *in[],
type *tp);
/** Constructor for a Add node.
*
* @param *db A pointer for debug information.
......@@ -1846,6 +1814,14 @@ ir_node *new_rd_EndExcept(dbg_info *db, ir_graph *irg, ir_node *block);
ir_node *new_rd_Filter (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *arg,
ir_mode *mode, long proj);
/** Constructor for a NoMem node.
*
* Returns the unique NoMem node of the graph. The same as
* get_irg_no_mem().
*
* @param *irg The ir graph the node belongs to.
*/
ir_node *new_rd_NoMem (ir_graph *irg);
/*-------------------------------------------------------------------------*/
/* The raw interface without debug support */
......@@ -2470,22 +2446,14 @@ ir_node *new_r_Break (ir_graph *irg, ir_node *block);
ir_node *new_r_Filter (ir_graph *irg, ir_node *block, ir_node *arg,
ir_mode *mode, long proj);
/** Constructor for a FuncCall node.
/** Constructor for a NoMem node.
*
* FuncCall is a function Call that has no side effects. Therefore there
* is not memory operand or result.
* Returns the unique NoMem node of the graph. The same as
* get_irg_no_mem().
*
* @param *irg The ir graph the node belong to.
* @param *block The block the node belong to.
* @param *callee A pointer to the called procedure.
* @param arity The number of procedure parameters.
* @param *in[] An array with the pointers to the parameters.
* The constructor copies this array.
* @param *type Type information of the procedure called.
* @param *irg The ir graph the node belongs to.
*/
ir_node *new_r_FuncCall (ir_graph *irg, ir_node *block,
ir_node *callee, int arity, ir_node *in[],
type *tp);
ir_node *new_r_NoMem (ir_graph *irg);
/*-----------------------------------------------------------------------*/
/* The block oriented interface */
......@@ -3162,20 +3130,12 @@ ir_node *new_d_Break (dbg_info *db);
ir_node *new_d_Filter (dbg_info *db, ir_node *arg, ir_mode *mode, long proj);
/** Constructor for a FuncCall node.
/** Constructor for a NoMem node.
*
* FuncCall is a function Call that has no side effects. Therefore there
* is not memory operand or result. Adds the node to the block in current_ir_block.
*
* @param *db A pointer for debug information.
* @param *callee A pointer to the called procedure.
* @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.
* Returns the unique NoMem node of the graph. The same as
* get_irg_no_mem().
*/
ir_node *new_d_FuncCall (dbg_info* db, ir_node *callee, int arity, ir_node *in[],
type *tp);
ir_node *new_d_NoMem (void);
/*-----------------------------------------------------------------------*/
/* The block oriented interface without debug support */
......@@ -3712,7 +3672,6 @@ ir_node *new_Id (ir_node *val, ir_mode *mode);
* Returns the unique Bad node of the graph. The same as
* get_irg_bad().
*/
ir_node *new_Bad (void);
/** Constructor for a Confirm node.
......@@ -3738,19 +3697,12 @@ ir_node *new_Confirm (ir_node *val, ir_node *bound, pn_Cmp cmp);
*/
ir_node *new_Unknown(ir_mode *m);
/** Constructor for a FuncCall node.
/** Constructor for a NoMem node.
*
* FuncCall is a function Call that has no side effects. Therefore there
* is not memory operand or result.Adds the node to the block in current_ir_block.
*
* @param *callee A pointer to the called procedure.
* @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.
* Returns the unique NoMem node of the graph. The same as
* get_irg_no_mem().
*/
ir_node *new_FuncCall (ir_node *callee, int arity, ir_node *in[],
type *tp);
ir_node *new_NoMem (void);
/*---------------------------------------------------------------------*/
/* The comfortable interface. */
......
......@@ -30,6 +30,13 @@ __new_d_Bad(void) {
return current_ir_graph->bad;
}
static INLINE ir_node *
__new_d_NoMem(void) {
return current_ir_graph->no_mem;
}
#define new_d_Bad() __new_d_Bad()
#define new_d_NoMem() __new_d_NoMem()
#endif /* _IRCONS_T_H_ */
......@@ -250,7 +250,8 @@ static void collect_node(ir_node * node, void *env) {
if (is_Block(node)
|| node_floats(node)
|| get_irn_op(node) == op_Bad
|| get_irn_op(node) == op_Unknown) {
|| get_irn_op(node) == op_Unknown
|| get_irn_op(node) == op_NoMem) {
ir_node ** arr = (ir_node **) ird_get_irg_link(get_irn_irg(node));
if (!arr) arr = NEW_ARR_F(ir_node *, 0);
ARR_APP1(ir_node *, arr, node);
......@@ -265,7 +266,7 @@ static void collect_node(ir_node * node, void *env) {
/** Construct lists to walk ir block-wise.
*
* Collects all blocks, nodes not op_pin_state_pinned,
* Bad and Unknown into a flexible array in link field of
* Bad, NoMem and Unknown into a flexible array in link field of
* irg they belong to. Sets the irg link field to NULL in all
* graphs not visited.
* Free the list with DEL_ARR_F. */
......@@ -487,6 +488,7 @@ dump_node_mode(FILE *F, ir_node *n)
case iro_Free:
case iro_Sync:
case iro_Jmp:
case iro_NoMem:
break;
default: {
ir_mode *mode = get_irn_mode(n);
......@@ -774,11 +776,13 @@ static INLINE int dump_node_info(FILE *F, ir_node *n)
return bad;
}
/**
* checks wheater a node is "constant-like", ie can be treated "block-less"
*/
static INLINE
bool is_constlike_node(ir_node *n) {
ir_op *op = get_irn_op(n);
return (op == op_Const || op == op_Bad || op == op_SymConst || op == op_Unknown);
return (op == op_Const || op == op_Bad || op == op_NoMem || op == op_SymConst || op == op_Unknown);
}
......@@ -1177,7 +1181,7 @@ static void dump_graph(FILE *F, ir_graph *irg) {
/* Basic type and entity nodes and edges. */
/*******************************************************************/
/* dumps the edges between nodes and their type or entity attributes. */
/** dumps the edges between nodes and their type or entity attributes. */
static void dump_node2type_edges(ir_node *n, void *env)
{
FILE *F = env;
......
......@@ -75,6 +75,8 @@ void set_opt_constant_folding (int value);
* - Remove Store that overwrites a just stored value (WAW).
* - Remove Store if it stores a value just loaded (WAR with the same value).
* - Remove Load that loads a value just saved (RAW with the same value).
* - remove Load that loads a value already loaded (RAR)
* - replace Load of constant values with constants (RC)
*/
void set_opt_redundant_LoadStore(int value);
......
......@@ -343,7 +343,7 @@ copy_preds (ir_node *n, void *env) {
*/
static void
copy_graph (int copy_node_nr) {
ir_node *oe, *ne, *ob, *nb; /* old end, new end, old bad, new bad */
ir_node *oe, *ne, *ob, *nb, *om, *nm; /* old end, new end, old bad, new bad, old NoMem, new NoMem */
ir_node *ka; /* keep alive */
int i, irn_arity;
......@@ -360,6 +360,7 @@ copy_graph (int copy_node_nr) {
copy_attrs(oe, ne);
set_new_node(oe, ne);
/* copy the Bad node */
ob = get_irg_bad(current_ir_graph);
nb = new_ir_node(get_irn_dbg_info(ob),
current_ir_graph,
......@@ -370,6 +371,17 @@ copy_graph (int copy_node_nr) {
NULL);
set_new_node(ob, nb);
/* copy the NoMem node */
om = get_irg_no_mem(current_ir_graph);
nm = new_ir_node(get_irn_dbg_info(om),
current_ir_graph,
NULL,
op_NoMem,
mode_M,
0,
NULL);
set_new_node(om, nm);
/* copy the live nodes */
irg_walk(get_nodes_block(oe), copy_node, copy_preds, (void *)copy_node_nr);
/* copy_preds for the end node ... */
......@@ -404,8 +416,9 @@ copy_graph (int copy_node_nr) {
}
}
/* start block somtimes only reached after keep alives */
/* start block sometimes only reached after keep alives */
set_nodes_block(nb, get_new_node(get_nodes_block(ob)));
set_nodes_block(nm, get_new_node(get_nodes_block(om)));
}
/**
......@@ -426,6 +439,7 @@ copy_graph_env (int copy_node_nr) {
set_irn_link(get_irg_globals (current_ir_graph), NULL);
set_irn_link(get_irg_args (current_ir_graph), NULL);
set_irn_link(get_irg_initial_mem(current_ir_graph), NULL);
set_irn_link(get_irg_no_mem (current_ir_graph), NULL);
/* we use the block walk flag for removing Bads from Blocks ins. */
inc_irg_block_visited(current_ir_graph);
......@@ -470,6 +484,12 @@ copy_graph_env (int copy_node_nr) {
copy_preds(get_irg_bad(current_ir_graph), NULL);
}
set_irg_bad(current_ir_graph, get_new_node(get_irg_bad(current_ir_graph)));
if (get_irn_link(get_irg_no_mem(current_ir_graph)) == NULL) {
copy_node(get_irg_no_mem(current_ir_graph), (void *)copy_node_nr);
copy_preds(get_irg_no_mem(current_ir_graph), NULL);
}
set_irg_no_mem(current_ir_graph, get_new_node(get_irg_no_mem(current_ir_graph)));
}
/**
......
......@@ -151,10 +151,12 @@ new_ir_graph (entity *ent, int n_loc)
res->start_block = new_immBlock();
res->start = new_Start();
res->bad = new_ir_node(NULL, res, res->start_block, op_Bad, mode_T, 0, NULL);
res->no_mem = new_ir_node(NULL, res, res->start_block, op_NoMem, mode_M, 0, NULL);
/* Proj results of start node */
projX = new_Proj (res->start, mode_X, pn_Start_X_initial_exec);
res->frame = new_Proj (res->start, mode_P_mach, pn_Start_P_frame_base); res->globals = new_Proj (res->start, mode_P_mach, pn_Start_P_globals);
res->frame = new_Proj (res->start, mode_P_mach, pn_Start_P_frame_base);
res->globals = new_Proj (res->start, mode_P_mach, pn_Start_P_globals);
res->initial_mem = new_Proj (res->start, mode_M, pn_Start_M);
res->args = new_Proj (res->start, mode_T, pn_Start_T_args);
#ifdef DEBUG_libfirm
......@@ -214,7 +216,8 @@ ir_graph *new_const_code_irg(void) {
res->end_reg = res->end;
res->end_except = res->end;
mature_immBlock(get_cur_block()); /* mature the end block */
res->bad = new_ir_node (NULL, res, res->start_block, op_Bad, mode_T, 0, NULL);
res->bad = new_ir_node (NULL, res, res->start_block, op_Bad, mode_T, 0, NULL);
res->no_mem = new_ir_node (NULL, res, res->start_block, op_NoMem, mode_M, 0, NULL);
res->start = new_Start ();
res->initial_mem = new_Proj (res->start, mode_M, pn_Start_M);
......@@ -231,6 +234,7 @@ ir_graph *new_const_code_irg(void) {
set_Block_block_visited(res->start_block, -1);
set_irn_visited(res->start_block, -1);
set_irn_visited(res->bad, -1);
set_irn_visited(res->no_mem, -1);
res->phase_state = phase_high;
return res;
......@@ -411,19 +415,15 @@ void
__set_irg_bad(irg, node);
}
/* GL removed: we need unknown with mode for analyses.
ir_node *
get_irg_unknown (ir_graph *irg)
{
return irg->unknown;
(get_irg_no_mem)(const ir_graph *irg) {
return __get_irg_no_mem(irg);
}
void
set_irg_unknown (ir_graph *irg, ir_node *node)
{
irg->unknown = node;
(set_irg_no_mem)(ir_graph *irg, ir_node *node) {
__set_irg_no_mem(irg, node);
}
*/
ir_node *
(get_irg_current_block)(const ir_graph *irg) {
......
......@@ -190,6 +190,10 @@ void set_irg_current_block (ir_graph *irg, ir_node *node);
ir_node *get_irg_bad (const ir_graph *irg);
void set_irg_bad (ir_graph *irg, ir_node *node);
/** Returns the NoMem node. Use new_NoMem() instead!! */
ir_node *get_irg_no_mem (const ir_graph *irg);
void set_irg_no_mem (ir_graph *irg, ir_node *node);
/** Returns the number of value numbers of a graph. */
int get_irg_n_locs (ir_graph *irg);
......
......@@ -59,6 +59,8 @@ struct ir_graph {
struct ir_node *args; /**< methods arguments */
struct ir_node *bad; /**< bad node of this ir_graph, the one and
only in this graph */
struct ir_node *no_mem; /**< NoMem node of this ir_graph, the one and
only in this graph */
/* GL removed: we need unknown with mode for analyses. */
/* struct ir_node *unknown;*/ /**< unknown node of this ir_graph */
struct obstack *obst; /**< obstack where all of the ir_nodes live */
......@@ -270,6 +272,15 @@ __set_irg_bad(ir_graph *irg, ir_node *node) {
irg->bad = node;
}
static INLINE ir_node *
__get_irg_no_mem(const ir_graph *irg) {
return irg->no_mem;
}
static INLINE void
__set_irg_no_mem(ir_graph *irg, ir_node *node) {
irg->no_mem = node;
}
static INLINE ir_node *
__get_irg_current_block(const ir_graph *irg) {
return irg->current_block;
......@@ -440,6 +451,8 @@ __inc_irg_block_visited(ir_graph *irg) {
#define set_irg_args(irg, node) __set_irg_args(irg, node)
#define get_irg_bad(irg) __get_irg_bad(irg)
#define set_irg_bad(irg, node) __set_irg_bad(irg, node)
#define get_irg_no_mem(irg) __get_irg_no_mem(irg)
#define set_irg_no_mem(irg, node) __set_irg_no_mem(irg, node)
#define get_irg_current_block(irg) __get_irg_current_block(irg)
#define set_irg_current_block(irg, node) __set_irg_current_block(irg, node)
#define get_irg_entity(irg) __get_irg_entity(irg)
......
......@@ -367,7 +367,7 @@ void set_irn_pinned(ir_node *node, op_pin_state state) {
if (get_irn_op(node) == op_Tuple)
return;
assert(node && get_op_pinned(get_irn_op(node)) == op_pin_state_exc_pinned);
assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned);
assert(state == op_pin_state_pinned || state == op_pin_state_floats);
node->attr.except.pin_state = state;
......@@ -445,13 +445,6 @@ get_irn_call_attr (ir_node *node)
return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
}
type *
get_irn_funccall_attr (ir_node *node)
{
assert (node->op == op_FuncCall);
return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
}
sel_attr
get_irn_sel_attr (ir_node *node)
{
......@@ -491,7 +484,7 @@ except_attr
get_irn_except_attr (ir_node *node)
{
assert (node->op == op_Div || node->op == op_Quot ||
node->op == op_DivMod || node->op == op_Mod);
node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc);
return node->attr.except;
}
......@@ -1186,95 +1179,6 @@ void set_CallBegin_call (ir_node *node, ir_node *call) {
node->attr.callbegin.call = call;
}
ir_node *
get_FuncCall_ptr (ir_node *node) {
assert (node->op == op_FuncCall);
return get_irn_n(node, 0);
}
void
set_FuncCall_ptr (ir_node *node, ir_node *ptr) {
assert (node->op == op_FuncCall);
set_irn_n(node, 0, ptr);
}
ir_node **
get_FuncCall_param_arr (ir_node *node) {
assert (node->op == op_FuncCall);
return (ir_node **)&get_irn_in(node)[FUNCCALL_PARAM_OFFSET];
}
int
get_FuncCall_n_params (ir_node *node) {
assert (node->op == op_FuncCall);
return (get_irn_arity(node) - FUNCCALL_PARAM_OFFSET);
}
int
get_FuncCall_arity (ir_node *node) {
assert (node->op == op_FuncCall);
return get_FuncCall_n_params(node);
}
/* void
set_FuncCall_arity (ir_node *node, ir_node *arity) {
assert (node->op == op_FuncCall);
}
*/
ir_node *
get_FuncCall_param (ir_node *node, int pos) {
assert (node->op == op_FuncCall);
return get_irn_n(node, pos + FUNCCALL_PARAM_OFFSET);
}
void
set_FuncCall_param (ir_node *node, int pos, ir_node *param) {
assert (node->op == op_FuncCall);
set_irn_n(node, pos + FUNCCALL_PARAM_OFFSET, param);
}
type *
get_FuncCall_type (ir_node *node) {
assert (node->op == op_FuncCall);
return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp);
}
void
set_FuncCall_type (ir_node *node, type *tp) {
assert (node->op == op_FuncCall);
assert (is_method_type(tp));
node->attr.call.cld_tp = tp;
}
int FuncCall_has_callees(ir_node *node) {
return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) &&
(node->attr.call.callee_arr != NULL));
}
int get_FuncCall_n_callees(ir_node * node) {
assert(node->op == op_FuncCall && node->attr.call.callee_arr);
return ARR_LEN(node->attr.call.callee_arr);
}
entity * get_FuncCall_callee(ir_node * node, int pos) {
assert(node->op == op_FuncCall && node->attr.call.callee_arr);
return node->attr.call.callee_arr[pos];
}
void set_FuncCall_callee_arr(ir_node * node, int n, entity ** arr) {
assert(node->op == op_FuncCall);
if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) {
node->attr.call.callee_arr = NEW_ARR_D(entity *, current_ir_graph->obst, n);
}
memcpy(node->attr.call.callee_arr, arr, n * sizeof(entity *));
}
void remove_FuncCall_callee_arr(ir_node * node) {
assert(node->op == op_FuncCall);
node->attr.call.callee_arr = NULL;
}
#define BINOP(OP) \
ir_node * get_##OP##_left(ir_node *node) { \
......
......@@ -515,44 +515,6 @@ void set_CallBegin_ptr (ir_node *node, ir_node *ptr);
ir_node *get_CallBegin_call (ir_node *node);
void set_CallBegin_call (ir_node *node, ir_node *call);
ir_node *get_FuncCall_ptr (ir_node *node);
void set_FuncCall_ptr (ir_node *node, ir_node *ptr);
ir_node **get_FuncCall_param_arr (ir_node *node);
/** Gets the number of parameters of a func call. */
int get_FuncCall_n_params (ir_node *node);
/** Gets the func call parameter at position pos. */
ir_node *get_FuncCall_param (ir_node *node, int pos);
/** Sets the func call parameter at position pos. */
void set_FuncCall_param (ir_node *node, int pos, ir_node *param);
/** Gets the type of a func call. */