Age | Commit message (Expand) | Author | Files | Lines |
2020-09-05 | replace_with_{pseudo,value}() can be tail-calls | Luc Van Oostenryck | 1 | -8/+4 |
2020-09-05 | use replace_with_value() | Luc Van Oostenryck | 1 | -8/+8 |
2020-09-05 | add helper replace_with_value() | Luc Van Oostenryck | 1 | -0/+5 |
2020-08-06 | bad-shift: wait dead code elimination to warn about bad shifts | Luc Van Oostenryck | 1 | -15/+5 |
2018-12-22 | doc: fix list formatting | Luc Van Oostenryck | 1 | -2/+3 |
2018-09-06 | Merge branch 'rem-trivial-phi' into tip | Luc Van Oostenryck | 1 | -19/+44 |
2018-09-01 | trivial-phi: remove more complex trivial phi-nodes | Luc Van Oostenryck | 1 | -2/+17 |
2018-09-01 | trivial-phi: directly return the unique value | Luc Van Oostenryck | 1 | -17/+9 |
2018-09-01 | trivial-phi: use a temp var for the real source | Luc Van Oostenryck | 1 | -2/+7 |
2018-09-01 | trivial-phi: early return | Luc Van Oostenryck | 1 | -1/+1 |
2018-09-01 | trivial-phi: extract trivial_phi() from clean_up_phi() | Luc Van Oostenryck | 1 | -3/+22 |
2018-09-01 | trivial-phi: make clean_up_phi() more sequential | Luc Van Oostenryck | 1 | -4/+5 |
2018-09-01 | move DEF_OPCODE() to header file | Luc Van Oostenryck | 1 | -7/+0 |
2018-08-31 | Merge branch 'opcode' into tip | Luc Van Oostenryck | 1 | -3/+25 |
2018-08-26 | add a function to remove deadborn instructions | Luc Van Oostenryck | 1 | -0/+22 |
2018-08-25 | add a flag for volatile memops | Luc Van Oostenryck | 1 | -1/+1 |
2018-08-25 | symaddr: s/insn->symbol/insn->src/ | Luc Van Oostenryck | 1 | -3/+3 |
2018-08-24 | Merge branches 'optim-trunc-or' and 'optim-mask-shift-or' into tip | Luc Van Oostenryck | 1 | -18/+61 |
2018-08-24 | simplify TRUNC(SHIFT(a | b, S), N) | Luc Van Oostenryck | 1 | -0/+6 |
2018-08-24 | simplify AND(SHIFT(a | b, S), M) | Luc Van Oostenryck | 1 | -0/+18 |
2018-08-23 | prepare simplification of MASK(SHIFT(a | b, S), M) | Luc Van Oostenryck | 1 | -4/+22 |
2018-08-23 | doc: extend simplification notation | Luc Van Oostenryck | 1 | -13/+15 |
2018-08-22 | simplify TRUNC((x & M') | y, N) | Luc Van Oostenryck | 1 | -0/+8 |
2018-08-22 | Merge branches 'optim-shift-and' and 'optim-bitfield' into tip | Luc Van Oostenryck | 1 | -45/+95 |
2018-08-22 | simplify ((x & M) << S) when (M << S) == (-1 << S) | Luc Van Oostenryck | 1 | -0/+2 |
2018-08-22 | simplify ((x & M) << S) when (M << S) == 0 | Luc Van Oostenryck | 1 | -0/+11 |
2018-08-22 | simplify ((x & M) >> S) when (M >> S) == (-1 >> S) | Luc Van Oostenryck | 1 | -0/+2 |
2018-08-22 | simplify ((x & M) >> S) when (M >> S) == 0 | Luc Van Oostenryck | 1 | -1/+5 |
2018-08-22 | use an intermediate mask in simplify_shift() | Luc Van Oostenryck | 1 | -3/+3 |
2018-08-22 | simplify SHL((x & M') | y, S) | Luc Van Oostenryck | 1 | -0/+4 |
2018-08-22 | simplify OP((x | C), K) when (C & M) != C | Luc Van Oostenryck | 1 | -0/+4 |
2018-08-22 | simplify OP((x | C), K) when (C & M) == M | Luc Van Oostenryck | 1 | -0/+4 |
2018-08-22 | simplify OP((x | C), K) when (C & M) == 0 | Luc Van Oostenryck | 1 | -0/+9 |
2018-08-22 | simplify OP(((x & M') | y), K) when (M' & M) != M' | Luc Van Oostenryck | 1 | -0/+5 |
2018-08-22 | simplify OP(((x & M') | y), K) when (M' & M) == M | Luc Van Oostenryck | 1 | -0/+8 |
2018-08-22 | move opcode test inside simplify_mask_or_and() | Luc Van Oostenryck | 1 | -3/+7 |
2018-08-22 | allow simplification of OP(((x & y) | (a & M')), K) | Luc Van Oostenryck | 1 | -2/+5 |
2018-08-22 | switch return order in simplify_mask_or_and() | Luc Van Oostenryck | 1 | -6/+5 |
2018-08-22 | document simplify_mask_or() & simplify_mask_or_and() | Luc Van Oostenryck | 1 | -0/+21 |
2018-08-22 | use better names for simplify_mask_or_and() vars | Luc Van Oostenryck | 1 | -3/+4 |
2018-08-22 | add simplify_mask_or() | Luc Van Oostenryck | 1 | -16/+14 |
2018-08-22 | unify simplify_lsr_or() & simplify_and_or_mask() | Luc Van Oostenryck | 1 | -33/+23 |
2018-08-21 | doc: add doc for simplification notation | Luc Van Oostenryck | 1 | -0/+24 |
2018-08-21 | doc: reword doc for replace_pseudo() | Luc Van Oostenryck | 1 | -1/+1 |
2018-08-21 | doc: convert existing simplify.c doc into ReST autodoc | Luc Van Oostenryck | 1 | -36/+43 |
2018-08-17 | Merge branches 'optim-shl-lsr' and 'optim-trunc-trunc' into tip | Luc Van Oostenryck | 1 | -2/+7 |
2018-08-17 | simplify TRUNC(TRUNC(x)) | Luc Van Oostenryck | 1 | -0/+3 |
2018-08-17 | reorganize simplification of ZEXT(TRUNC(x)) | Luc Van Oostenryck | 1 | -2/+4 |
2018-08-17 | simplify ((x >> S) << S) | Luc Van Oostenryck | 1 | -0/+7 |
2018-08-17 | reorganize shift-shift simplification | Luc Van Oostenryck | 1 | -6/+8 |
2018-08-17 | simpler guard in LSR-SHL simplification | Luc Van Oostenryck | 1 | -3/+1 |
2018-08-08 | Merge branches 'fix-inc-dec-size' and 'optim-mask' into tip | Luc Van Oostenryck | 1 | -7/+85 |
2018-08-08 | simplify (x & M) >> S to (x >> S) & (M >> S) | Luc Van Oostenryck | 1 | -0/+14 |
2018-08-08 | simplify (x << S) >> S into x & (-1 >> S) | Luc Van Oostenryck | 1 | -0/+11 |
2018-08-08 | simplify ((x & M) | y) >> S to (y >> S) when (M >> S) == 0 | Luc Van Oostenryck | 1 | -0/+24 |
2018-08-08 | simplify ((x & M') | y ) & M into (y & M) when (M' & M) == 0 | Luc Van Oostenryck | 1 | -0/+23 |
2018-08-08 | reorg code for shift-shift simplification | Luc Van Oostenryck | 1 | -5/+10 |
2018-08-07 | use multi_users() instead on nbr_users() | Luc Van Oostenryck | 1 | -3/+3 |
2018-08-07 | Merge branch 'fix-logical-extra' into tip | Luc Van Oostenryck | 1 | -1/+52 |
2018-08-07 | avoid infinite simplification loops of the second kind | Luc Van Oostenryck | 1 | -2/+3 |
2018-08-06 | simplify AND(SETCC(x,y), M) | Luc Van Oostenryck | 1 | -0/+5 |
2018-08-06 | simplify TRUNC(SETCC(x,y), N) | Luc Van Oostenryck | 1 | -0/+2 |
2018-08-06 | simplify SEXT(SETCC(x,y), N) | Luc Van Oostenryck | 1 | -0/+4 |
2018-08-06 | simplify ZEXT(SETCC(x,y), N) | Luc Van Oostenryck | 1 | -0/+13 |
2018-08-06 | simplify SETNE(TRUNC(x,N),{0,1}) | Luc Van Oostenryck | 1 | -0/+17 |
2018-08-06 | simplify SETNE(AND(X,1),0) to AND(X,1) | Luc Van Oostenryck | 1 | -0/+10 |
2018-08-06 | fix size corruption when simplifing 'x != 0' to 'x' | Luc Van Oostenryck | 1 | -1/+1 |
2018-08-04 | Merge branch 'list-optims' (early part) into tip | Luc Van Oostenryck | 1 | -2/+2 |
2018-07-28 | Merge branch 'optim-setne' into tip | Luc Van Oostenryck | 1 | -15/+21 |
2018-07-28 | simplify 'x != 0' or 'x == 1' to 'x' | Luc Van Oostenryck | 1 | -0/+8 |
2018-07-28 | simplify SET{EQ,NE}(SEXT(x, N),{0,1}) | Luc Van Oostenryck | 1 | -1/+5 |
2018-07-28 | simplify SET{EQ,NE}(ZEXT(x, N),{0,1}) | Luc Van Oostenryck | 1 | -10/+7 |
2018-07-25 | cleanup of simplify_seteq_setne(): remove tmp vars | Luc Van Oostenryck | 1 | -5/+2 |
2018-07-25 | Merge branch 'optim-cast' into tip | Luc Van Oostenryck | 1 | -11/+105 |
2018-07-25 | Merge branch 'optim-shift' into tip | Luc Van Oostenryck | 1 | -9/+114 |
2018-07-25 | shift: simplify ASR(ZEXT(X, N), C) | Luc Van Oostenryck | 1 | -0/+10 |
2018-07-25 | shift: avoid simplification of ASR(LSR(x,0),N) | Luc Van Oostenryck | 1 | -1/+1 |
2018-07-25 | shift: simplify ASR(LSR(x,N),N') | Luc Van Oostenryck | 1 | -1/+4 |
2018-07-25 | shift: simplify LSR(LSR(x,N),N') & friends | Luc Van Oostenryck | 1 | -1/+46 |
2018-07-25 | add ptr_list_multiple() | Luc Van Oostenryck | 1 | -1/+1 |
2018-07-25 | add ptr_list_empty() | Luc Van Oostenryck | 1 | -1/+1 |
2018-07-25 | kill dead OP_FADD & friends | Luc Van Oostenryck | 1 | -0/+7 |
2018-07-23 | big-shift: do not optimize over-sized ASRs | Luc Van Oostenryck | 1 | -0/+2 |
2018-07-23 | big-shift: do not optimize negative shifts | Luc Van Oostenryck | 1 | -0/+2 |
2018-07-23 | big-shift: fix warning message for negative or over-sized shifts | Luc Van Oostenryck | 1 | -5/+18 |
2018-07-23 | big-shift: move shift count check in a separate function | Luc Van Oostenryck | 1 | -5/+16 |
2018-07-23 | cast: simplify SEXT(ZEXT(x,N),N') | Luc Van Oostenryck | 1 | -0/+3 |
2018-07-23 | cast: simplify ZEXT(ZEXT(x,N),N') | Luc Van Oostenryck | 1 | -0/+6 |
2018-07-23 | cast: simplify SEXT(SEXT(x,N),N') | Luc Van Oostenryck | 1 | -0/+5 |
2018-07-23 | cast: simplify AND(ZEXT(x,M),N) | Luc Van Oostenryck | 1 | -1/+34 |
2018-07-23 | cast: simplify [ZS]EXT(AND(x,M),N) | Luc Van Oostenryck | 1 | -0/+24 |
2018-07-23 | cast: preserve the sizes of TRUNC(AND(x,M),N) | Luc Van Oostenryck | 1 | -6/+11 |
2018-07-23 | cast: use a switch to handle TRUNC(AND(x,M),N) in simplify_cast() | Luc Van Oostenryck | 1 | -7/+11 |
2018-07-23 | cast: do not compare sizes, test the opcode | Luc Van Oostenryck | 1 | -1/+1 |
2018-07-23 | cast: fix shift signedness in cast simplification | Luc Van Oostenryck | 1 | -1/+2 |
2018-07-23 | cast: simplify [SZ]EXT + TRUNC to a smaller/greater size | Luc Van Oostenryck | 1 | -1/+4 |
2018-07-23 | cast: simplify [SZ]EXT + TRUNC to original size | Luc Van Oostenryck | 1 | -0/+10 |
2018-07-23 | extract nbr_users() from unssa.c | Luc Van Oostenryck | 1 | -1/+1 |
2018-07-23 | big-shift: add -Wshift-count-{negative,overflow} | Luc Van Oostenryck | 1 | -1/+2 |
2018-07-23 | big-shift: use the type width for too big shift | Luc Van Oostenryck | 1 | -2/+2 |
2018-07-23 | big-shift: simplify over-sized OP_SHLs | Luc Van Oostenryck | 1 | -0/+2 |
2018-07-23 | big-shift: simplify over-sized OP_LSRs | Luc Van Oostenryck | 1 | -0/+8 |
2018-07-23 | big-shift: reuse simplify_asr() for LSR & SHL | Luc Van Oostenryck | 1 | -4/+4 |
2018-07-23 | big-shift: reorder the tests in simplify_asr() | Luc Van Oostenryck | 1 | -3/+5 |
2018-07-23 | big-shift: do not simplify over-sized OP_ASR to zero | Luc Van Oostenryck | 1 | -1/+0 |
2018-07-21 | big-shift: do not evaluate negative or over-sized shifts | Luc Van Oostenryck | 1 | -0/+6 |
2018-07-21 | big-shift: mark out-of-range OP_{ASR,LSR,SHL} as tainted | Luc Van Oostenryck | 1 | -1/+2 |
2018-06-30 | fix: remove dead OP_{SETVAL,SETFVAL,SLICE} | Luc Van Oostenryck | 1 | -0/+9 |
2018-06-30 | fix killing OP_SWITCH | Luc Van Oostenryck | 1 | -0/+1 |
2018-06-30 | Merge branch 'cast-optim' into tip | Luc Van Oostenryck | 1 | -2/+3 |
2018-06-29 | cast: optimize away casts to/from pointers | Luc Van Oostenryck | 1 | -2/+3 |
2018-06-28 | bool: remove OP_{AND,OR}_BOOL instructions | Luc Van Oostenryck | 1 | -23/+0 |
2018-06-28 | bool: simplify ZEXT in bool -> int -> bool | Luc Van Oostenryck | 1 | -2/+12 |
2018-06-28 | bool: fix add missing check in simplify_seteq_setne() | Luc Van Oostenryck | 1 | -1/+4 |
2018-06-28 | simplify 'x ^ ~0' to '~x' | Luc Van Oostenryck | 1 | -1/+7 |
2018-06-28 | simplify 'x & ~0' to 'x' | Luc Van Oostenryck | 1 | -0/+2 |
2018-06-28 | simplify 'x | ~0' to '~0' | Luc Van Oostenryck | 1 | -1/+8 |
2018-06-26 | cast: simplify TRUNC + ZEXT to AND | Luc Van Oostenryck | 1 | -0/+9 |
2018-06-23 | cast: prepare for more cast simplifications | Luc Van Oostenryck | 1 | -7/+10 |
2018-06-23 | cast: merge simplification of constant casts with constant unops | Luc Van Oostenryck | 1 | -23/+12 |
2018-06-23 | cast: simplify simplify_cast() | Luc Van Oostenryck | 1 | -23/+4 |
2018-06-23 | new helper: def_opcode() | Luc Van Oostenryck | 1 | -0/+7 |
2018-06-23 | cast: specialize integer casts | Luc Van Oostenryck | 1 | -12/+12 |
2018-06-23 | cast: specialize cast from pointers | Luc Van Oostenryck | 1 | -0/+1 |
2018-06-23 | cast: specialize casts from unsigned to pointers | Luc Van Oostenryck | 1 | -0/+1 |
2018-06-23 | cast: specialize floats to integer conversion | Luc Van Oostenryck | 1 | -0/+1 |
2018-06-23 | cast: specialize FPCAST into [USF]CVTF | Luc Van Oostenryck | 1 | -2/+3 |
2018-06-23 | Merge branches 'bug-fpcast-constant', 'case-unop', 'replace-pseudo' and 'add-... | Luc Van Oostenryck | 1 | -27/+24 |
2018-06-23 | ir: case OP_UNOP ... OP_UNOP_END | Luc Van Oostenryck | 1 | -12/+2 |
2018-06-23 | add missing entry for OP_FNEG in kill_insn() & validate_insn() | Luc Van Oostenryck | 1 | -1/+1 |
2018-06-22 | remove unused arg in simplify_cond_branch() | Luc Van Oostenryck | 1 | -3/+3 |
2018-06-22 | new helper: replace_pseudo() | Luc Van Oostenryck | 1 | -12/+19 |
2018-06-22 | avoid useless deref in simplify_cond_branch() | Luc Van Oostenryck | 1 | -4/+4 |
2018-06-21 | fix bad fpcast simplification | Luc Van Oostenryck | 1 | -2/+2 |
2018-05-06 | Merge branches 'unop', 'describe-dirty', 'range-syntax', 'old-testcases', 'fi... | Luc Van Oostenryck | 1 | -2/+4 |
2018-05-06 | fix: remove usage when killing symaddr (part 2) | Luc Van Oostenryck | 1 | -1/+1 |
2018-05-06 | fix: remove usage when killing symaddr (part 1) | Luc Van Oostenryck | 1 | -0/+1 |
2018-04-04 | fix missing handling of OP_FNEG | Luc Van Oostenryck | 1 | -1/+2 |
2018-03-18 | add remove_use() | Luc Van Oostenryck | 1 | -0/+8 |
2018-03-18 | make remove_usage() more generic | Luc Van Oostenryck | 1 | -3/+8 |
2018-03-17 | optim: simplify null select | Luc Van Oostenryck | 1 | -0/+6 |
2018-03-11 | fix symbol cleanup | Luc Van Oostenryck | 1 | -0/+2 |
2018-02-24 | fix accesses through incorrect union members | Jann Horn | 1 | -5/+5 |
2018-02-20 | ban use of 'true' or 'false' | Luc Van Oostenryck | 1 | -8/+6 |
2018-02-20 | no need for signed & unsigned multiplication | Luc Van Oostenryck | 1 | -10/+5 |
2018-02-20 | unsigned multiplication is also associative | Luc Van Oostenryck | 1 | -1/+1 |
2018-02-14 | kill dead loads | Luc Van Oostenryck | 1 | -1/+5 |
2018-02-13 | let kill_instruction() report if changes were made | Luc Van Oostenryck | 1 | -9/+8 |
2018-02-13 | use has_users() in dead_insn() too | Luc Van Oostenryck | 1 | -5/+2 |
2018-02-13 | add helper for pseudo's user-list's size | Luc Van Oostenryck | 1 | -2/+2 |
2018-02-08 | Merge branches 'cse-setfval' and 'extract-eval' into tip | Luc Van Oostenryck | 1 | -113/+128 |
2018-02-06 | extract extract eval_insn() from simplify_constant_binop() | Luc Van Oostenryck | 1 | -113/+128 |
2018-01-08 | add OP_SETFVAL | Luc Van Oostenryck | 1 | -0/+1 |
2017-11-18 | fix support of floating-point compare | Luc Van Oostenryck | 1 | -1/+1 |
2017-11-16 | canonicalize compare instructions | Luc Van Oostenryck | 1 | -4/+16 |
2017-11-16 | canonicalize binops before simplification | Luc Van Oostenryck | 1 | -11/+9 |
2017-11-16 | use opcode table for compare_opcode() | Luc Van Oostenryck | 1 | -25/+1 |
2017-11-11 | fix 'simplification' of float-to-int casts | Luc Van Oostenryck | 1 | -0/+4 |
2017-08-08 | mark pseudo users as deleted instead of removing them | Luc Van Oostenryck | 1 | -2/+3 |
2017-07-31 | fix ptrlist corruption while killing unreachable BBs | Luc Van Oostenryck | 1 | -0/+9 |
2017-05-12 | ignore VOID when trying to if-convert phi-nodes | Luc Van Oostenryck | 1 | -6/+35 |
2017-03-06 | split OP_BR between unconditional & conditional: OP_CBR | Luc Van Oostenryck | 1 | -10/+5 |
2017-03-04 | fix usage in simplify_seteq_setne() | Luc Van Oostenryck | 1 | -2/+3 |
2017-02-16 | simplify float-to-float casts that doesn't change size | Luc Van Oostenryck | 1 | -0/+2 |
2017-02-16 | add killing of stores | Luc Van Oostenryck | 1 | -0/+7 |
2017-02-16 | add killing of non-volatile loads | Luc Van Oostenryck | 1 | -0/+6 |
2017-02-16 | fix killing OP_CALL via pointers | Luc Van Oostenryck | 1 | -0/+2 |
2017-02-16 | add killing of pure calls | Luc Van Oostenryck | 1 | -0/+11 |
2017-02-16 | kill_instruction() may need to be forced or not | Luc Van Oostenryck | 1 | -1/+10 |
2017-02-16 | fix killing of otherwise not-handled instructions | Luc Van Oostenryck | 1 | -1/+3 |
2017-02-16 | remove unused clear_phi() | Luc Van Oostenryck | 1 | -10/+0 |
2017-02-16 | fix clear_phi(), replace it by kill_instruction() | Luc Van Oostenryck | 1 | -3/+3 |
2017-02-16 | fix killing of OP_PHIs | Luc Van Oostenryck | 1 | -1/+1 |
2017-02-16 | add helper kill_use_list() | Luc Van Oostenryck | 1 | -0/+10 |
2017-02-16 | add killing of OP_PHISOURCEs | Luc Van Oostenryck | 1 | -0/+3 |
2017-02-16 | add killing of OP_SLICEs | Luc Van Oostenryck | 1 | -0/+1 |
2017-02-13 | simplify '(x || x)' and '(x && x)' | Luc Van Oostenryck | 1 | -4/+4 |
2017-02-13 | simplify comparisons followed by an equality test against 0 or 1 | Luc Van Oostenryck | 1 | -0/+65 |
2017-02-13 | add warning option '-Wtautological-compare' | Luc Van Oostenryck | 1 | -0/+4 |
2017-02-13 | simplify '(x op x)' to '0', '1' or 'x' | Luc Van Oostenryck | 1 | -0/+35 |
2017-02-13 | simplify '(x || 1)' to '1' | Luc Van Oostenryck | 1 | -1/+6 |
2017-02-13 | simplify '~(~x)' and '-(-x)' to 'x' | Luc Van Oostenryck | 1 | -0/+17 |
2017-02-13 | simplify '(x % 1)' into '0' | Luc Van Oostenryck | 1 | -0/+5 |
2017-02-13 | simplify '(x / -1)' to '-x' (but only for signed division) | Luc Van Oostenryck | 1 | -0/+2 |
2017-02-13 | simplify '(x * -1)' to '-x' | Luc Van Oostenryck | 1 | -0/+11 |
2017-02-13 | simplify '(x / 1)' to 'x' | Luc Van Oostenryck | 1 | -0/+1 |
2017-02-13 | move OP_MUL simplification in a separate function | Luc Van Oostenryck | 1 | -0/+17 |
2017-02-13 | fix killing OP_SETVAL instructions | Luc Van Oostenryck | 1 | -0/+1 |
2017-02-13 | cleanup kill_instruction() | Luc Van Oostenryck | 1 | -26/+21 |
2017-02-13 | explicitely ignore killing OP_ENTRY | Luc Van Oostenryck | 1 | -0/+4 |
2017-02-13 | fix killing OP_COMPUTEDGOTO | Luc Van Oostenryck | 1 | -0/+1 |
2017-02-13 | fix killing OP_SELECT | Luc Van Oostenryck | 1 | -0/+1 |
2017-02-13 | fix killing OP_CAST & friends | Luc Van Oostenryck | 1 | -0/+4 |
2017-02-13 | fix killing OP_PHI instructions | Luc Van Oostenryck | 1 | -0/+1 |
2017-02-13 | kill uses of replaced instructions | Luc Van Oostenryck | 1 | -0/+20 |
2017-02-13 | fix crash while testing between conditional & unconditional OP_BR | Luc Van Oostenryck | 1 | -1/+1 |
2013-05-11 | fix SIGFPE caused by signed division overflow | Xi Wang | 1 | -0/+4 |
2012-05-10 | simplify: conservative handling of casts with pointers | Jan Pokorný | 1 | -0/+6 |
2008-04-24 | Simplify (and warn about) right shifts that result in zero | Linus Torvalds | 1 | -1/+56 |
2007-04-20 | simplify.c: Declare delete_pseudo_user_list_entry static | Josh Triplett | 1 | -1/+1 |