diff options
Diffstat (limited to 'gcc/tree-dfa.c')
-rw-r--r-- | gcc/tree-dfa.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 461e2cf..10fd41e 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -878,6 +878,37 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset, } goto done; + case TARGET_MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TMR_SYMBOL (exp)) + { + /* Via the variable index we can reach the whole object. */ + if (TMR_INDEX (exp)) + { + exp = TMR_SYMBOL (exp); + bit_offset = 0; + maxsize = -1; + goto done; + } + if (integer_zerop (TMR_OFFSET (exp))) + exp = TMR_SYMBOL (exp); + else + { + double_int off = mem_ref_offset (exp); + off = double_int_lshift (off, + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + off = double_int_add (off, shwi_to_double_int (bit_offset)); + if (double_int_fits_in_shwi_p (off)) + { + bit_offset = double_int_to_shwi (off); + exp = TMR_SYMBOL (exp); + } + } + } + goto done; + default: goto done; } @@ -1010,6 +1041,22 @@ get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset) } goto done; + case TARGET_MEM_REF: + /* Hand back the decl for MEM[&decl, off]. */ + if (TMR_SYMBOL (exp)) + { + if (TMR_SYMBOL (exp)) + return NULL_TREE; + if (!integer_zerop (TMR_OFFSET (exp))) + { + double_int off = mem_ref_offset (exp); + gcc_assert (off.high == -1 || off.high == 0); + byte_offset += double_int_to_shwi (off); + } + exp = TMR_SYMBOL (exp); + } + goto done; + default: goto done; } |