rtx addr_for_mem_ref (tree exp, addr_space_t as, bool really_expand) { struct mem_address addr; get_address_description (exp, &addr); return addr_for_mem_ref (&addr, as, really_expand); }
tree maybe_fold_tmr (tree ref) { struct mem_address addr; bool changed = false; tree ret, off; get_address_description (ref, &addr); if (addr.base && TREE_CODE (addr.base) == INTEGER_CST) { if (addr.offset) addr.offset = fold_binary_to_constant (PLUS_EXPR, sizetype, addr.offset, fold_convert (sizetype, addr.base)); else addr.offset = addr.base; addr.base = NULL_TREE; changed = true; } if (addr.index && TREE_CODE (addr.index) == INTEGER_CST) { off = addr.index; if (addr.step) { off = fold_binary_to_constant (MULT_EXPR, sizetype, off, addr.step); addr.step = NULL_TREE; } if (addr.offset) { addr.offset = fold_binary_to_constant (PLUS_EXPR, sizetype, addr.offset, off); } else addr.offset = off; addr.index = NULL_TREE; changed = true; } if (!changed) return NULL_TREE; ret = create_mem_ref_raw (TREE_TYPE (ref), NULL_TREE, &addr); if (!ret) return NULL_TREE; copy_mem_ref_info (ret, ref); return ret; }
tree maybe_fold_tmr (tree ref) { struct mem_address addr; bool changed = false; tree ret, off; get_address_description (ref, &addr); if (addr.base && TREE_CODE (addr.base) == INTEGER_CST && !integer_zerop (addr.base)) { addr.offset = fold_binary_to_constant (PLUS_EXPR, TREE_TYPE (addr.offset), addr.offset, addr.base); addr.base = NULL_TREE; changed = true; } if (addr.symbol && TREE_CODE (TREE_OPERAND (addr.symbol, 0)) == MEM_REF) { addr.offset = fold_binary_to_constant (PLUS_EXPR, TREE_TYPE (addr.offset), addr.offset, TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 1)); addr.symbol = TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 0); changed = true; } else if (addr.symbol && handled_component_p (TREE_OPERAND (addr.symbol, 0))) { HOST_WIDE_INT offset; addr.symbol = build_fold_addr_expr (get_addr_base_and_unit_offset (TREE_OPERAND (addr.symbol, 0), &offset)); addr.offset = int_const_binop (PLUS_EXPR, addr.offset, size_int (offset)); changed = true; } if (addr.index && TREE_CODE (addr.index) == INTEGER_CST) { off = addr.index; if (addr.step) { off = fold_binary_to_constant (MULT_EXPR, sizetype, off, addr.step); addr.step = NULL_TREE; } addr.offset = fold_binary_to_constant (PLUS_EXPR, TREE_TYPE (addr.offset), addr.offset, off); addr.index = NULL_TREE; changed = true; } if (!changed) return NULL_TREE; /* If we have propagated something into this TARGET_MEM_REF and thus ended up folding it, always create a new TARGET_MEM_REF regardless if it is valid in this for on the target - the propagation result wouldn't be anyway. */ ret = create_mem_ref_raw (TREE_TYPE (ref), TREE_TYPE (addr.offset), &addr, false); copy_mem_ref_info (ret, ref); return ret; }