2 * Copyright © 2013 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 /** @file brw_fs_peephole_predicated_break.cpp
29 * Loops are often structured as
39 * This peephole pass removes the IF and ENDIF instructions and predicates the
40 * BREAK, dropping two instructions from the loop body.
44 fs_visitor::opt_peephole_predicated_break()
46 bool progress
= false;
48 cfg_t
cfg(&instructions
);
50 for (int b
= 0; b
< cfg
.num_blocks
; b
++) {
51 bblock_t
*block
= cfg
.blocks
[b
];
53 /* BREAK and CONTINUE instructions, by definition, can only be found at
54 * the ends of basic blocks.
56 fs_inst
*inst
= (fs_inst
*) block
->end
;
57 if (inst
->opcode
!= BRW_OPCODE_BREAK
&& inst
->opcode
!= BRW_OPCODE_CONTINUE
)
60 fs_inst
*if_inst
= (fs_inst
*) inst
->prev
;
61 if (if_inst
->opcode
!= BRW_OPCODE_IF
)
64 fs_inst
*endif_inst
= (fs_inst
*) inst
->next
;
65 if (endif_inst
->opcode
!= BRW_OPCODE_ENDIF
)
68 /* For Sandybridge with IF with embedded comparison we need to emit an
69 * instruction to set the flag register.
71 if (brw
->gen
== 6 && if_inst
->conditional_mod
) {
72 fs_inst
*cmp_inst
= CMP(reg_null_d
, if_inst
->src
[0], if_inst
->src
[1],
73 if_inst
->conditional_mod
);
74 if_inst
->insert_before(cmp_inst
);
75 inst
->predicate
= BRW_PREDICATE_NORMAL
;
77 inst
->predicate
= if_inst
->predicate
;
78 inst
->predicate_inverse
= if_inst
->predicate_inverse
;
84 /* By removing the ENDIF instruction we removed a basic block. Skip over
85 * it for the next iteration.
93 invalidate_live_intervals();