inline tree do_valueize (tree (*valueize)(tree), tree op) { if (valueize && TREE_CODE (op) == SSA_NAME) return valueize (op); return op; }
inline gimple * get_def (tree (*valueize)(tree), tree name) { if (valueize && ! valueize (name)) return NULL; return SSA_NAME_DEF_STMT (name); }
inline tree do_valueize (tree (*valueize)(tree), tree op) { if (valueize && TREE_CODE (op) == SSA_NAME) { tree tem = valueize (op); if (tem) return tem; } return op; }
static inline tree do_valueize (tree op, tree (*valueize)(tree), bool &valueized) { if (valueize && TREE_CODE (op) == SSA_NAME) { tree tem = valueize (op); if (tem && tem != op) { op = tem; valueized = true; } } return op; }
bool gimple_simplify (gimple stmt, code_helper *rcode, tree *ops, gimple_seq *seq, tree (*valueize)(tree)) { switch (gimple_code (stmt)) { case GIMPLE_ASSIGN: { enum tree_code code = gimple_assign_rhs_code (stmt); tree type = TREE_TYPE (gimple_assign_lhs (stmt)); switch (gimple_assign_rhs_class (stmt)) { case GIMPLE_SINGLE_RHS: if (code == REALPART_EXPR || code == IMAGPART_EXPR || code == VIEW_CONVERT_EXPR) { tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); if (valueize && TREE_CODE (op0) == SSA_NAME) { tree tem = valueize (op0); if (tem) op0 = tem; } *rcode = code; ops[0] = op0; return gimple_resimplify1 (seq, rcode, type, ops, valueize); } else if (code == BIT_FIELD_REF) { tree rhs1 = gimple_assign_rhs1 (stmt); tree op0 = TREE_OPERAND (rhs1, 0); if (valueize && TREE_CODE (op0) == SSA_NAME) { tree tem = valueize (op0); if (tem) op0 = tem; } *rcode = code; ops[0] = op0; ops[1] = TREE_OPERAND (rhs1, 1); ops[2] = TREE_OPERAND (rhs1, 2); return gimple_resimplify3 (seq, rcode, type, ops, valueize); } else if (code == SSA_NAME && valueize) { tree op0 = gimple_assign_rhs1 (stmt); tree valueized = valueize (op0); if (!valueized || op0 == valueized) return false; ops[0] = valueized; *rcode = TREE_CODE (op0); return true; } break; case GIMPLE_UNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); if (valueize && TREE_CODE (rhs1) == SSA_NAME) { tree tem = valueize (rhs1); if (tem) rhs1 = tem; } *rcode = code; ops[0] = rhs1; return gimple_resimplify1 (seq, rcode, type, ops, valueize); } case GIMPLE_BINARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); if (valueize && TREE_CODE (rhs1) == SSA_NAME) { tree tem = valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); if (valueize && TREE_CODE (rhs2) == SSA_NAME) { tree tem = valueize (rhs2); if (tem) rhs2 = tem; } *rcode = code; ops[0] = rhs1; ops[1] = rhs2; return gimple_resimplify2 (seq, rcode, type, ops, valueize); } case GIMPLE_TERNARY_RHS: { tree rhs1 = gimple_assign_rhs1 (stmt); if (valueize && TREE_CODE (rhs1) == SSA_NAME) { tree tem = valueize (rhs1); if (tem) rhs1 = tem; } tree rhs2 = gimple_assign_rhs2 (stmt); if (valueize && TREE_CODE (rhs2) == SSA_NAME) { tree tem = valueize (rhs2); if (tem) rhs2 = tem; } tree rhs3 = gimple_assign_rhs3 (stmt); if (valueize && TREE_CODE (rhs3) == SSA_NAME) { tree tem = valueize (rhs3); if (tem) rhs3 = tem; } *rcode = code; ops[0] = rhs1; ops[1] = rhs2; ops[2] = rhs3; return gimple_resimplify3 (seq, rcode, type, ops, valueize); } default: gcc_unreachable (); } break; } case GIMPLE_CALL: /* ??? This way we can't simplify calls with side-effects. */ if (gimple_call_lhs (stmt) != NULL_TREE) { tree fn = gimple_call_fn (stmt); /* ??? Internal function support missing. */ if (!fn) return false; if (valueize && TREE_CODE (fn) == SSA_NAME) { tree tem = valueize (fn); if (tem) fn = tem; } if (!fn || TREE_CODE (fn) != ADDR_EXPR || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))) || !gimple_builtin_call_types_compatible_p (stmt, TREE_OPERAND (fn, 0))) return false; tree decl = TREE_OPERAND (fn, 0); tree type = TREE_TYPE (gimple_call_lhs (stmt)); switch (gimple_call_num_args (stmt)) { case 1: { tree arg1 = gimple_call_arg (stmt, 0); if (valueize && TREE_CODE (arg1) == SSA_NAME) { tree tem = valueize (arg1); if (tem) arg1 = tem; } *rcode = DECL_FUNCTION_CODE (decl); ops[0] = arg1; return gimple_resimplify1 (seq, rcode, type, ops, valueize); } case 2: { tree arg1 = gimple_call_arg (stmt, 0); if (valueize && TREE_CODE (arg1) == SSA_NAME) { tree tem = valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); if (valueize && TREE_CODE (arg2) == SSA_NAME) { tree tem = valueize (arg2); if (tem) arg2 = tem; } *rcode = DECL_FUNCTION_CODE (decl); ops[0] = arg1; ops[1] = arg2; return gimple_resimplify2 (seq, rcode, type, ops, valueize); } case 3: { tree arg1 = gimple_call_arg (stmt, 0); if (valueize && TREE_CODE (arg1) == SSA_NAME) { tree tem = valueize (arg1); if (tem) arg1 = tem; } tree arg2 = gimple_call_arg (stmt, 1); if (valueize && TREE_CODE (arg2) == SSA_NAME) { tree tem = valueize (arg2); if (tem) arg2 = tem; } tree arg3 = gimple_call_arg (stmt, 2); if (valueize && TREE_CODE (arg3) == SSA_NAME) { tree tem = valueize (arg3); if (tem) arg3 = tem; } *rcode = DECL_FUNCTION_CODE (decl); ops[0] = arg1; ops[1] = arg2; ops[2] = arg3; return gimple_resimplify3 (seq, rcode, type, ops, valueize); } default: return false; } } break; case GIMPLE_COND: { tree lhs = gimple_cond_lhs (stmt); if (valueize && TREE_CODE (lhs) == SSA_NAME) { tree tem = valueize (lhs); if (tem) lhs = tem; } tree rhs = gimple_cond_rhs (stmt); if (valueize && TREE_CODE (rhs) == SSA_NAME) { tree tem = valueize (rhs); if (tem) rhs = tem; } *rcode = gimple_cond_code (stmt); ops[0] = lhs; ops[1] = rhs; return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize); } default: break; } return false; }