1 /* 2 * Copyright © 2018 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 DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #include "nir.h" 25 #include "nir_builder.h" 26 #include "nir_deref.h" 27 28 struct match_node { 29 /* Note: these fields are only valid for leaf nodes */ 30 31 unsigned next_array_idx; 32 int src_wildcard_idx; 33 nir_deref_path first_src_path; 34 35 /* The index of the first read of the source path that's part of the copy 36 * we're matching. If the last write to the source path is after this, we 37 * would get a different result from reading it at the end and we can't 38 * emit the copy. 39 */ 40 unsigned first_src_read; 41 42 /* The last time there was a write to this node. */ 43 unsigned last_overwritten; 44 45 /* The last time there was a write to this node which successfully advanced 46 * next_array_idx. This helps us catch any intervening aliased writes. 47 */ 48 unsigned last_successful_write; 49 50 unsigned num_children; 51 struct match_node *children[]; 52 }; 53 54 struct match_state { 55 /* Map from nir_variable * -> match_node */ 56 struct hash_table *var_nodes; 57 /* Map from cast nir_deref_instr * -> match_node */ 58 struct hash_table *cast_nodes; 59 60 unsigned cur_instr; 61 62 nir_builder builder; 63 64 void *dead_ctx; 65 }; 66 67 static struct match_node * create_match_node(const struct glsl_type * type,struct match_state * state)68 create_match_node(const struct glsl_type *type, struct match_state *state) 69 { 70 unsigned num_children = 0; 71 if (glsl_type_is_array_or_matrix(type)) { 72 /* One for wildcards */ 73 num_children = glsl_get_length(type) + 1; 74 } else if (glsl_type_is_struct_or_ifc(type)) { 75 num_children = glsl_get_length(type); 76 } 77 78 struct match_node *node = rzalloc_size(state->dead_ctx, 79 sizeof(struct match_node) + 80 num_children * sizeof(struct match_node *)); 81 node->num_children = num_children; 82 node->src_wildcard_idx = -1; 83 node->first_src_read = UINT32_MAX; 84 return node; 85 } 86 87 static struct match_node * node_for_deref(nir_deref_instr * instr,struct match_node * parent,struct match_state * state)88 node_for_deref(nir_deref_instr *instr, struct match_node *parent, 89 struct match_state *state) 90 { 91 unsigned idx; 92 switch (instr->deref_type) { 93 case nir_deref_type_var: { 94 struct hash_entry *entry = 95 _mesa_hash_table_search(state->var_nodes, instr->var); 96 if (entry) { 97 return entry->data; 98 } else { 99 struct match_node *node = create_match_node(instr->type, state); 100 _mesa_hash_table_insert(state->var_nodes, instr->var, node); 101 return node; 102 } 103 } 104 105 case nir_deref_type_cast: { 106 struct hash_entry *entry = 107 _mesa_hash_table_search(state->cast_nodes, instr); 108 if (entry) { 109 return entry->data; 110 } else { 111 struct match_node *node = create_match_node(instr->type, state); 112 _mesa_hash_table_insert(state->cast_nodes, instr, node); 113 return node; 114 } 115 } 116 117 case nir_deref_type_array_wildcard: 118 idx = parent->num_children - 1; 119 break; 120 121 case nir_deref_type_array: 122 if (nir_src_is_const(instr->arr.index)) { 123 idx = nir_src_as_uint(instr->arr.index); 124 assert(idx < parent->num_children - 1); 125 } else { 126 idx = parent->num_children - 1; 127 } 128 break; 129 130 case nir_deref_type_struct: 131 idx = instr->strct.index; 132 break; 133 134 default: 135 unreachable("bad deref type"); 136 } 137 138 assert(idx < parent->num_children); 139 if (parent->children[idx]) { 140 return parent->children[idx]; 141 } else { 142 struct match_node *node = create_match_node(instr->type, state); 143 parent->children[idx] = node; 144 return node; 145 } 146 } 147 148 static struct match_node * node_for_wildcard(const struct glsl_type * type,struct match_node * parent,struct match_state * state)149 node_for_wildcard(const struct glsl_type *type, struct match_node *parent, 150 struct match_state *state) 151 { 152 assert(glsl_type_is_array_or_matrix(type)); 153 unsigned idx = glsl_get_length(type); 154 155 if (parent->children[idx]) { 156 return parent->children[idx]; 157 } else { 158 struct match_node *node = 159 create_match_node(glsl_get_array_element(type), state); 160 parent->children[idx] = node; 161 return node; 162 } 163 } 164 165 static struct match_node * node_for_path(nir_deref_path * path,struct match_state * state)166 node_for_path(nir_deref_path *path, struct match_state *state) 167 { 168 struct match_node *node = NULL; 169 for (nir_deref_instr **instr = path->path; *instr; instr++) 170 node = node_for_deref(*instr, node, state); 171 172 return node; 173 } 174 175 static struct match_node * node_for_path_with_wildcard(nir_deref_path * path,unsigned wildcard_idx,struct match_state * state)176 node_for_path_with_wildcard(nir_deref_path *path, unsigned wildcard_idx, 177 struct match_state *state) 178 { 179 struct match_node *node = NULL; 180 unsigned idx = 0; 181 for (nir_deref_instr **instr = path->path; *instr; instr++, idx++) { 182 if (idx == wildcard_idx) 183 node = node_for_wildcard((*(instr - 1))->type, node, state); 184 else 185 node = node_for_deref(*instr, node, state); 186 } 187 188 return node; 189 } 190 191 typedef void (*match_cb)(struct match_node *, struct match_state *); 192 193 static void _foreach_child(match_cb cb,struct match_node * node,struct match_state * state)194 _foreach_child(match_cb cb, struct match_node *node, struct match_state *state) 195 { 196 if (node->num_children == 0) { 197 cb(node, state); 198 } else { 199 for (unsigned i = 0; i < node->num_children; i++) { 200 if (node->children[i]) 201 _foreach_child(cb, node->children[i], state); 202 } 203 } 204 } 205 206 static void _foreach_aliasing(nir_deref_instr ** deref,match_cb cb,struct match_node * node,struct match_state * state)207 _foreach_aliasing(nir_deref_instr **deref, match_cb cb, 208 struct match_node *node, struct match_state *state) 209 { 210 if (*deref == NULL) { 211 cb(node, state); 212 return; 213 } 214 215 switch ((*deref)->deref_type) { 216 case nir_deref_type_struct: { 217 struct match_node *child = node->children[(*deref)->strct.index]; 218 if (child) 219 _foreach_aliasing(deref + 1, cb, child, state); 220 return; 221 } 222 223 case nir_deref_type_array: 224 case nir_deref_type_array_wildcard: { 225 if ((*deref)->deref_type == nir_deref_type_array_wildcard || 226 !nir_src_is_const((*deref)->arr.index)) { 227 /* This access may touch any index, so we have to visit all of 228 * them. 229 */ 230 for (unsigned i = 0; i < node->num_children; i++) { 231 if (node->children[i]) 232 _foreach_aliasing(deref + 1, cb, node->children[i], state); 233 } 234 } else { 235 /* Visit the wildcard entry if any */ 236 if (node->children[node->num_children - 1]) { 237 _foreach_aliasing(deref + 1, cb, 238 node->children[node->num_children - 1], state); 239 } 240 241 unsigned index = nir_src_as_uint((*deref)->arr.index); 242 /* Check that the index is in-bounds */ 243 if (index < node->num_children - 1 && node->children[index]) 244 _foreach_aliasing(deref + 1, cb, node->children[index], state); 245 } 246 return; 247 } 248 249 case nir_deref_type_cast: 250 _foreach_child(cb, node, state); 251 return; 252 253 default: 254 unreachable("bad deref type"); 255 } 256 } 257 258 /* Given a deref path, find all the leaf deref nodes that alias it. */ 259 260 static void foreach_aliasing_node(nir_deref_path * path,match_cb cb,struct match_state * state)261 foreach_aliasing_node(nir_deref_path *path, 262 match_cb cb, 263 struct match_state *state) 264 { 265 if (path->path[0]->deref_type == nir_deref_type_var) { 266 struct hash_entry *entry = _mesa_hash_table_search(state->var_nodes, 267 path->path[0]->var); 268 if (entry) 269 _foreach_aliasing(&path->path[1], cb, entry->data, state); 270 271 hash_table_foreach(state->cast_nodes, entry) 272 _foreach_child(cb, entry->data, state); 273 } else { 274 /* Casts automatically alias anything that isn't a cast */ 275 assert(path->path[0]->deref_type == nir_deref_type_cast); 276 hash_table_foreach(state->var_nodes, entry) 277 _foreach_child(cb, entry->data, state); 278 279 /* Casts alias other casts if the casts are different or if they're the 280 * same and the path from the cast may alias as per the usual rules. 281 */ 282 hash_table_foreach(state->cast_nodes, entry) { 283 const nir_deref_instr *cast = entry->key; 284 assert(cast->deref_type == nir_deref_type_cast); 285 if (cast == path->path[0]) 286 _foreach_aliasing(&path->path[1], cb, entry->data, state); 287 else 288 _foreach_child(cb, entry->data, state); 289 } 290 } 291 } 292 293 static nir_deref_instr * build_wildcard_deref(nir_builder * b,nir_deref_path * path,unsigned wildcard_idx)294 build_wildcard_deref(nir_builder *b, nir_deref_path *path, 295 unsigned wildcard_idx) 296 { 297 assert(path->path[wildcard_idx]->deref_type == nir_deref_type_array); 298 299 nir_deref_instr *tail = 300 nir_build_deref_array_wildcard(b, path->path[wildcard_idx - 1]); 301 302 for (unsigned i = wildcard_idx + 1; path->path[i]; i++) 303 tail = nir_build_deref_follower(b, tail, path->path[i]); 304 305 return tail; 306 } 307 308 static void clobber(struct match_node * node,struct match_state * state)309 clobber(struct match_node *node, struct match_state *state) 310 { 311 node->last_overwritten = state->cur_instr; 312 } 313 314 static bool try_match_deref(nir_deref_path * base_path,int * path_array_idx,nir_deref_path * deref_path,int arr_idx,nir_deref_instr * dst)315 try_match_deref(nir_deref_path *base_path, int *path_array_idx, 316 nir_deref_path *deref_path, int arr_idx, 317 nir_deref_instr *dst) 318 { 319 for (int i = 0; ; i++) { 320 nir_deref_instr *b = base_path->path[i]; 321 nir_deref_instr *d = deref_path->path[i]; 322 /* They have to be the same length */ 323 if ((b == NULL) != (d == NULL)) 324 return false; 325 326 if (b == NULL) 327 break; 328 329 /* This can happen if one is a deref_array and the other a wildcard */ 330 if (b->deref_type != d->deref_type) 331 return false;; 332 333 switch (b->deref_type) { 334 case nir_deref_type_var: 335 if (b->var != d->var) 336 return false; 337 continue; 338 339 case nir_deref_type_array: 340 assert(b->arr.index.is_ssa && d->arr.index.is_ssa); 341 const bool const_b_idx = nir_src_is_const(b->arr.index); 342 const bool const_d_idx = nir_src_is_const(d->arr.index); 343 const unsigned b_idx = const_b_idx ? nir_src_as_uint(b->arr.index) : 0; 344 const unsigned d_idx = const_d_idx ? nir_src_as_uint(d->arr.index) : 0; 345 346 /* If we don't have an index into the path yet or if this entry in 347 * the path is at the array index, see if this is a candidate. We're 348 * looking for an index which is zero in the base deref and arr_idx 349 * in the search deref and has a matching array size. 350 */ 351 if ((*path_array_idx < 0 || *path_array_idx == i) && 352 const_b_idx && b_idx == 0 && 353 const_d_idx && d_idx == arr_idx && 354 glsl_get_length(nir_deref_instr_parent(b)->type) == 355 glsl_get_length(nir_deref_instr_parent(dst)->type)) { 356 *path_array_idx = i; 357 continue; 358 } 359 360 /* We're at the array index but not a candidate */ 361 if (*path_array_idx == i) 362 return false; 363 364 /* If we're not the path array index, we must match exactly. We 365 * could probably just compare SSA values and trust in copy 366 * propagation but doing it ourselves means this pass can run a bit 367 * earlier. 368 */ 369 if (b->arr.index.ssa == d->arr.index.ssa || 370 (const_b_idx && const_d_idx && b_idx == d_idx)) 371 continue; 372 373 return false; 374 375 case nir_deref_type_array_wildcard: 376 continue; 377 378 case nir_deref_type_struct: 379 if (b->strct.index != d->strct.index) 380 return false; 381 continue; 382 383 default: 384 unreachable("Invalid deref type in a path"); 385 } 386 } 387 388 /* If we got here without failing, we've matched. However, it isn't an 389 * array match unless we found an altered array index. 390 */ 391 return *path_array_idx > 0; 392 } 393 394 static void handle_read(nir_deref_instr * src,struct match_state * state)395 handle_read(nir_deref_instr *src, struct match_state *state) 396 { 397 /* We only need to create an entry for sources that might be used to form 398 * an array copy. Hence no indirects or indexing into a vector. 399 */ 400 if (nir_deref_instr_has_indirect(src) || 401 nir_deref_instr_is_known_out_of_bounds(src) || 402 (src->deref_type == nir_deref_type_array && 403 glsl_type_is_vector(nir_src_as_deref(src->parent)->type))) 404 return; 405 406 nir_deref_path src_path; 407 nir_deref_path_init(&src_path, src, state->dead_ctx); 408 409 /* Create a node for this source if it doesn't exist. The point of this is 410 * to know which nodes aliasing a given store we actually need to care 411 * about, to avoid creating an excessive amount of nodes. 412 */ 413 node_for_path(&src_path, state); 414 } 415 416 /* The core implementation, which is used for both copies and writes. Return 417 * true if a copy is created. 418 */ 419 static bool handle_write(nir_deref_instr * dst,nir_deref_instr * src,unsigned write_index,unsigned read_index,struct match_state * state)420 handle_write(nir_deref_instr *dst, nir_deref_instr *src, 421 unsigned write_index, unsigned read_index, 422 struct match_state *state) 423 { 424 nir_builder *b = &state->builder; 425 426 nir_deref_path dst_path; 427 nir_deref_path_init(&dst_path, dst, state->dead_ctx); 428 429 unsigned idx = 0; 430 for (nir_deref_instr **instr = dst_path.path; *instr; instr++, idx++) { 431 if ((*instr)->deref_type != nir_deref_type_array) 432 continue; 433 434 /* Get the entry where the index is replaced by a wildcard, so that we 435 * hopefully can keep matching an array copy. 436 */ 437 struct match_node *dst_node = 438 node_for_path_with_wildcard(&dst_path, idx, state); 439 440 if (!src) 441 goto reset; 442 443 if (nir_src_as_uint((*instr)->arr.index) != dst_node->next_array_idx) 444 goto reset; 445 446 if (dst_node->next_array_idx == 0) { 447 /* At this point there may be multiple source indices which are zero, 448 * so we can't pin down the actual source index. Just store it and 449 * move on. 450 */ 451 nir_deref_path_init(&dst_node->first_src_path, src, state->dead_ctx); 452 } else { 453 nir_deref_path src_path; 454 nir_deref_path_init(&src_path, src, state->dead_ctx); 455 bool result = try_match_deref(&dst_node->first_src_path, 456 &dst_node->src_wildcard_idx, 457 &src_path, dst_node->next_array_idx, 458 *instr); 459 nir_deref_path_finish(&src_path); 460 if (!result) 461 goto reset; 462 } 463 464 /* Check if an aliasing write clobbered the array after the last normal 465 * write. For example, with a sequence like this: 466 * 467 * dst[0][*] = src[0][*]; 468 * dst[0][0] = 0; // invalidates the array copy dst[*][*] = src[*][*] 469 * dst[1][*] = src[1][*]; 470 * 471 * Note that the second write wouldn't reset the entry for dst[*][*] 472 * by itself, but it'll be caught by this check when processing the 473 * third copy. 474 */ 475 if (dst_node->last_successful_write < dst_node->last_overwritten) 476 goto reset; 477 478 dst_node->last_successful_write = write_index; 479 480 /* In this case we've successfully processed an array element. Check if 481 * this is the last, so that we can emit an array copy. 482 */ 483 dst_node->next_array_idx++; 484 dst_node->first_src_read = MIN2(dst_node->first_src_read, read_index); 485 if (dst_node->next_array_idx > 1 && 486 dst_node->next_array_idx == glsl_get_length((*(instr - 1))->type)) { 487 /* Make sure that nothing was overwritten. */ 488 struct match_node *src_node = 489 node_for_path_with_wildcard(&dst_node->first_src_path, 490 dst_node->src_wildcard_idx, 491 state); 492 493 if (src_node->last_overwritten <= dst_node->first_src_read) { 494 nir_copy_deref(b, build_wildcard_deref(b, &dst_path, idx), 495 build_wildcard_deref(b, &dst_node->first_src_path, 496 dst_node->src_wildcard_idx)); 497 foreach_aliasing_node(&dst_path, clobber, state); 498 return true; 499 } 500 } else { 501 continue; 502 } 503 504 reset: 505 dst_node->next_array_idx = 0; 506 dst_node->src_wildcard_idx = -1; 507 dst_node->last_successful_write = 0; 508 dst_node->first_src_read = UINT32_MAX; 509 } 510 511 /* Mark everything aliasing dst_path as clobbered. This needs to happen 512 * last since in the loop above we need to know what last clobbered 513 * dst_node and this overwrites that. 514 */ 515 foreach_aliasing_node(&dst_path, clobber, state); 516 517 return false; 518 } 519 520 static bool opt_find_array_copies_block(nir_builder * b,nir_block * block,struct match_state * state)521 opt_find_array_copies_block(nir_builder *b, nir_block *block, 522 struct match_state *state) 523 { 524 bool progress = false; 525 526 unsigned next_index = 0; 527 528 _mesa_hash_table_clear(state->var_nodes, NULL); 529 _mesa_hash_table_clear(state->cast_nodes, NULL); 530 531 nir_foreach_instr(instr, block) { 532 if (instr->type != nir_instr_type_intrinsic) 533 continue; 534 535 /* Index the instructions before we do anything else. */ 536 instr->index = next_index++; 537 538 /* Save the index of this instruction */ 539 state->cur_instr = instr->index; 540 541 nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 542 543 if (intrin->intrinsic == nir_intrinsic_load_deref) { 544 handle_read(nir_src_as_deref(intrin->src[0]), state); 545 continue; 546 } 547 548 if (intrin->intrinsic != nir_intrinsic_copy_deref && 549 intrin->intrinsic != nir_intrinsic_store_deref) 550 continue; 551 552 nir_deref_instr *dst_deref = nir_src_as_deref(intrin->src[0]); 553 554 /* The destination must be local. If we see a non-local store, we 555 * continue on because it won't affect local stores or read-only 556 * variables. 557 */ 558 if (!nir_deref_mode_may_be(dst_deref, nir_var_function_temp)) 559 continue; 560 561 if (!nir_deref_mode_must_be(dst_deref, nir_var_function_temp)) { 562 /* This only happens if we have something that might be a local store 563 * but we don't know. In this case, clear everything. 564 */ 565 nir_deref_path dst_path; 566 nir_deref_path_init(&dst_path, dst_deref, state->dead_ctx); 567 foreach_aliasing_node(&dst_path, clobber, state); 568 continue; 569 } 570 571 /* If there are any known out-of-bounds writes, then we can just skip 572 * this write as it's undefined and won't contribute to building up an 573 * array copy anyways. 574 */ 575 if (nir_deref_instr_is_known_out_of_bounds(dst_deref)) 576 continue; 577 578 nir_deref_instr *src_deref; 579 unsigned load_index = 0; 580 if (intrin->intrinsic == nir_intrinsic_copy_deref) { 581 src_deref = nir_src_as_deref(intrin->src[1]); 582 load_index = intrin->instr.index; 583 } else { 584 assert(intrin->intrinsic == nir_intrinsic_store_deref); 585 nir_intrinsic_instr *load = nir_src_as_intrinsic(intrin->src[1]); 586 if (load == NULL || load->intrinsic != nir_intrinsic_load_deref) { 587 src_deref = NULL; 588 } else { 589 src_deref = nir_src_as_deref(load->src[0]); 590 load_index = load->instr.index; 591 } 592 593 if (nir_intrinsic_write_mask(intrin) != 594 (1 << glsl_get_components(dst_deref->type)) - 1) { 595 src_deref = NULL; 596 } 597 } 598 599 /* The source must be either local or something that's guaranteed to be 600 * read-only. 601 */ 602 if (src_deref && 603 !nir_deref_mode_must_be(src_deref, nir_var_function_temp | 604 nir_var_read_only_modes)) { 605 src_deref = NULL; 606 } 607 608 /* There must be no indirects in the source or destination and no known 609 * out-of-bounds accesses in the source, and the copy must be fully 610 * qualified, or else we can't build up the array copy. We handled 611 * out-of-bounds accesses to the dest above. The types must match, since 612 * copy_deref currently can't bitcast mismatched deref types. 613 */ 614 if (src_deref && 615 (nir_deref_instr_has_indirect(src_deref) || 616 nir_deref_instr_is_known_out_of_bounds(src_deref) || 617 nir_deref_instr_has_indirect(dst_deref) || 618 !glsl_type_is_vector_or_scalar(src_deref->type) || 619 glsl_get_bare_type(src_deref->type) != 620 glsl_get_bare_type(dst_deref->type))) { 621 src_deref = NULL; 622 } 623 624 state->builder.cursor = nir_after_instr(instr); 625 progress |= handle_write(dst_deref, src_deref, instr->index, 626 load_index, state); 627 } 628 629 return progress; 630 } 631 632 static bool opt_find_array_copies_impl(nir_function_impl * impl)633 opt_find_array_copies_impl(nir_function_impl *impl) 634 { 635 nir_builder b; 636 nir_builder_init(&b, impl); 637 638 bool progress = false; 639 640 struct match_state s; 641 s.dead_ctx = ralloc_context(NULL); 642 s.var_nodes = _mesa_pointer_hash_table_create(s.dead_ctx); 643 s.cast_nodes = _mesa_pointer_hash_table_create(s.dead_ctx); 644 nir_builder_init(&s.builder, impl); 645 646 nir_foreach_block(block, impl) { 647 if (opt_find_array_copies_block(&b, block, &s)) 648 progress = true; 649 } 650 651 ralloc_free(s.dead_ctx); 652 653 if (progress) { 654 nir_metadata_preserve(impl, nir_metadata_block_index | 655 nir_metadata_dominance); 656 } else { 657 nir_metadata_preserve(impl, nir_metadata_all); 658 } 659 660 return progress; 661 } 662 663 /** 664 * This peephole optimization looks for a series of load/store_deref or 665 * copy_deref instructions that copy an array from one variable to another and 666 * turns it into a copy_deref that copies the entire array. The pattern it 667 * looks for is extremely specific but it's good enough to pick up on the 668 * input array copies in DXVK and should also be able to pick up the sequence 669 * generated by spirv_to_nir for a OpLoad of a large composite followed by 670 * OpStore. 671 * 672 * TODO: Support out-of-order copies. 673 */ 674 bool nir_opt_find_array_copies(nir_shader * shader)675 nir_opt_find_array_copies(nir_shader *shader) 676 { 677 bool progress = false; 678 679 nir_foreach_function(function, shader) { 680 if (function->impl && opt_find_array_copies_impl(function->impl)) 681 progress = true; 682 } 683 684 return progress; 685 } 686