1 /*************************************************************************
2 * Program: firm_node_ext.c
3 * Function: Provides functions to extend firm by nodes needed by the
5 * Author: Andreas Schoesser
7 *************************************************************************/
13 #include "simd_presets.h"
19 #include "ia32/gen_ia32_regalloc_if.h"
20 #include "grs/base_t.h"
25 ir_opcode iro_MultipleAdd;
26 ir_op *op_MultipleAdd;
31 ir_opcode iro_Complex;
34 ir_opcode iro_FakeComplex;
35 ir_op *op_FakeComplex;
38 ir_opcode iro_be_Keep;
39 extern ir_op *op_be_Keep;
43 /************************************************************************
44 * Initialize the pattern creation.
45 * - Creates new Firm opcodes needed by the transformation
46 ************************************************************************/
50 // The SIMD optimization inserts ia32 specific nodes
51 // Create the opcodes for those nodes here
52 // Reason: We need those opcodes when inserting ia32_nodes anyway.
53 ia32_register_init(NULL);
54 ia32_create_opcodes();
57 iro_VProj = get_next_ir_opcode();
58 op_VProj = new_ir_op(iro_VProj, "VProj", op_pin_state_pinned, 0, oparity_unary, 0, sizeof(long), NULL);
60 iro_MultipleAdd = get_next_ir_opcode();
61 op_MultipleAdd = new_ir_op(iro_MultipleAdd, "MultipleAdd", op_pin_state_pinned, 0, oparity_dynamic, 0, 0, NULL);
63 iro_IrNode = get_next_ir_opcode();
64 op_IrNode = new_ir_op(iro_IrNode, "IR_node", op_pin_state_pinned, 0, oparity_dynamic, 0, 0, NULL);
66 iro_Complex = get_next_ir_opcode();
67 op_Complex = new_ir_op(iro_Complex, "Complex", op_pin_state_pinned, irop_flag_none, oparity_dynamic, 0, 0, NULL);
69 iro_FakeComplex = get_next_ir_opcode();
70 op_FakeComplex = new_ir_op(iro_FakeComplex, "FakeComplex", op_pin_state_pinned, irop_flag_none, oparity_dynamic, 0, 0, NULL);
72 iro_be_Keep = get_op_code(op_be_Keep);
74 // Mode LLu now exists:
75 // mode_DLu = new_ir_vector_mode("DLu", irms_int_number, 128, 4, 0, irma_none, 128);
80 /************************************************************************
81 * Inserts a new ir_node an also updates the opcode lists of the GRS
82 ************************************************************************/
84 ir_node *new_ir_node_with_update(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode, int arity, ir_node *in[])
86 ir_node *new_node = new_ir_node(db, irg, block, op, mode, arity, in);
88 // Update the GRS' node list
89 ext_grs_irn_private_t *pr_n = _ext_grs_get_irn_private(new_node);
90 ext_grs_irg_private_t *pr_g = _ext_grs_get_irg_private(irg);
92 memset(pr_n, 0, sizeof(*pr_n));
94 // Do we have to initialize pr_n?
96 lc_list_add(&pr_n->node_list, &_ext_grs_NODE_LIST(pr_g, get_op_code(op), get_mode_modecode(mode)));
98 // Do we have to call this?
99 // (_ext_grs_N_INSTANCES(pr_g, get_op_code(op), get_mode_modecode(mode)))++;
108 | \/ |_ _| | |_ / \ __| | __| |
109 | |\/| | | | | | __| / _ \ / _` |/ _` |
110 | | | | |_| | | |_ / ___ \ (_| | (_| |
111 |_| |_|\__,_|_|\__/_/ \_\__,_|\__,_| */
113 /************************************************************************
114 * Returns 1 if the given node is a MultipleAdd operation
115 ************************************************************************/
117 int is_MultipleAdd(ir_node *n)
119 return(get_irn_opcode(n) == iro_MultipleAdd);
124 /************************************************************************
125 * Returns 1 if the 2 MultipeAdd nodes have the same base addresses
126 * but different offsets > size -> no alias
127 * 0 otherwise -> may alias
128 ************************************************************************/
130 ir_alias_relation get_multadd_alias_relation(ir_node *n1, ir_node *n2)
133 int i, offset_diff, same_base = 1, pos1, pos2, summands_not_equal = 0, size;
134 ir_node *const1 = NULL, *const2 = NULL, *base1 = NULL, *base2 = NULL, *ma1, *ma2;
135 ir_mode *mode1, *mode2;
138 switch(get_irn_opcode(n1))
140 case iro_Store: ma1 = get_Store_ptr(n1); mode1 = get_irn_mode(get_Store_value(n1)); break;
141 case iro_Load: ma1 = get_Load_ptr(n1); mode1 = get_Load_mode(n1); /*mode_F;*/ /* Hack */ break; // TODO: Get Load mode
142 default: return(no_alias);
145 switch(get_irn_opcode(n2))
147 case iro_Store: ma2 = get_Store_ptr(n2); mode2 = get_irn_mode(get_Store_value(n1)); break;
148 case iro_Load: ma2 = get_Load_ptr(n2); mode2 = get_Load_mode(n1); /*mode_F;*/ /* Hack */ break; // TODO: Get LOAD mode
149 default: return(no_alias);
152 assert(is_MultipleAdd(ma1) && is_MultipleAdd(ma2));
154 size = MAX(get_mode_size_bytes(mode1), get_mode_size_bytes(mode2));
156 // Different number of summands. Return "may alias"
157 // Rethink. If they contain different Sel's or restrict pointers
158 if(get_irn_arity(ma1) != get_irn_arity(ma2))
161 // Since MultipleAdd ins are ordered, the constant value has to be in_0 in both cases
162 const1 = get_irn_n(ma1, 0);
163 const2 = get_irn_n(ma2, 0);
164 if(!is_Const(const1) && !is_Const(const2))
167 offset_diff = abs(get_tarval_long(get_Const_tarval(const1)) - get_tarval_long(get_Const_tarval(const2)));
169 // Go through both in-arrays simultaneously and search for the base pointers
170 // Also check the rest of the ins for equalness
172 for(pos1 = 1, pos2 = 1; pos1 < get_irn_arity(ma1) && pos2 < get_irn_arity(ma1); )
176 if((n1 = get_irn_n(ma1, pos1)) == (n2 = get_irn_n(ma2, pos2)))
183 summands_not_equal = 1;
185 n1 = get_irn_n(ma1, pos1);
186 n2 = get_irn_n(ma2, pos2);
188 // Look if we have the base pointer
189 if((get_irn_opcode(n1) == iro_Proj || get_irn_opcode(n1) == iro_Sel))
191 assert(base1 == NULL);
196 if((get_irn_opcode(n2) == iro_Proj || get_irn_opcode(n2) == iro_Sel))
198 assert(base2 == NULL);
204 /*if(summands_not_equal)
205 return(may_alias); */
207 if(base1 == NULL || base2 == NULL)
209 if(!summands_not_equal)
211 // Summands are exaclty the same (including the base) so check the constant
212 if(offset_diff < size)
213 return(sure_alias); // Offsets are overlapping
214 return(no_alias); // Offsets are not overlapping
218 // Summands not the same and no (or just 1) base found. Bad luck, bail out
224 // Summands are different, but 2 bases were found. check them:
225 // Alias relation depends on the alias relation of the base addresses
226 assert(base1 != NULL && base2 != NULL && "We should have found 2 bases!");
227 return(get_alias_relation(get_irn_irg(base1), base1, mode_F, base2, mode_F));
237 \ \ / / _ \ _ __ ___ (_)
238 \ \ / /| |_) | '__/ _ \| |
239 \ V / | __/| | | (_) | |
243 /************************************************************************
244 * Gets and sets the vproj number
245 ************************************************************************/
247 int get_VProj_proj(ir_node *node)
249 int *pa = (int *) get_irn_generic_attr(node);
253 void set_VProj_proj(ir_node *node, int proj)
255 int *pa = get_irn_generic_attr(node);
259 ir_opcode get_VProj_op()