-static unsigned analyze_arg(ir_node *arg, unsigned bits)
-{
- int i, p;
- ir_node *succ;
-
- /* We must visit a node once to avoid endless recursion.*/
- set_irn_link(arg, VISITED);
-
- for (i = get_irn_n_outs(arg) - 1; i >= 0; --i) {
- succ = get_irn_out(arg, i);
-
- /* We was here.*/
- if (get_irn_link(succ) == VISITED)
- continue;
-
- /* We should not walk over the memory edge.*/
- if (get_irn_mode(succ) == mode_M)
- continue;
-
- /* If we reach with the recursion a Call node and our reference
- isn't the address of this Call we accept that the reference will
- be read and written if the graph of the method represented by
- "Call" isn't computed else we analyze that graph. If our
- reference is the address of this
- Call node that mean the reference will be read.*/
- switch (get_irn_opcode(succ)) {
-
- case iro_Call: {
- ir_node *ptr = get_Call_ptr(succ);
-
- if (ptr == arg) {
- /* Hmm: not sure what this is, most likely a read */
- bits |= ptr_access_read;
- }
- else {
- ir_op *op = get_irn_op(ptr);
- ir_entity *meth_ent;
-
- if (op == op_SymConst && get_SymConst_kind(ptr) == symconst_addr_ent) {
- meth_ent = get_SymConst_entity(ptr);
-
- for (p = get_Call_n_params(succ) - 1; p >= 0; --p) {
- if (get_Call_param(succ, p) == arg) {
- /* an arg can be used more than once ! */
- bits |= get_method_param_access(meth_ent, p);
- }
- }
- }
- else if (op == op_Sel && get_irp_callee_info_state() == irg_callee_info_consistent) {
- /* is be a polymorphic call but callee information is available */
- int i, n_params = get_Call_n_params(succ);
-
- /* simply look into ALL possible callees */
- for (i = get_Call_n_callees(succ) - 1; i >= 0; --i) {
- meth_ent = get_Call_callee(succ, i);
-
- /* unknown_entity is used to signal that we don't know what is called */
- if (meth_ent == unknown_entity) {
- bits |= ptr_access_all;
- break;
- }
-
- for (p = n_params - 1; p >= 0; --p) {
- if (get_Call_param(succ, p) == arg) {
- /* an arg can be used more than once ! */
- bits |= get_method_param_access(meth_ent, p);
- }
- }
- }
- }
- else /* can do anything */
- bits |= ptr_access_all;
- }
-
- /* search stops here anyway */
- continue;
- }
- case iro_Store:
- /* We have reached a Store node => the reference is written or stored. */
- if (get_Store_ptr(succ) == arg) {
- /* written to */
- bits |= ptr_access_write;
- }
- else {
- /* stored itself */
- bits |= ptr_access_store;
- }
-
- /* search stops here anyway */
- continue;
-
- case iro_Load:
- /* We have reached a Load node => the reference is read. */
- bits |= ptr_access_read;
-
- /* search stops here anyway */
- continue;
-
- case iro_Conv:
- /* our address is casted into something unknown. Break our search. */
- bits = ptr_access_all;
- break;
-
- default:
- break;
- }
-
- /* If we know that, the argument will be read, write and stored, we
- can break the recursion.*/
- if (bits == ptr_access_all) {
- bits = ptr_access_all;
- break;
- }
-
- /*
- * A calculation that do not lead to a reference mode ends our search.
- * This is dangerous: It would allow to cast into integer and that cast back ...
- * so, when we detect a Conv we go mad, see the Conv case above.
- */
- if (!mode_is_reference(get_irn_mode(succ)))
- continue;
-
- /* follow further the address calculation */
- bits = analyze_arg(succ, bits);
- }
- set_irn_link(arg, NULL);
- return bits;
+static unsigned analyze_arg(ir_node *arg, unsigned bits) {
+ int i, p;
+ ir_node *succ;
+
+ /* We must visit a node once to avoid endless recursion.*/
+ set_irn_link(arg, VISITED);
+
+ for (i = get_irn_n_outs(arg) - 1; i >= 0; --i) {
+ succ = get_irn_out(arg, i);
+
+ /* We was here.*/
+ if (get_irn_link(succ) == VISITED)
+ continue;
+
+ /* We should not walk over the memory edge.*/
+ if (get_irn_mode(succ) == mode_M)
+ continue;
+
+ /* If we reach with the recursion a Call node and our reference
+ isn't the address of this Call we accept that the reference will
+ be read and written if the graph of the method represented by
+ "Call" isn't computed else we analyze that graph. If our
+ reference is the address of this
+ Call node that mean the reference will be read.*/
+ switch (get_irn_opcode(succ)) {
+
+ case iro_Call: {
+ ir_node *ptr = get_Call_ptr(succ);
+
+ if (ptr == arg) {
+ /* Hmm: not sure what this is, most likely a read */
+ bits |= ptr_access_read;
+ } else {
+ ir_entity *meth_ent;
+
+ if (is_Global(ptr)) {
+ meth_ent = get_Global_entity(ptr);
+
+ for (p = get_Call_n_params(succ) - 1; p >= 0; --p) {
+ if (get_Call_param(succ, p) == arg) {
+ /* an arg can be used more than once ! */
+ bits |= get_method_param_access(meth_ent, p);
+ }
+ }
+ } else if (is_Sel(ptr) && get_irp_callee_info_state() == irg_callee_info_consistent) {
+ /* is be a polymorphic call but callee information is available */
+ int i, n_params = get_Call_n_params(succ);
+
+ /* simply look into ALL possible callees */
+ for (i = get_Call_n_callees(succ) - 1; i >= 0; --i) {
+ meth_ent = get_Call_callee(succ, i);
+
+ /* unknown_entity is used to signal that we don't know what is called */
+ if (meth_ent == unknown_entity) {
+ bits |= ptr_access_all;
+ break;
+ }
+
+ for (p = n_params - 1; p >= 0; --p) {
+ if (get_Call_param(succ, p) == arg) {
+ /* an arg can be used more than once ! */
+ bits |= get_method_param_access(meth_ent, p);
+ }
+ }
+ }
+ } else /* can do anything */
+ bits |= ptr_access_all;
+ }
+
+ /* search stops here anyway */
+ continue;
+ }
+ case iro_Store:
+ /* We have reached a Store node => the reference is written or stored. */
+ if (get_Store_ptr(succ) == arg) {
+ /* written to */
+ bits |= ptr_access_write;
+ } else {
+ /* stored itself */
+ bits |= ptr_access_store;
+ }
+
+ /* search stops here anyway */
+ continue;
+
+ case iro_Load:
+ /* We have reached a Load node => the reference is read. */
+ bits |= ptr_access_read;
+
+ /* search stops here anyway */
+ continue;
+
+ case iro_Conv:
+ /* our address is casted into something unknown. Break our search. */
+ bits = ptr_access_all;
+ break;
+
+ default:
+ break;
+ }
+
+ /* If we know that, the argument will be read, write and stored, we
+ can break the recursion.*/
+ if (bits == ptr_access_all) {
+ bits = ptr_access_all;
+ break;
+ }
+
+ /*
+ * A calculation that do not lead to a reference mode ends our search.
+ * This is dangerous: It would allow to cast into integer and that cast back ...
+ * so, when we detect a Conv we go mad, see the Conv case above.
+ */
+ if (!mode_is_reference(get_irn_mode(succ)))
+ continue;
+
+ /* follow further the address calculation */
+ bits = analyze_arg(succ, bits);
+ }
+ set_irn_link(arg, NULL);
+ return bits;