17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2020 Google, Inc. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 207ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 217ec681f3Smrg * SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#include <stdlib.h> 257ec681f3Smrg 267ec681f3Smrg#include "util/ralloc.h" 277ec681f3Smrg 287ec681f3Smrg#include "ir3.h" 297ec681f3Smrg 307ec681f3Smrgstruct ir3_validate_ctx { 317ec681f3Smrg struct ir3 *ir; 327ec681f3Smrg 337ec681f3Smrg /* Current block being validated: */ 347ec681f3Smrg struct ir3_block *current_block; 357ec681f3Smrg 367ec681f3Smrg /* Current instruction being validated: */ 377ec681f3Smrg struct ir3_instruction *current_instr; 387ec681f3Smrg 397ec681f3Smrg /* Set of instructions found so far, used to validate that we 407ec681f3Smrg * don't have SSA uses that occure before def's 417ec681f3Smrg */ 427ec681f3Smrg struct set *defs; 437ec681f3Smrg}; 447ec681f3Smrg 457ec681f3Smrgstatic void 467ec681f3Smrgvalidate_error(struct ir3_validate_ctx *ctx, const char *condstr) 477ec681f3Smrg{ 487ec681f3Smrg fprintf(stderr, "validation fail: %s\n", condstr); 497ec681f3Smrg if (ctx->current_instr) { 507ec681f3Smrg fprintf(stderr, " -> for instruction: "); 517ec681f3Smrg ir3_print_instr(ctx->current_instr); 527ec681f3Smrg } else { 537ec681f3Smrg fprintf(stderr, " -> for block%u\n", block_id(ctx->current_block)); 547ec681f3Smrg } 557ec681f3Smrg abort(); 567ec681f3Smrg} 577ec681f3Smrg 587ec681f3Smrg#define validate_assert(ctx, cond) \ 597ec681f3Smrg do { \ 607ec681f3Smrg if (!(cond)) { \ 617ec681f3Smrg validate_error(ctx, #cond); \ 627ec681f3Smrg } \ 637ec681f3Smrg } while (0) 647ec681f3Smrg 657ec681f3Smrgstatic unsigned 667ec681f3Smrgreg_class_flags(struct ir3_register *reg) 677ec681f3Smrg{ 687ec681f3Smrg return reg->flags & (IR3_REG_HALF | IR3_REG_SHARED); 697ec681f3Smrg} 707ec681f3Smrg 717ec681f3Smrgstatic void 727ec681f3Smrgvalidate_src(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr, 737ec681f3Smrg struct ir3_register *reg) 747ec681f3Smrg{ 757ec681f3Smrg if (reg->flags & IR3_REG_IMMED) 767ec681f3Smrg validate_assert(ctx, ir3_valid_immediate(instr, reg->iim_val)); 777ec681f3Smrg 787ec681f3Smrg if (!(reg->flags & IR3_REG_SSA) || !reg->def) 797ec681f3Smrg return; 807ec681f3Smrg 817ec681f3Smrg struct ir3_register *src = reg->def; 827ec681f3Smrg 837ec681f3Smrg validate_assert(ctx, _mesa_set_search(ctx->defs, src->instr)); 847ec681f3Smrg validate_assert(ctx, src->wrmask == reg->wrmask); 857ec681f3Smrg validate_assert(ctx, reg_class_flags(src) == reg_class_flags(reg)); 867ec681f3Smrg 877ec681f3Smrg if (reg->tied) { 887ec681f3Smrg validate_assert(ctx, reg->tied->tied == reg); 897ec681f3Smrg bool found = false; 907ec681f3Smrg foreach_dst (dst, instr) { 917ec681f3Smrg if (dst == reg->tied) { 927ec681f3Smrg found = true; 937ec681f3Smrg break; 947ec681f3Smrg } 957ec681f3Smrg } 967ec681f3Smrg validate_assert(ctx, 977ec681f3Smrg found && "tied register not in the same instruction"); 987ec681f3Smrg } 997ec681f3Smrg} 1007ec681f3Smrg 1017ec681f3Smrg/* phi sources are logically read at the end of the predecessor basic block, 1027ec681f3Smrg * and we have to validate them then in order to correctly validate that the 1037ec681f3Smrg * use comes after the definition for loop phis. 1047ec681f3Smrg */ 1057ec681f3Smrgstatic void 1067ec681f3Smrgvalidate_phi_src(struct ir3_validate_ctx *ctx, struct ir3_block *block, 1077ec681f3Smrg struct ir3_block *pred) 1087ec681f3Smrg{ 1097ec681f3Smrg unsigned pred_idx = ir3_block_get_pred_index(block, pred); 1107ec681f3Smrg 1117ec681f3Smrg foreach_instr (phi, &block->instr_list) { 1127ec681f3Smrg if (phi->opc != OPC_META_PHI) 1137ec681f3Smrg break; 1147ec681f3Smrg 1157ec681f3Smrg ctx->current_instr = phi; 1167ec681f3Smrg validate_assert(ctx, phi->srcs_count == block->predecessors_count); 1177ec681f3Smrg validate_src(ctx, phi, phi->srcs[pred_idx]); 1187ec681f3Smrg } 1197ec681f3Smrg} 1207ec681f3Smrg 1217ec681f3Smrgstatic void 1227ec681f3Smrgvalidate_phi(struct ir3_validate_ctx *ctx, struct ir3_instruction *phi) 1237ec681f3Smrg{ 1247ec681f3Smrg _mesa_set_add(ctx->defs, phi); 1257ec681f3Smrg validate_assert(ctx, phi->dsts_count == 1); 1267ec681f3Smrg validate_assert(ctx, is_dest_gpr(phi->dsts[0])); 1277ec681f3Smrg} 1287ec681f3Smrg 1297ec681f3Smrgstatic void 1307ec681f3Smrgvalidate_dst(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr, 1317ec681f3Smrg struct ir3_register *reg) 1327ec681f3Smrg{ 1337ec681f3Smrg if (reg->tied) { 1347ec681f3Smrg validate_assert(ctx, reg->tied->tied == reg); 1357ec681f3Smrg validate_assert(ctx, reg_class_flags(reg->tied) == reg_class_flags(reg)); 1367ec681f3Smrg validate_assert(ctx, reg->tied->wrmask == reg->wrmask); 1377ec681f3Smrg if (reg->flags & IR3_REG_ARRAY) { 1387ec681f3Smrg validate_assert(ctx, reg->tied->array.base == reg->array.base); 1397ec681f3Smrg validate_assert(ctx, reg->tied->size == reg->size); 1407ec681f3Smrg } 1417ec681f3Smrg bool found = false; 1427ec681f3Smrg foreach_src (src, instr) { 1437ec681f3Smrg if (src == reg->tied) { 1447ec681f3Smrg found = true; 1457ec681f3Smrg break; 1467ec681f3Smrg } 1477ec681f3Smrg } 1487ec681f3Smrg validate_assert(ctx, 1497ec681f3Smrg found && "tied register not in the same instruction"); 1507ec681f3Smrg } 1517ec681f3Smrg 1527ec681f3Smrg if (reg->flags & IR3_REG_SSA) 1537ec681f3Smrg validate_assert(ctx, reg->instr == instr); 1547ec681f3Smrg 1557ec681f3Smrg if (reg->flags & IR3_REG_RELATIV) 1567ec681f3Smrg validate_assert(ctx, instr->address); 1577ec681f3Smrg} 1587ec681f3Smrg 1597ec681f3Smrg#define validate_reg_size(ctx, reg, type) \ 1607ec681f3Smrg validate_assert( \ 1617ec681f3Smrg ctx, type_size(type) == (((reg)->flags & IR3_REG_HALF) ? 16 : 32)) 1627ec681f3Smrg 1637ec681f3Smrgstatic void 1647ec681f3Smrgvalidate_instr(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr) 1657ec681f3Smrg{ 1667ec681f3Smrg struct ir3_register *last_reg = NULL; 1677ec681f3Smrg 1687ec681f3Smrg foreach_src_n (reg, n, instr) { 1697ec681f3Smrg if (reg->flags & IR3_REG_RELATIV) 1707ec681f3Smrg validate_assert(ctx, instr->address); 1717ec681f3Smrg 1727ec681f3Smrg validate_src(ctx, instr, reg); 1737ec681f3Smrg 1747ec681f3Smrg /* Validate that all src's are either half of full. 1757ec681f3Smrg * 1767ec681f3Smrg * Note: tex instructions w/ .s2en are a bit special in that the 1777ec681f3Smrg * tex/samp src reg is half-reg for non-bindless and full for 1787ec681f3Smrg * bindless, irrespective of the precision of other srcs. The 1797ec681f3Smrg * tex/samp src is the first src reg when .s2en is set 1807ec681f3Smrg */ 1817ec681f3Smrg if (reg->tied) { 1827ec681f3Smrg /* must have the same size as the destination, handled in 1837ec681f3Smrg * validate_reg(). 1847ec681f3Smrg */ 1857ec681f3Smrg } else if (reg == instr->address) { 1867ec681f3Smrg validate_assert(ctx, reg->flags & IR3_REG_HALF); 1877ec681f3Smrg } else if ((instr->flags & IR3_INSTR_S2EN) && (n < 2)) { 1887ec681f3Smrg if (n == 0) { 1897ec681f3Smrg if (instr->flags & IR3_INSTR_B) 1907ec681f3Smrg validate_assert(ctx, !(reg->flags & IR3_REG_HALF)); 1917ec681f3Smrg else 1927ec681f3Smrg validate_assert(ctx, reg->flags & IR3_REG_HALF); 1937ec681f3Smrg } 1947ec681f3Smrg } else if (opc_cat(instr->opc) == 1 || opc_cat(instr->opc) == 6) { 1957ec681f3Smrg /* handled below */ 1967ec681f3Smrg } else if (opc_cat(instr->opc) == 0) { 1977ec681f3Smrg /* end/chmask/etc are allowed to have different size sources */ 1987ec681f3Smrg } else if (instr->opc == OPC_META_PARALLEL_COPY) { 1997ec681f3Smrg /* pcopy sources have to match with their destination but can have 2007ec681f3Smrg * different sizes from each other. 2017ec681f3Smrg */ 2027ec681f3Smrg } else if (n > 0) { 2037ec681f3Smrg validate_assert(ctx, (last_reg->flags & IR3_REG_HALF) == 2047ec681f3Smrg (reg->flags & IR3_REG_HALF)); 2057ec681f3Smrg } 2067ec681f3Smrg 2077ec681f3Smrg last_reg = reg; 2087ec681f3Smrg } 2097ec681f3Smrg 2107ec681f3Smrg for (unsigned i = 0; i < instr->dsts_count; i++) { 2117ec681f3Smrg struct ir3_register *reg = instr->dsts[i]; 2127ec681f3Smrg 2137ec681f3Smrg validate_dst(ctx, instr, reg); 2147ec681f3Smrg } 2157ec681f3Smrg 2167ec681f3Smrg _mesa_set_add(ctx->defs, instr); 2177ec681f3Smrg 2187ec681f3Smrg /* Check that src/dst types match the register types, and for 2197ec681f3Smrg * instructions that have different opcodes depending on type, 2207ec681f3Smrg * that the opcodes are correct. 2217ec681f3Smrg */ 2227ec681f3Smrg switch (opc_cat(instr->opc)) { 2237ec681f3Smrg case 1: /* move instructions */ 2247ec681f3Smrg if (instr->opc == OPC_MOVMSK || instr->opc == OPC_BALLOT_MACRO) { 2257ec681f3Smrg validate_assert(ctx, instr->dsts_count == 1); 2267ec681f3Smrg validate_assert(ctx, instr->dsts[0]->flags & IR3_REG_SHARED); 2277ec681f3Smrg validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF)); 2287ec681f3Smrg validate_assert( 2297ec681f3Smrg ctx, util_is_power_of_two_or_zero(instr->dsts[0]->wrmask + 1)); 2307ec681f3Smrg } else if (instr->opc == OPC_ANY_MACRO || instr->opc == OPC_ALL_MACRO || 2317ec681f3Smrg instr->opc == OPC_READ_FIRST_MACRO || 2327ec681f3Smrg instr->opc == OPC_READ_COND_MACRO) { 2337ec681f3Smrg /* nothing yet */ 2347ec681f3Smrg } else if (instr->opc == OPC_ELECT_MACRO) { 2357ec681f3Smrg validate_assert(ctx, instr->dsts_count == 1); 2367ec681f3Smrg validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_SHARED)); 2377ec681f3Smrg } else { 2387ec681f3Smrg foreach_dst (dst, instr) 2397ec681f3Smrg validate_reg_size(ctx, dst, instr->cat1.dst_type); 2407ec681f3Smrg foreach_src (src, instr) { 2417ec681f3Smrg if (!src->tied && src != instr->address) 2427ec681f3Smrg validate_reg_size(ctx, src, instr->cat1.src_type); 2437ec681f3Smrg } 2447ec681f3Smrg 2457ec681f3Smrg switch (instr->opc) { 2467ec681f3Smrg case OPC_SWZ: 2477ec681f3Smrg validate_assert(ctx, instr->srcs_count == 2); 2487ec681f3Smrg validate_assert(ctx, instr->dsts_count == 2); 2497ec681f3Smrg break; 2507ec681f3Smrg case OPC_GAT: 2517ec681f3Smrg validate_assert(ctx, instr->srcs_count == 4); 2527ec681f3Smrg validate_assert(ctx, instr->dsts_count == 1); 2537ec681f3Smrg break; 2547ec681f3Smrg case OPC_SCT: 2557ec681f3Smrg validate_assert(ctx, instr->srcs_count == 1); 2567ec681f3Smrg validate_assert(ctx, instr->dsts_count == 4); 2577ec681f3Smrg break; 2587ec681f3Smrg default: 2597ec681f3Smrg break; 2607ec681f3Smrg } 2617ec681f3Smrg } 2627ec681f3Smrg 2637ec681f3Smrg if (instr->opc != OPC_MOV) 2647ec681f3Smrg validate_assert(ctx, !instr->address); 2657ec681f3Smrg 2667ec681f3Smrg break; 2677ec681f3Smrg case 3: 2687ec681f3Smrg /* Validate that cat3 opc matches the src type. We've already checked 2697ec681f3Smrg * that all the src regs are same type 2707ec681f3Smrg */ 2717ec681f3Smrg if (instr->srcs[0]->flags & IR3_REG_HALF) { 2727ec681f3Smrg validate_assert(ctx, instr->opc == cat3_half_opc(instr->opc)); 2737ec681f3Smrg } else { 2747ec681f3Smrg validate_assert(ctx, instr->opc == cat3_full_opc(instr->opc)); 2757ec681f3Smrg } 2767ec681f3Smrg break; 2777ec681f3Smrg case 4: 2787ec681f3Smrg /* Validate that cat4 opc matches the dst type: */ 2797ec681f3Smrg if (instr->dsts[0]->flags & IR3_REG_HALF) { 2807ec681f3Smrg validate_assert(ctx, instr->opc == cat4_half_opc(instr->opc)); 2817ec681f3Smrg } else { 2827ec681f3Smrg validate_assert(ctx, instr->opc == cat4_full_opc(instr->opc)); 2837ec681f3Smrg } 2847ec681f3Smrg break; 2857ec681f3Smrg case 5: 2867ec681f3Smrg validate_reg_size(ctx, instr->dsts[0], instr->cat5.type); 2877ec681f3Smrg break; 2887ec681f3Smrg case 6: 2897ec681f3Smrg switch (instr->opc) { 2907ec681f3Smrg case OPC_RESINFO: 2917ec681f3Smrg case OPC_RESFMT: 2927ec681f3Smrg validate_reg_size(ctx, instr->dsts[0], instr->cat6.type); 2937ec681f3Smrg validate_reg_size(ctx, instr->srcs[0], instr->cat6.type); 2947ec681f3Smrg break; 2957ec681f3Smrg case OPC_L2G: 2967ec681f3Smrg case OPC_G2L: 2977ec681f3Smrg validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF)); 2987ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 2997ec681f3Smrg break; 3007ec681f3Smrg case OPC_STG: 3017ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 3027ec681f3Smrg validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF)); 3037ec681f3Smrg validate_reg_size(ctx, instr->srcs[2], instr->cat6.type); 3047ec681f3Smrg validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF)); 3057ec681f3Smrg break; 3067ec681f3Smrg case OPC_STG_A: 3077ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 3087ec681f3Smrg validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF)); 3097ec681f3Smrg validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF)); 3107ec681f3Smrg validate_reg_size(ctx, instr->srcs[4], instr->cat6.type); 3117ec681f3Smrg validate_assert(ctx, !(instr->srcs[5]->flags & IR3_REG_HALF)); 3127ec681f3Smrg break; 3137ec681f3Smrg case OPC_STL: 3147ec681f3Smrg case OPC_STP: 3157ec681f3Smrg case OPC_STLW: 3167ec681f3Smrg case OPC_SPILL_MACRO: 3177ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 3187ec681f3Smrg validate_reg_size(ctx, instr->srcs[1], instr->cat6.type); 3197ec681f3Smrg validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF)); 3207ec681f3Smrg break; 3217ec681f3Smrg case OPC_STIB: 3227ec681f3Smrg if (instr->flags & IR3_INSTR_B) { 3237ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 3247ec681f3Smrg validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF)); 3257ec681f3Smrg validate_reg_size(ctx, instr->srcs[2], instr->cat6.type); 3267ec681f3Smrg } else { 3277ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 3287ec681f3Smrg validate_reg_size(ctx, instr->srcs[1], instr->cat6.type); 3297ec681f3Smrg validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF)); 3307ec681f3Smrg } 3317ec681f3Smrg break; 3327ec681f3Smrg default: 3337ec681f3Smrg validate_reg_size(ctx, instr->dsts[0], instr->cat6.type); 3347ec681f3Smrg validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF)); 3357ec681f3Smrg if (instr->srcs_count > 1) 3367ec681f3Smrg validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF)); 3377ec681f3Smrg break; 3387ec681f3Smrg } 3397ec681f3Smrg } 3407ec681f3Smrg 3417ec681f3Smrg if (instr->opc == OPC_META_PARALLEL_COPY) { 3427ec681f3Smrg foreach_src_n (src, n, instr) { 3437ec681f3Smrg validate_assert(ctx, reg_class_flags(src) == 3447ec681f3Smrg reg_class_flags(instr->dsts[n])); 3457ec681f3Smrg } 3467ec681f3Smrg } 3477ec681f3Smrg} 3487ec681f3Smrg 3497ec681f3Smrgstatic bool 3507ec681f3Smrgis_physical_successor(struct ir3_block *block, struct ir3_block *succ) 3517ec681f3Smrg{ 3527ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(block->physical_successors); i++) 3537ec681f3Smrg if (block->physical_successors[i] == succ) 3547ec681f3Smrg return true; 3557ec681f3Smrg return false; 3567ec681f3Smrg} 3577ec681f3Smrg 3587ec681f3Smrgvoid 3597ec681f3Smrgir3_validate(struct ir3 *ir) 3607ec681f3Smrg{ 3617ec681f3Smrg#ifdef NDEBUG 3627ec681f3Smrg#define VALIDATE 0 3637ec681f3Smrg#else 3647ec681f3Smrg#define VALIDATE 1 3657ec681f3Smrg#endif 3667ec681f3Smrg 3677ec681f3Smrg if (!VALIDATE) 3687ec681f3Smrg return; 3697ec681f3Smrg 3707ec681f3Smrg struct ir3_validate_ctx *ctx = ralloc_size(NULL, sizeof(*ctx)); 3717ec681f3Smrg 3727ec681f3Smrg ctx->ir = ir; 3737ec681f3Smrg ctx->defs = _mesa_pointer_set_create(ctx); 3747ec681f3Smrg 3757ec681f3Smrg foreach_block (block, &ir->block_list) { 3767ec681f3Smrg ctx->current_block = block; 3777ec681f3Smrg ctx->current_instr = NULL; 3787ec681f3Smrg 3797ec681f3Smrg /* We require that the first block does not have any predecessors, 3807ec681f3Smrg * which allows us to assume that phi nodes and meta:input's do not 3817ec681f3Smrg * appear in the same basic block. 3827ec681f3Smrg */ 3837ec681f3Smrg validate_assert( 3847ec681f3Smrg ctx, block != ir3_start_block(ir) || block->predecessors_count == 0); 3857ec681f3Smrg 3867ec681f3Smrg struct ir3_instruction *prev = NULL; 3877ec681f3Smrg foreach_instr (instr, &block->instr_list) { 3887ec681f3Smrg ctx->current_instr = instr; 3897ec681f3Smrg if (instr->opc == OPC_META_PHI) { 3907ec681f3Smrg /* phis must be the first in the block */ 3917ec681f3Smrg validate_assert(ctx, prev == NULL || prev->opc == OPC_META_PHI); 3927ec681f3Smrg validate_phi(ctx, instr); 3937ec681f3Smrg } else { 3947ec681f3Smrg validate_instr(ctx, instr); 3957ec681f3Smrg } 3967ec681f3Smrg prev = instr; 3977ec681f3Smrg } 3987ec681f3Smrg 3997ec681f3Smrg for (unsigned i = 0; i < 2; i++) { 4007ec681f3Smrg if (block->successors[i]) { 4017ec681f3Smrg validate_phi_src(ctx, block->successors[i], block); 4027ec681f3Smrg 4037ec681f3Smrg ctx->current_instr = NULL; 4047ec681f3Smrg 4057ec681f3Smrg /* Each logical successor should also be a physical successor: */ 4067ec681f3Smrg validate_assert(ctx, is_physical_successor(block, block->successors[i])); 4077ec681f3Smrg } 4087ec681f3Smrg } 4097ec681f3Smrg 4107ec681f3Smrg validate_assert(ctx, block->successors[0] || !block->successors[1]); 4117ec681f3Smrg validate_assert(ctx, block->physical_successors[0] || !block->physical_successors[1]); 4127ec681f3Smrg } 4137ec681f3Smrg 4147ec681f3Smrg ralloc_free(ctx); 4157ec681f3Smrg} 416