static tree get_real_ref_rhs (tree expr) { switch (TREE_CODE (expr)) { case SSA_NAME: { /* Given a self-assign statement, say foo.x = foo.x, the IR (after SSA) looks like: D.1797_14 = foo.x; foo.x ={v} D.1797_14; So if the rhs EXPR is an SSA_NAME of a temp variable, e.g. D.1797_14, we need to grab the rhs of its SSA def statement (i.e. foo.x). */ tree vdecl = SSA_NAME_VAR (expr); if ((!vdecl || DECL_ARTIFICIAL (vdecl)) && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) { gimple def_stmt = SSA_NAME_DEF_STMT (expr); /* We are only interested in an assignment with a single rhs operand because if it is not, the original assignment will not possibly be a self-assignment. */ if (gimple_assign_single_p (def_stmt)) return get_real_ref_rhs (gimple_assign_rhs1 (def_stmt)); else return NULL_TREE; } else return vdecl; } case VAR_DECL: case PARM_DECL: case FIELD_DECL: case COMPONENT_REF: case MEM_REF: case ARRAY_REF: return expr; default: return NULL_TREE; } }
static tree get_non_ssa_expr (tree expr) { if (!expr) return NULL_TREE; switch (TREE_CODE (expr)) { case VAR_DECL: case PARM_DECL: case FIELD_DECL: { if (DECL_NAME (expr)) return expr; else return NULL_TREE; } case COMPONENT_REF: { tree base, orig_base = TREE_OPERAND (expr, 0); tree component, orig_component = TREE_OPERAND (expr, 1); base = get_non_ssa_expr (orig_base); if (!base) return NULL_TREE; component = get_non_ssa_expr (orig_component); if (!component) return NULL_TREE; /* If either BASE or COMPONENT is converted, build a new component reference tree. */ if (base != orig_base || component != orig_component) return build3 (COMPONENT_REF, TREE_TYPE (component), base, component, NULL_TREE); else return expr; } case MEM_REF: { tree orig_base = TREE_OPERAND (expr, 0); if (TREE_CODE (orig_base) == SSA_NAME) { tree base = get_non_ssa_expr (orig_base); if (!base) return NULL_TREE; return fold_build2 (MEM_REF, TREE_TYPE (expr), base, TREE_OPERAND (expr, 1)); } return expr; } case ARRAY_REF: { tree array, orig_array = TREE_OPERAND (expr, 0); tree index, orig_index = TREE_OPERAND (expr, 1); array = get_non_ssa_expr (orig_array); if (!array) return NULL_TREE; index = get_non_ssa_expr (orig_index); if (!index) return NULL_TREE; /* If either ARRAY or INDEX is converted, build a new array reference tree. */ if (array != orig_array || index != orig_index) return build4 (ARRAY_REF, TREE_TYPE (expr), array, index, TREE_OPERAND (expr, 2), TREE_OPERAND (expr, 3)); else return expr; } case SSA_NAME: { tree vdecl = SSA_NAME_VAR (expr); if ((!vdecl || DECL_ARTIFICIAL (vdecl)) && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) { gimple def_stmt = SSA_NAME_DEF_STMT (expr); if (gimple_assign_single_p (def_stmt)) vdecl = gimple_assign_rhs1 (def_stmt); } return get_non_ssa_expr (vdecl); } case INTEGER_CST: return expr; default: /* Return NULL_TREE for any other kind of tree nodes. */ return NULL_TREE; } }