17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2020-2021 Collabora Ltd. 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 * Authors (Collabora): 247ec681f3Smrg * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> 257ec681f3Smrg */ 267ec681f3Smrg 277ec681f3Smrg#ifndef __BI_TEST_H 287ec681f3Smrg#define __BI_TEST_H 297ec681f3Smrg 307ec681f3Smrg#include <stdio.h> 317ec681f3Smrg#include <inttypes.h> 327ec681f3Smrg#include "compiler.h" 337ec681f3Smrg 347ec681f3Smrg/* Helpers for unit testing */ 357ec681f3Smrg#define TEST_END(nr_pass, nr_fail) \ 367ec681f3Smrg printf("Passed %u/%u tests.\n", nr_pass, nr_pass + nr_fail); \ 377ec681f3Smrg return nr_fail ? 1 : 0; 387ec681f3Smrg 397ec681f3Smrg/* Helper to generate a bi_builder suitable for creating test instructions */ 407ec681f3Smrgstatic inline bi_builder * 417ec681f3Smrgbit_builder(void *memctx) 427ec681f3Smrg{ 437ec681f3Smrg bi_context *ctx = rzalloc(memctx, bi_context); 447ec681f3Smrg list_inithead(&ctx->blocks); 457ec681f3Smrg 467ec681f3Smrg bi_block *blk = rzalloc(ctx, bi_block); 477ec681f3Smrg 487ec681f3Smrg blk->predecessors = _mesa_set_create(blk, 497ec681f3Smrg _mesa_hash_pointer, 507ec681f3Smrg _mesa_key_pointer_equal); 517ec681f3Smrg 527ec681f3Smrg list_addtail(&blk->link, &ctx->blocks); 537ec681f3Smrg list_inithead(&blk->instructions); 547ec681f3Smrg 557ec681f3Smrg bi_builder *b = rzalloc(memctx, bi_builder); 567ec681f3Smrg b->shader = ctx; 577ec681f3Smrg b->cursor = bi_after_block(blk); 587ec681f3Smrg return b; 597ec681f3Smrg} 607ec681f3Smrg 617ec681f3Smrg/* Helper to compare for logical equality of instructions. Need to skip over 627ec681f3Smrg * the link, guaranteed to be first. After that we can compare raw data. */ 637ec681f3Smrgstatic inline bool 647ec681f3Smrgbit_instr_equal(bi_instr *A, bi_instr *B) 657ec681f3Smrg{ 667ec681f3Smrg return memcmp((uint8_t *) A + sizeof(struct list_head), 677ec681f3Smrg (uint8_t *) B + sizeof(struct list_head), 687ec681f3Smrg sizeof(bi_instr) - sizeof(struct list_head)) == 0; 697ec681f3Smrg} 707ec681f3Smrg 717ec681f3Smrgstatic inline bool 727ec681f3Smrgbit_block_equal(bi_block *A, bi_block *B) 737ec681f3Smrg{ 747ec681f3Smrg if (list_length(&A->instructions) != list_length(&B->instructions)) 757ec681f3Smrg return false; 767ec681f3Smrg 777ec681f3Smrg list_pair_for_each_entry(bi_instr, insA, insB, 787ec681f3Smrg &A->instructions, &B->instructions, link) { 797ec681f3Smrg if (!bit_instr_equal(insA, insB)) 807ec681f3Smrg return false; 817ec681f3Smrg } 827ec681f3Smrg 837ec681f3Smrg return true; 847ec681f3Smrg} 857ec681f3Smrg 867ec681f3Smrgstatic inline bool 877ec681f3Smrgbit_shader_equal(bi_context *A, bi_context *B) 887ec681f3Smrg{ 897ec681f3Smrg if (list_length(&A->blocks) != list_length(&B->blocks)) 907ec681f3Smrg return false; 917ec681f3Smrg 927ec681f3Smrg list_pair_for_each_entry(bi_block, blockA, blockB, 937ec681f3Smrg &A->blocks, &B->blocks, link) { 947ec681f3Smrg if (!bit_block_equal(blockA, blockB)) 957ec681f3Smrg return false; 967ec681f3Smrg } 977ec681f3Smrg 987ec681f3Smrg return true; 997ec681f3Smrg} 1007ec681f3Smrg 1017ec681f3Smrg#define INSTRUCTION_CASE(instr, expected, CB) do { \ 1027ec681f3Smrg bi_instr *left = instr; \ 1037ec681f3Smrg bi_instr *right = expected; \ 1047ec681f3Smrg CB(b, left); \ 1057ec681f3Smrg if (bit_instr_equal(left, right)) { \ 1067ec681f3Smrg nr_pass++; \ 1077ec681f3Smrg } else { \ 1087ec681f3Smrg fprintf(stderr, "Incorrect optimization\n"); \ 1097ec681f3Smrg bi_print_instr(instr, stderr); \ 1107ec681f3Smrg bi_print_instr(left, stderr); \ 1117ec681f3Smrg bi_print_instr(right, stderr); \ 1127ec681f3Smrg fprintf(stderr, "\n"); \ 1137ec681f3Smrg nr_fail++; \ 1147ec681f3Smrg } \ 1157ec681f3Smrg} while(0) 1167ec681f3Smrg 1177ec681f3Smrg#define BIT_ASSERT(condition) do { \ 1187ec681f3Smrg if (condition) { \ 1197ec681f3Smrg nr_pass++; \ 1207ec681f3Smrg } else { \ 1217ec681f3Smrg fprintf(stderr, "Assertion failed: %s\n", #condition); \ 1227ec681f3Smrg nr_fail++; \ 1237ec681f3Smrg } \ 1247ec681f3Smrg} while(0) 1257ec681f3Smrg 1267ec681f3Smrg#endif 127