+/**
+ * Update a property depending on a call property.
+ */
+static mtp_additional_properties update_property(mtp_additional_properties orig_prop, mtp_additional_properties call_prop)
+{
+ mtp_additional_properties t = (orig_prop | call_prop) & mtp_temporary;
+ mtp_additional_properties r = orig_prop & call_prop;
+ return r | t;
+}
+
+/**
+ * Check if a node is stored.
+ */
+static int is_stored(const ir_node *n)
+{
+ const ir_edge_t *edge;
+ const ir_node *ptr;
+
+ foreach_out_edge(n, edge) {
+ const ir_node *succ = get_edge_src_irn(edge);
+
+ switch (get_irn_opcode(succ)) {
+ case iro_Return:
+ case iro_Load:
+ case iro_Cmp:
+ /* ok */
+ break;
+ case iro_Store:
+ if (get_Store_value(succ) == n)
+ return 1;
+ /* ok if its only the address input */
+ break;
+ case iro_Sel:
+ case iro_Cast:
+ case iro_Confirm:
+ if (is_stored(succ))
+ return 1;
+ break;
+ case iro_Call:
+ ptr = get_Call_ptr(succ);
+ if (is_Global(ptr)) {
+ ir_entity *ent = get_Global_entity(ptr);
+ size_t i;
+
+ /* we know the called entity */
+ for (i = get_Call_n_params(succ); i > 0;) {
+ if (get_Call_param(succ, --i) == n) {
+ /* n is the i'th param of the call */
+ if (get_method_param_access(ent, i) & ptr_access_store) {
+ /* n is store in ent */
+ return 1;
+ }
+ }
+ }
+ } else {
+ /* unknown call address */
+ return 1;
+ }
+ break;
+ default:
+ /* bad, potential alias */
+ return 1;