1/* Gimple simplify definitions. 2 3 Copyright (C) 2011-2020 Free Software Foundation, Inc. 4 Contributed by Richard Guenther <rguenther@suse.de> 5 6This file is part of GCC. 7 8GCC is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 3, or (at your option) any later 11version. 12 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License 19along with GCC; see the file COPYING3. If not see 20<http://www.gnu.org/licenses/>. */ 21 22#ifndef GCC_GIMPLE_MATCH_H 23#define GCC_GIMPLE_MATCH_H 24 25 26/* Helper to transparently allow tree codes and builtin function codes 27 exist in one storage entity. */ 28class code_helper 29{ 30public: 31 code_helper () {} 32 code_helper (tree_code code) : rep ((int) code) {} 33 code_helper (combined_fn fn) : rep (-(int) fn) {} 34 operator tree_code () const { return (tree_code) rep; } 35 operator combined_fn () const { return (combined_fn) -rep; } 36 bool is_tree_code () const { return rep > 0; } 37 bool is_fn_code () const { return rep < 0; } 38 int get_rep () const { return rep; } 39private: 40 int rep; 41}; 42 43/* Represents the condition under which an operation should happen, 44 and the value to use otherwise. The condition applies elementwise 45 (as for VEC_COND_EXPR) if the values are vectors. */ 46class gimple_match_cond 47{ 48public: 49 enum uncond { UNCOND }; 50 51 /* Build an unconditional op. */ 52 gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE) {} 53 gimple_match_cond (tree, tree); 54 55 gimple_match_cond any_else () const; 56 57 /* The condition under which the operation occurs, or NULL_TREE 58 if the operation is unconditional. */ 59 tree cond; 60 61 /* The value to use when the condition is false. This is NULL_TREE if 62 the operation is unconditional or if the value doesn't matter. */ 63 tree else_value; 64}; 65 66inline 67gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in) 68 : cond (cond_in), else_value (else_value_in) 69{ 70} 71 72/* Return a gimple_match_cond with the same condition but with an 73 arbitrary ELSE_VALUE. */ 74 75inline gimple_match_cond 76gimple_match_cond::any_else () const 77{ 78 return gimple_match_cond (cond, NULL_TREE); 79} 80 81/* Represents an operation to be simplified, or the result of the 82 simplification. */ 83class gimple_match_op 84{ 85public: 86 gimple_match_op (); 87 gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int); 88 gimple_match_op (const gimple_match_cond &, 89 code_helper, tree, tree); 90 gimple_match_op (const gimple_match_cond &, 91 code_helper, tree, tree, tree); 92 gimple_match_op (const gimple_match_cond &, 93 code_helper, tree, tree, tree, tree); 94 gimple_match_op (const gimple_match_cond &, 95 code_helper, tree, tree, tree, tree, tree); 96 gimple_match_op (const gimple_match_cond &, 97 code_helper, tree, tree, tree, tree, tree, tree); 98 99 void set_op (code_helper, tree, unsigned int); 100 void set_op (code_helper, tree, tree); 101 void set_op (code_helper, tree, tree, tree); 102 void set_op (code_helper, tree, tree, tree, tree); 103 void set_op (code_helper, tree, tree, tree, tree, bool); 104 void set_op (code_helper, tree, tree, tree, tree, tree); 105 void set_op (code_helper, tree, tree, tree, tree, tree, tree); 106 void set_value (tree); 107 108 tree op_or_null (unsigned int) const; 109 110 bool resimplify (gimple_seq *, tree (*)(tree)); 111 112 /* The maximum value of NUM_OPS. */ 113 static const unsigned int MAX_NUM_OPS = 5; 114 115 /* The conditions under which the operation is performed, and the value to 116 use as a fallback. */ 117 gimple_match_cond cond; 118 119 /* The operation being performed. */ 120 code_helper code; 121 122 /* The type of the result. */ 123 tree type; 124 125 /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order 126 from the target order. */ 127 bool reverse; 128 129 /* The number of operands to CODE. */ 130 unsigned int num_ops; 131 132 /* The operands to CODE. Only the first NUM_OPS entries are meaningful. */ 133 tree ops[MAX_NUM_OPS]; 134}; 135 136inline 137gimple_match_op::gimple_match_op () 138 : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false), 139 num_ops (0) 140{ 141} 142 143/* Constructor that takes the condition, code, type and number of 144 operands, but leaves the caller to fill in the operands. */ 145 146inline 147gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in, 148 code_helper code_in, tree type_in, 149 unsigned int num_ops_in) 150 : cond (cond_in), code (code_in), type (type_in), reverse (false), 151 num_ops (num_ops_in) 152{ 153} 154 155/* Constructors for various numbers of operands. */ 156 157inline 158gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in, 159 code_helper code_in, tree type_in, 160 tree op0) 161 : cond (cond_in), code (code_in), type (type_in), reverse (false), 162 num_ops (1) 163{ 164 ops[0] = op0; 165} 166 167inline 168gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in, 169 code_helper code_in, tree type_in, 170 tree op0, tree op1) 171 : cond (cond_in), code (code_in), type (type_in), reverse (false), 172 num_ops (2) 173{ 174 ops[0] = op0; 175 ops[1] = op1; 176} 177 178inline 179gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in, 180 code_helper code_in, tree type_in, 181 tree op0, tree op1, tree op2) 182 : cond (cond_in), code (code_in), type (type_in), reverse (false), 183 num_ops (3) 184{ 185 ops[0] = op0; 186 ops[1] = op1; 187 ops[2] = op2; 188} 189 190inline 191gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in, 192 code_helper code_in, tree type_in, 193 tree op0, tree op1, tree op2, tree op3) 194 : cond (cond_in), code (code_in), type (type_in), reverse (false), 195 num_ops (4) 196{ 197 ops[0] = op0; 198 ops[1] = op1; 199 ops[2] = op2; 200 ops[3] = op3; 201} 202 203inline 204gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in, 205 code_helper code_in, tree type_in, 206 tree op0, tree op1, tree op2, tree op3, 207 tree op4) 208 : cond (cond_in), code (code_in), type (type_in), reverse (false), 209 num_ops (5) 210{ 211 ops[0] = op0; 212 ops[1] = op1; 213 ops[2] = op2; 214 ops[3] = op3; 215 ops[4] = op4; 216} 217 218/* Change the operation performed to CODE_IN, the type of the result to 219 TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs 220 to set the operands itself. */ 221 222inline void 223gimple_match_op::set_op (code_helper code_in, tree type_in, 224 unsigned int num_ops_in) 225{ 226 code = code_in; 227 type = type_in; 228 num_ops = num_ops_in; 229} 230 231/* Functions for changing the operation performed, for various numbers 232 of operands. */ 233 234inline void 235gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0) 236{ 237 code = code_in; 238 type = type_in; 239 num_ops = 1; 240 ops[0] = op0; 241} 242 243inline void 244gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1) 245{ 246 code = code_in; 247 type = type_in; 248 num_ops = 2; 249 ops[0] = op0; 250 ops[1] = op1; 251} 252 253inline void 254gimple_match_op::set_op (code_helper code_in, tree type_in, 255 tree op0, tree op1, tree op2) 256{ 257 code = code_in; 258 type = type_in; 259 num_ops = 3; 260 ops[0] = op0; 261 ops[1] = op1; 262 ops[2] = op2; 263} 264 265inline void 266gimple_match_op::set_op (code_helper code_in, tree type_in, 267 tree op0, tree op1, tree op2, bool reverse_in) 268{ 269 code = code_in; 270 type = type_in; 271 reverse = reverse_in; 272 num_ops = 3; 273 ops[0] = op0; 274 ops[1] = op1; 275 ops[2] = op2; 276} 277 278inline void 279gimple_match_op::set_op (code_helper code_in, tree type_in, 280 tree op0, tree op1, tree op2, tree op3) 281{ 282 code = code_in; 283 type = type_in; 284 num_ops = 4; 285 ops[0] = op0; 286 ops[1] = op1; 287 ops[2] = op2; 288 ops[3] = op3; 289} 290 291inline void 292gimple_match_op::set_op (code_helper code_in, tree type_in, 293 tree op0, tree op1, tree op2, tree op3, tree op4) 294{ 295 code = code_in; 296 type = type_in; 297 num_ops = 5; 298 ops[0] = op0; 299 ops[1] = op1; 300 ops[2] = op2; 301 ops[3] = op3; 302 ops[4] = op4; 303} 304 305/* Set the "operation" to be the single value VALUE, such as a constant 306 or SSA_NAME. */ 307 308inline void 309gimple_match_op::set_value (tree value) 310{ 311 set_op (TREE_CODE (value), TREE_TYPE (value), value); 312} 313 314/* Return the value of operand I, or null if there aren't that many 315 operands. */ 316 317inline tree 318gimple_match_op::op_or_null (unsigned int i) const 319{ 320 return i < num_ops ? ops[i] : NULL_TREE; 321} 322 323/* Return whether OP is a non-expression result and a gimple value. */ 324 325inline bool 326gimple_simplified_result_is_gimple_val (const gimple_match_op *op) 327{ 328 return (op->code.is_tree_code () 329 && (TREE_CODE_LENGTH ((tree_code) op->code) == 0 330 || ((tree_code) op->code) == ADDR_EXPR) 331 && is_gimple_val (op->ops[0])); 332} 333 334extern tree (*mprts_hook) (gimple_match_op *); 335 336bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *, 337 tree (*)(tree), tree (*)(tree)); 338tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *, 339 tree res = NULL_TREE); 340void maybe_build_generic_op (gimple_match_op *); 341 342 343#endif /* GCC_GIMPLE_MATCH_H */ 344