1 /* 2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. 3 * 4 * This file is part of libFirm. 5 * 6 * This file may be distributed and/or modified under the terms of the 7 * GNU General Public License version 2 as published by the Free Software 8 * Foundation and appearing in the file LICENSE.GPL included in the 9 * packaging of this file. 10 * 11 * Licensees holding valid libFirm Professional Edition licenses may use 12 * this file in accordance with the libFirm Commercial License. 13 * Agreement provided with the Software. 14 * 15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE. 18 */ 19 20 /** 21 * @file 22 * @brief Debug macros used in iropt. 23 * @author Goetz Lindenmaier, Michael Beck 24 */ 25 #ifndef FIRM_IR_IROPT_DBG_H 26 #define FIRM_IR_IROPT_DBG_H 27 28 #include "dbginfo_t.h" 29 #include "irhooks.h" 30 #include "firmstat.h" 31 #include "util.h" 32 33 /** 34 * Merge the debug info due to dead block elimination. 35 * 36 * @param oldn the block that it is eliminated 37 * @param n the new node for this block, may be equal to oldn 38 */ 39 #define DBG_OPT_DEAD_BLOCK(oldn, n) \ 40 do { \ 41 hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_DEAD_BLOCK); \ 42 __dbg_info_merge_pair(n, oldn, dbg_dead_code); \ 43 } while(0) 44 45 46 /** 47 * Merge the debug info due to a straightening optimization. 48 * Block oldn is merged with n. 49 * 50 * @param oldn the old block 51 * @param n the new block the merges with oldn 52 */ 53 #define DBG_OPT_STG(oldn, n) \ 54 do { \ 55 ir_node *ons[2]; \ 56 ons[0] = oldn; \ 57 ons[1] = get_Block_cfgpred(oldn, 0); \ 58 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_STG); \ 59 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_straightening); \ 60 } while(0) 61 62 /** 63 * Merge the debug info due to an if simplification. 64 * 65 * @param oldn the old Block 66 * @param proj1 the first ProjX predecessor 67 * @param proj2 the second ProjX predecessor 68 * @param n the new Block 69 */ 70 #define DBG_OPT_IFSIM1(oldn, proj1, proj2, n) \ 71 do { \ 72 ir_node *ons[4]; \ 73 ons[0] = oldn; \ 74 ons[1] = proj1; \ 75 ons[2] = proj2; \ 76 ons[3] = get_Proj_pred(proj1); \ 77 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_IFSIM); \ 78 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_if_simplification); \ 79 } while(0) 80 81 /** 82 * Merge the debug info due to an if simplification. 83 * @param oldn the old Cond 84 * @param n the new Jmp 85 */ 86 #define DBG_OPT_IFSIM2(oldn, n) \ 87 do { \ 88 hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_IFSIM); \ 89 __dbg_info_merge_pair(n, oldn, dbg_if_simplification); \ 90 } while(0) 91 92 /** 93 * Merge the debug info due to an algebraic_simplification. 94 * A node could be evaluated into a Constant. 95 * 96 * @param oldn the node 97 * @param n the new constant holding the value 98 */ 99 #define DBG_OPT_CSTEVAL(oldn, n) \ 100 do { \ 101 hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_CONST_EVAL); \ 102 __dbg_info_merge_pair(n, oldn, dbg_const_eval); \ 103 } while(0) 104 105 /** 106 * Merge the debug info due to an algebraic_simplification. 107 * 108 * @param oldn the old node 109 * @param n the new node replacing oldn 110 * @param flag firm statistics option 111 */ 112 #define DBG_OPT_ALGSIM0(oldn, n, flag) \ 113 do { \ 114 hook_merge_nodes(&n, 1, &oldn, 1, (hook_opt_kind)flag); \ 115 __dbg_info_merge_pair(n, oldn, dbg_algebraic_simplification); \ 116 } while(0) 117 118 /** 119 * Merge the debug info due to an algebraic_simplification. 120 * 121 * @param oldn the old node 122 * @param a a predecessor of oldn 123 * @param b a predecessor of oldn 124 * @param n the new node replacing oldn 125 * @param flag firm statistics option 126 */ 127 #define DBG_OPT_ALGSIM1(oldn, a, b, n, flag) \ 128 do { \ 129 ir_node *ons[3]; \ 130 ons[0] = oldn; \ 131 ons[1] = a; \ 132 ons[2] = b; \ 133 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), (hook_opt_kind)flag); \ 134 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_algebraic_simplification); \ 135 } while(0) 136 137 /** 138 * Merge the debug info due to an algebraic_simplification. 139 * 140 * @param oldn the old node 141 * @param pred the predecessor of oldn 142 * @param n the new node replacing oldn 143 * @param flag firm statistics option 144 */ 145 #define DBG_OPT_ALGSIM2(oldn, pred, n, flag) \ 146 do { \ 147 ir_node *ons[3]; \ 148 ons[0] = oldn; \ 149 ons[1] = pred; \ 150 ons[2] = n; \ 151 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), (hook_opt_kind)flag); \ 152 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_algebraic_simplification); \ 153 } while(0) 154 155 /** 156 * Merge the debug info due to an algebraic_simplification. 157 */ 158 #define DBG_OPT_ALGSIM3(oldn, a, n, flag) \ 159 do { \ 160 ir_node *ons[2]; \ 161 ons[0] = oldn; \ 162 ons[1] = a; \ 163 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), flag); \ 164 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_algebraic_simplification); \ 165 } while(0) 166 167 /** 168 * Merge the debug info due to a Phi optimization. 169 * A Phi node was replaced by one of its input (the only meaningful) 170 * 171 * @param phi the Phi node that will be replaced 172 * @param n in Phi Input that will replace Phi 173 */ 174 #define DBG_OPT_PHI(phi, n) \ 175 do { \ 176 hook_merge_nodes(&n, 1, &phi, 1, HOOK_OPT_PHI); \ 177 __dbg_info_merge_sets(&n, 1, &phi, 1, dbg_opt_ssa); \ 178 } while(0) 179 180 181 /** 182 * Merge the debug info due to a Sync optimization. 183 * A Sync node was replaced by one of its input (the only meaningful) 184 * 185 * @param sync the Sync node that will be replaced 186 * @param n in Sync Input that will replace Sync 187 */ 188 #define DBG_OPT_SYNC(sync, n) \ 189 do { \ 190 hook_merge_nodes(&n, 1, &sync, 1, HOOK_OPT_SYNC); \ 191 __dbg_info_merge_sets(&n, 1, &sync, 1, dbg_opt_ssa); \ 192 } while(0) 193 194 195 /** 196 * Merge the debug info due to Write-after-Write optimization: 197 * Store oldst will be removed, because Store st overwrites it. 198 * 199 * @param oldst the old store that will be removed 200 * @param st the other store that overwrites oldst 201 */ 202 #define DBG_OPT_WAW(oldst, st) \ 203 do { \ 204 ir_node *ons[2]; \ 205 ons[0] = oldst; \ 206 ons[1] = st; \ 207 hook_merge_nodes(&st, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_WAW); \ 208 __dbg_info_merge_sets(&st, 1, ons, ARRAY_SIZE(ons), dbg_write_after_write); \ 209 } while(0) 210 211 /** 212 * Merge the debug info due to Write-after-Read optimization: 213 * A store will be removed because it rite a value just read back. 214 * 215 * @param store the store that will be removed 216 * @param load the load that produces the value that store will write back 217 */ 218 #define DBG_OPT_WAR(store, load) \ 219 do { \ 220 ir_node *ons[2]; \ 221 ons[0] = store; \ 222 ons[1] = load; \ 223 hook_merge_nodes(&load, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_WAR); \ 224 __dbg_info_merge_sets(&load, 1, ons, ARRAY_SIZE(ons), dbg_write_after_read); \ 225 } while(0) 226 227 /** 228 * Merge the debug info due to Read-after-Write optimization: 229 * A load will be replaced by a value that was just stored. 230 * 231 * @param load the load that will be replaced 232 * @param value the value that will replace the load 233 */ 234 #define DBG_OPT_RAW(load, value) \ 235 do { \ 236 ir_node *ons[2]; \ 237 ons[0] = load; \ 238 ons[1] = value; \ 239 hook_merge_nodes(&value, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_RAW); \ 240 __dbg_info_merge_sets(&value, 1, ons, ARRAY_SIZE(ons), dbg_read_after_write); \ 241 } while(0) 242 243 /** 244 * Merge the debug info due to Read-after-Read optimization: 245 * Load oldld will be replace by a reference to Load ld. 246 * 247 * @param oldld the old load that can be replaced 248 * @param ld the load that produces the same values 249 */ 250 #define DBG_OPT_RAR(oldld, ld) \ 251 do { \ 252 ir_node *ons[2]; \ 253 ons[0] = oldld; \ 254 ons[1] = ld; \ 255 hook_merge_nodes(&ld, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_RAR); \ 256 __dbg_info_merge_sets(&ld, 1, ons, ARRAY_SIZE(ons), dbg_read_after_read); \ 257 } while(0) 258 259 /** 260 * Merge the debug info due to Read-a-Const optimization: 261 * Load ld will be replace by a Constant if the value that 262 * will be loaded is known and immutable. 263 * 264 * @param ld the load 265 * @param c the constant value that will replace the load's result 266 */ 267 #define DBG_OPT_RC(ld, c) \ 268 do { \ 269 ir_node *ons[2]; \ 270 ons[0] = ld; \ 271 ons[1] = c; \ 272 hook_merge_nodes(&c, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_RC); \ 273 __dbg_info_merge_sets(&ld, 1, ons, ARRAY_SIZE(ons), dbg_read_a_const); \ 274 } while(0) 275 276 /** 277 * Merge the debug info after a tuple optimization. 278 * a Proj(Tuple) is replaced by the associated tuple value. 279 * 280 * @param proj the Proj node 281 * @param tuple the Tuple node 282 * @param n the Proj(Tuple) value 283 */ 284 #define DBG_OPT_TUPLE(proj, tuple, n) \ 285 do { \ 286 ir_node *ons[3]; \ 287 ons[0] = proj; \ 288 ons[1] = tuple; \ 289 ons[2] = n; \ 290 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_TUPLE); \ 291 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_opt_auxnode); \ 292 } while(0) 293 294 /** 295 * Merge the debug info after an Id optimization. 296 * An Id node was replaced by its non-Id predecessor. 297 * 298 * @param id the Id node 299 * @param n the predecessor 300 */ 301 #define DBG_OPT_ID(id, n) \ 302 do { \ 303 ir_node *ons[2]; \ 304 ons[0] = id; \ 305 ons[1] = n; \ 306 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_ID); \ 307 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_opt_auxnode); \ 308 } while(0) 309 310 /** 311 * Merge the debug info due to common-subexpression elimination. 312 * 313 * @param oldn the old node 314 * @param n the node that replaces oldn 315 */ 316 #define DBG_OPT_CSE(oldn, n) \ 317 do { \ 318 ir_node *ons[2]; \ 319 ons[0] = oldn; \ 320 ons[1] = n; \ 321 hook_merge_nodes(&n, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_CSE); \ 322 __dbg_info_merge_sets(&n, 1, ons, ARRAY_SIZE(ons), dbg_opt_cse); \ 323 } while(0) 324 325 /** 326 * Merge the debug info due to polymorphic call optimization. 327 * A Sel node was replaced by a constant. 328 * 329 * @param sel the Sel node that will be replaced. 330 * @param c the constant node that replaces sel 331 */ 332 #define DBG_OPT_POLY(sel, c) \ 333 do { \ 334 ir_node *ons[3]; \ 335 ons[0] = sel; \ 336 ons[1] = skip_Proj(get_Sel_ptr(sel)); \ 337 ons[2] = c; \ 338 hook_merge_nodes(&c, 1, ons, ARRAY_SIZE(ons), HOOK_OPT_POLY_CALL); \ 339 __dbg_info_merge_sets(&c, 1, ons, ARRAY_SIZE(ons), dbg_rem_poly_call); \ 340 } while(0) 341 342 /** 343 * A node was replaced by another node due to a Confirmation. 344 * 345 * @param oldn the old node 346 * @param n the new node 347 */ 348 #define DBG_OPT_CONFIRM(oldn, n) \ 349 do { \ 350 hook_merge_nodes(&n, 1, &oldn, 1, HOOK_OPT_CONFIRM); \ 351 __dbg_info_merge_pair(n, oldn, dbg_opt_confirm); \ 352 } while(0) 353 354 /** 355 * A node was replaced by a constant due to a Confimation. 356 * 357 * @param oldn the old node 358 * @param c the new constant node 359 */ 360 #define DBG_OPT_CONFIRM_C(oldn, c) \ 361 do { \ 362 hook_merge_nodes(&c, 1, &oldn, 1, HOOK_OPT_CONFIRM_C); \ 363 __dbg_info_merge_pair(c, oldn, dbg_opt_confirm); \ 364 } while(0) 365 366 /** 367 * A exception exdge was removed due to a Confirmation prove. 368 * 369 * @param oldn the old node 370 */ 371 #define DBG_OPT_EXC_REM(oldn) \ 372 do { \ 373 hook_merge_nodes(NULL, 0, &oldn, 1, HOOK_OPT_EXC_REM); \ 374 } while(0) 375 376 /** 377 * A node could be evaluated to a value due to a Confirm. 378 * This will lead to a constant evaluation. 379 * 380 * @param n the node that could be evaluated 381 */ 382 #define DBG_EVAL_CONFIRM(n) \ 383 do { \ 384 hook_merge_nodes(NULL, 0, (ir_node**)&n, 1, HOOK_OPT_CONFIRM_E); \ 385 } while(0) 386 387 /** 388 * Merge the debug info due to a GVN-PRE result. 389 * 390 * @param oldn the old node 391 * @param n the new node replacing oldn 392 * @param flag firm statistics option 393 */ 394 #define DBG_OPT_GVN_PRE(oldn, n, flag) \ 395 do { \ 396 hook_merge_nodes(&n, 1, &oldn, 1, (hook_opt_kind)flag); \ 397 __dbg_info_merge_pair(n, oldn, dbg_gvn_pre); \ 398 } while(0) 399 400 /** 401 * Merge the debug info due to a combo result. 402 * 403 * @param oldn the old node 404 * @param n the new node replacing oldn 405 * @param flag firm statistics option 406 */ 407 #define DBG_OPT_COMBO(oldn, n, flag) \ 408 do { \ 409 hook_merge_nodes(&n, 1, &oldn, 1, (hook_opt_kind)flag); \ 410 __dbg_info_merge_pair(n, oldn, dbg_combo); \ 411 } while(0) 412 413 /** 414 * Merge the debug info due to a jump threading result. 415 * 416 * @param oldn the old control flow node 417 * @param n the new control flow node replacing oldn 418 */ 419 #define DBG_OPT_JUMPTHREADING(oldn, n) \ 420 do { \ 421 hook_merge_nodes(&n, 1, &oldn, 1, (hook_opt_kind)FS_OPT_JUMPTHREADING); \ 422 __dbg_info_merge_pair(n, oldn, dbg_jumpthreading); \ 423 } while(0) 424 425 #endif 426