diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-12 21:35:19 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-12 21:35:19 +0000 |
commit | a3ed3761ca3501faa64e92e7e38d32fdb146a0ff (patch) | |
tree | ba5ea342196989db654db06103cbefccccbe76fc /gcc/tree-ssa-address.c | |
parent | 64c0b1493f1490fe1a0171227b57429410dc15f2 (diff) | |
download | gcc-a3ed3761ca3501faa64e92e7e38d32fdb146a0ff.tar.gz |
2011-10-12 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 179863 using svnmerge.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@179867 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-address.c')
-rw-r--r-- | gcc/tree-ssa-address.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index 34479b33ae1..cf131578d2d 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -832,6 +832,68 @@ copy_mem_ref_info (tree to, tree from) TREE_THIS_VOLATILE (to) = TREE_THIS_VOLATILE (from); } +/* Copies the reference information from OLD_REF to NEW_REF, where + NEW_REF should be either a MEM_REF or a TARGET_MEM_REF. */ + +void +copy_ref_info (tree new_ref, tree old_ref) +{ + tree new_ptr_base = NULL_TREE; + + gcc_assert (TREE_CODE (new_ref) == MEM_REF + || TREE_CODE (new_ref) == TARGET_MEM_REF); + + TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref); + TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref); + + new_ptr_base = TREE_OPERAND (new_ref, 0); + + /* We can transfer points-to information from an old pointer + or decl base to the new one. */ + if (new_ptr_base + && TREE_CODE (new_ptr_base) == SSA_NAME + && !SSA_NAME_PTR_INFO (new_ptr_base)) + { + tree base = get_base_address (old_ref); + if (!base) + ; + else if ((TREE_CODE (base) == MEM_REF + || TREE_CODE (base) == TARGET_MEM_REF) + && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME + && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))) + { + struct ptr_info_def *new_pi; + duplicate_ssa_name_ptr_info + (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); + new_pi = SSA_NAME_PTR_INFO (new_ptr_base); + /* We have to be careful about transfering alignment information. */ + if (TREE_CODE (old_ref) == MEM_REF + && !(TREE_CODE (new_ref) == TARGET_MEM_REF + && (TMR_INDEX2 (new_ref) + || (TMR_STEP (new_ref) + && (TREE_INT_CST_LOW (TMR_STEP (new_ref)) + < new_pi->align))))) + { + new_pi->misalign += double_int_sub (mem_ref_offset (old_ref), + mem_ref_offset (new_ref)).low; + new_pi->misalign &= (new_pi->align - 1); + } + else + { + new_pi->align = 1; + new_pi->misalign = 0; + } + } + else if (TREE_CODE (base) == VAR_DECL + || TREE_CODE (base) == PARM_DECL + || TREE_CODE (base) == RESULT_DECL) + { + struct ptr_info_def *pi = get_ptr_info (new_ptr_base); + pt_solution_set_var (&pi->pt, base); + } + } +} + /* Move constants in target_mem_ref REF to offset. Returns the new target mem ref if anything changes, NULL_TREE otherwise. */ |