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 */ 30 static bool 31 possibly_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 */ 44 bool 45 ir_instruction::equals(const ir_instruction *, enum ir_node_type) const 46 { 47 return false; 48 } 49 50 bool 51 ir_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 73 bool 74 ir_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 84 bool 85 ir_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 104 bool 105 ir_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 127 bool 128 ir_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 (!possibly_null_equals(coordinate, other->coordinate, ignore)) 141 return false; 142 143 if (!possibly_null_equals(projector, other->projector, ignore)) 144 return false; 145 146 if (!possibly_null_equals(shadow_comparator, other->shadow_comparator, ignore)) 147 return false; 148 149 if (!possibly_null_equals(offset, other->offset, ignore)) 150 return false; 151 152 if (!sampler->equals(other->sampler, ignore)) 153 return false; 154 155 switch (op) { 156 case ir_tex: 157 case ir_lod: 158 case ir_query_levels: 159 case ir_texture_samples: 160 case ir_samples_identical: 161 break; 162 case ir_txb: 163 if (!lod_info.bias->equals(other->lod_info.bias, ignore)) 164 return false; 165 break; 166 case ir_txl: 167 case ir_txf: 168 case ir_txs: 169 if (!lod_info.lod->equals(other->lod_info.lod, ignore)) 170 return false; 171 break; 172 case ir_txd: 173 if (!lod_info.grad.dPdx->equals(other->lod_info.grad.dPdx, ignore) || 174 !lod_info.grad.dPdy->equals(other->lod_info.grad.dPdy, ignore)) 175 return false; 176 break; 177 case ir_txf_ms: 178 if (!lod_info.sample_index->equals(other->lod_info.sample_index, ignore)) 179 return false; 180 break; 181 case ir_tg4: 182 if (!lod_info.component->equals(other->lod_info.component, ignore)) 183 return false; 184 break; 185 default: 186 assert(!"Unrecognized texture op"); 187 } 188 189 return true; 190 } 191 192 bool 193 ir_expression::equals(const ir_instruction *ir, enum ir_node_type ignore) const 194 { 195 const ir_expression *other = ir->as_expression(); 196 if (!other) 197 return false; 198 199 if (type != other->type) 200 return false; 201 202 if (operation != other->operation) 203 return false; 204 205 for (unsigned i = 0; i < num_operands; i++) { 206 if (!operands[i]->equals(other->operands[i], ignore)) 207 return false; 208 } 209 210 return true; 211 } 212