1/* 2 * Copyright © 2013 Intel Corporation 3 * 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: 10 * 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 13 * Software. 14 * 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 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "ir.h" 25 26/** 27 * Helper for checking equality when one instruction might be NULL, since you 28 * can't access a's vtable in that case. 29 */ 30static bool 31possibly_null_equals(const ir_instruction *a, const ir_instruction *b, 32 enum ir_node_type ignore) 33{ 34 if (!a || !b) 35 return !a && !b; 36 37 return a->equals(b, ignore); 38} 39 40/** 41 * The base equality function: Return not equal for anything we don't know 42 * about. 43 */ 44bool 45ir_instruction::equals(const ir_instruction *, enum ir_node_type) const 46{ 47 return false; 48} 49 50bool 51ir_constant::equals(const ir_instruction *ir, enum ir_node_type) const 52{ 53 const ir_constant *other = ir->as_constant(); 54 if (!other) 55 return false; 56 57 if (type != other->type) 58 return false; 59 60 for (unsigned i = 0; i < type->components(); i++) { 61 if (type->is_double()) { 62 if (value.d[i] != other->value.d[i]) 63 return false; 64 } else { 65 if (value.u[i] != other->value.u[i]) 66 return false; 67 } 68 } 69 70 return true; 71} 72 73bool 74ir_dereference_variable::equals(const ir_instruction *ir, 75 enum ir_node_type) const 76{ 77 const ir_dereference_variable *other = ir->as_dereference_variable(); 78 if (!other) 79 return false; 80 81 return var == other->var; 82} 83 84bool 85ir_dereference_array::equals(const ir_instruction *ir, 86 enum ir_node_type ignore) const 87{ 88 const ir_dereference_array *other = ir->as_dereference_array(); 89 if (!other) 90 return false; 91 92 if (type != other->type) 93 return false; 94 95 if (!array->equals(other->array, ignore)) 96 return false; 97 98 if (!array_index->equals(other->array_index, ignore)) 99 return false; 100 101 return true; 102} 103 104bool 105ir_swizzle::equals(const ir_instruction *ir, 106 enum ir_node_type ignore) const 107{ 108 const ir_swizzle *other = ir->as_swizzle(); 109 if (!other) 110 return false; 111 112 if (type != other->type) 113 return false; 114 115 if (ignore != ir_type_swizzle) { 116 if (mask.x != other->mask.x || 117 mask.y != other->mask.y || 118 mask.z != other->mask.z || 119 mask.w != other->mask.w) { 120 return false; 121 } 122 } 123 124 return val->equals(other->val, ignore); 125} 126 127bool 128ir_texture::equals(const ir_instruction *ir, enum ir_node_type ignore) const 129{ 130 const ir_texture *other = ir->as_texture(); 131 if (!other) 132 return false; 133 134 if (type != other->type) 135 return false; 136 137 if (op != other->op) 138 return false; 139 140 if (is_sparse != other->is_sparse) 141 return false; 142 143 if (!possibly_null_equals(coordinate, other->coordinate, ignore)) 144 return false; 145 146 if (!possibly_null_equals(projector, other->projector, ignore)) 147 return false; 148 149 if (!possibly_null_equals(shadow_comparator, other->shadow_comparator, ignore)) 150 return false; 151 152 if (!possibly_null_equals(offset, other->offset, ignore)) 153 return false; 154 155 if (!possibly_null_equals(clamp, other->clamp, ignore)) 156 return false; 157 158 if (!sampler->equals(other->sampler, ignore)) 159 return false; 160 161 switch (op) { 162 case ir_tex: 163 case ir_lod: 164 case ir_query_levels: 165 case ir_texture_samples: 166 case ir_samples_identical: 167 break; 168 case ir_txb: 169 if (!lod_info.bias->equals(other->lod_info.bias, ignore)) 170 return false; 171 break; 172 case ir_txl: 173 case ir_txf: 174 case ir_txs: 175 if (!lod_info.lod->equals(other->lod_info.lod, ignore)) 176 return false; 177 break; 178 case ir_txd: 179 if (!lod_info.grad.dPdx->equals(other->lod_info.grad.dPdx, ignore) || 180 !lod_info.grad.dPdy->equals(other->lod_info.grad.dPdy, ignore)) 181 return false; 182 break; 183 case ir_txf_ms: 184 if (!lod_info.sample_index->equals(other->lod_info.sample_index, ignore)) 185 return false; 186 break; 187 case ir_tg4: 188 if (!lod_info.component->equals(other->lod_info.component, ignore)) 189 return false; 190 break; 191 default: 192 assert(!"Unrecognized texture op"); 193 } 194 195 return true; 196} 197 198bool 199ir_expression::equals(const ir_instruction *ir, enum ir_node_type ignore) const 200{ 201 const ir_expression *other = ir->as_expression(); 202 if (!other) 203 return false; 204 205 if (type != other->type) 206 return false; 207 208 if (operation != other->operation) 209 return false; 210 211 for (unsigned i = 0; i < num_operands; i++) { 212 if (!operands[i]->equals(other->operands[i], ignore)) 213 return false; 214 } 215 216 return true; 217} 218