Path: blob/21.2-virgl/src/compiler/nir/nir_loop_analyze.h
4545 views
/*1* Copyright © 2016 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#ifndef NIR_LOOP_ANALYZE_H24#define NIR_LOOP_ANALYZE_H2526#include "nir.h"2728/* Returns true if nir_cf_node contains a jump other than the expected_jump29* parameter.30*/31static inline bool32contains_other_jump(nir_cf_node *node, nir_instr *expected_jump)33{34switch (node->type) {35case nir_cf_node_block: {36nir_instr *lst_instr = nir_block_last_instr(nir_cf_node_as_block(node));3738/* dead_cf should have eliminated any instruction after the first break39*/40nir_foreach_instr(instr, nir_cf_node_as_block(node))41assert(instr->type != nir_instr_type_jump || instr == lst_instr);4243if (lst_instr && lst_instr->type == nir_instr_type_jump &&44lst_instr != expected_jump)45return true;46else47return false;48}49case nir_cf_node_if: {50nir_if *if_stmt = nir_cf_node_as_if(node);5152foreach_list_typed_safe(nir_cf_node, node, node, &if_stmt->then_list) {53if (contains_other_jump(node, expected_jump))54return true;55}5657foreach_list_typed_safe(nir_cf_node, node, node, &if_stmt->else_list) {58if (contains_other_jump(node, expected_jump))59return true;60}6162return false;63}64case nir_cf_node_loop:65return true;6667default:68unreachable("Unhandled cf node type");69}70}7172/* Here we define a trivial if as containing only a single break that must be73* located at the end of either the then or else branch of the top level if,74* there must be no other breaks or any other type of jump. Or we pass NULL75* to break_block the if must contains no jumps at all.76*/77static inline bool78nir_is_trivial_loop_if(nir_if *nif, nir_block *break_block)79{80nir_instr *last_instr = NULL;8182if (break_block) {83last_instr = nir_block_last_instr(break_block);84assert(last_instr && last_instr->type == nir_instr_type_jump &&85nir_instr_as_jump(last_instr)->type == nir_jump_break);86}8788if (contains_other_jump(&nif->cf_node, last_instr))89return false;9091return true;92}9394static inline bool95nir_block_ends_in_break(nir_block *block)96{97if (exec_list_is_empty(&block->instr_list))98return false;99100nir_instr *instr = nir_block_last_instr(block);101return instr->type == nir_instr_type_jump &&102nir_instr_as_jump(instr)->type == nir_jump_break;103}104105#endif /* NIR_LOOP_ANALYZE_H */106107108