+ /* the address of the load to be optimized */
+ ptr = get_Load_ptr(load);
+
+ /*
+ * Check if we can remove the exception form a Load:
+ * this can be done, if the address is from an Sel(Alloc) and
+ * the Sel type is a subtype of the alloc type.
+ *
+ * This optimizes some often used OO constructs,
+ * like x = new O; x->t;
+ */
+ if (info->projs[pn_Load_X_except]) {
+ if (get_irn_op(ptr) == op_Sel) {
+ ir_node *mem = get_Sel_mem(ptr);
+
+ if (get_irn_op(mem) == op_Alloc) {
+ /* ok, check the types */
+ entity *ent = get_Sel_entity(ptr);
+ type *s_type = get_entity_type(ent);
+ type *a_type = get_Alloc_type(mem);
+
+ if (is_subclass_of(s_type, a_type)) {
+ /* ok, condition met: there can't be an exception because
+ * alloc guarantees that enough memory was allocated */
+
+ exchange(info->projs[pn_Load_X_except], new_Bad());
+ info->projs[pn_Load_X_except] = NULL;
+ }
+ }
+ }
+ else if (get_irn_op(ptr) == op_Alloc) {
+ /* simple case: a direct load after an Alloc. Firm Alloc throw
+ * an exception in case of out-of-memory. So, there is no way for an
+ * exception in this load.
+ * This code is constructed by the "exception lowering" in the Jack compiler.
+ */
+ exchange(info->projs[pn_Load_X_except], new_Bad());
+ info->projs[pn_Load_X_except] = NULL;
+ }
+ }
+