@@ -334,6 +334,13 @@ let rec add_const c n dbg =
334
334
Cop (Csubi , [Cconst_int (n + x, dbg); c], dbg)
335
335
| Cop (Csubi, [c ; Cconst_int (x , _ )], _ ) when Misc. no_overflow_sub n x ->
336
336
add_const c (n - x) dbg
337
+ | Cop
338
+ ( Cor ,
339
+ [(Cop (Clsl , [_; Cconst_int (1 , _)], _) as inner); Cconst_int (1 , _)],
340
+ _ )
341
+ when n = - 1 ->
342
+ (* undo setting the tag bit *)
343
+ inner
337
344
| c -> Cop (Caddi , [c; Cconst_int (n, dbg)], dbg)
338
345
339
346
let incr_int c dbg = add_const c 1 dbg
@@ -360,38 +367,6 @@ let rec sub_int c1 c2 dbg =
360
367
361
368
let neg_int c dbg = sub_int (Cconst_int (0 , dbg)) c dbg
362
369
363
- let rec lsl_int c1 c2 dbg =
364
- match c1, c2 with
365
- | c1 , Cconst_int (0 , _ ) -> c1
366
- | Cop (Clsl , [c; Cconst_int (n1, _)], _), Cconst_int (n2, _)
367
- when n1 > 0 && n2 > 0 && n1 + n2 < size_int * 8 ->
368
- Cop (Clsl , [c; Cconst_int (n1 + n2, dbg)], dbg)
369
- | Cop (Caddi , [c1; Cconst_int (n1, _)], _), Cconst_int (n2, _)
370
- when Misc. no_overflow_lsl n1 n2 ->
371
- add_const (lsl_int c1 c2 dbg) (n1 lsl n2) dbg
372
- | _ , _ -> Cop (Clsl , [c1; c2], dbg)
373
-
374
- let lsl_const c n dbg = lsl_int c (Cconst_int (n, dbg)) dbg
375
-
376
- let is_power2 n = n = 1 lsl Misc. log2 n
377
-
378
- and mult_power2 c n dbg = lsl_int c (Cconst_int (Misc. log2 n, dbg)) dbg
379
-
380
- let rec mul_int c1 c2 dbg =
381
- match c1, c2 with
382
- | c , Cconst_int (0 , _ ) | Cconst_int (0 , _ ), c ->
383
- Csequence (c, Cconst_int (0 , dbg))
384
- | c , Cconst_int (1 , _ ) | Cconst_int (1 , _ ), c -> c
385
- | c , Cconst_int (- 1 , _ ) | Cconst_int (-1 , _ ), c ->
386
- sub_int (Cconst_int (0 , dbg)) c dbg
387
- | c , Cconst_int (n , _ ) when is_power2 n -> mult_power2 c n dbg
388
- | Cconst_int (n , _ ), c when is_power2 n -> mult_power2 c n dbg
389
- | Cop (Caddi , [c; Cconst_int (n, _)], _), Cconst_int (k, _)
390
- | Cconst_int (k, _), Cop (Caddi , [c; Cconst_int (n, _)], _)
391
- when Misc. no_overflow_mul n k ->
392
- add_const (mul_int c (Cconst_int (k, dbg)) dbg) (n * k) dbg
393
- | c1 , c2 -> Cop (Cmuli , [c1; c2], dbg)
394
-
395
370
(* identify cmm operations whose result is guaranteed to be small integers (e.g.
396
371
in the range [min_int / 4; max_int / 4]) *)
397
372
let guaranteed_to_be_small_int = function
@@ -410,7 +385,7 @@ let ignore_low_bit_int = function
410
385
| Cop (Cor, [c ; Cconst_int (1 , _ )], _ ) -> c
411
386
| c -> c
412
387
413
- let lsr_int c1 c2 dbg =
388
+ let rec lsr_int c1 c2 dbg =
414
389
match c1, c2 with
415
390
| c1 , Cconst_int (0 , _ ) -> c1
416
391
| Cop (Clsr , [c; Cconst_int (n1, _)], _), Cconst_int (n2, _)
@@ -420,46 +395,97 @@ let lsr_int c1 c2 dbg =
420
395
Cop (Clsr , [ignore_low_bit_int c1; c2], dbg)
421
396
| _ -> Cop (Clsr , [c1; c2], dbg)
422
397
423
- let lsr_const c n dbg = lsr_int c (Cconst_int (n, dbg)) dbg
424
-
425
- let asr_int c1 c2 dbg =
426
- match c2 with
427
- | Cconst_int (0 , _ ) -> c1
428
- | Cconst_int (n , _ ) when n > 0 -> (
398
+ and asr_int c1 c2 dbg =
399
+ match c1, c2 with
400
+ | c1 , Cconst_int (0 , _ ) -> c1
401
+ | c1 , Cconst_int (n , _ ) when n > 0 -> (
429
402
match ignore_low_bit_int c1 with
430
403
(* some operations always return small enough integers that it is safe and
431
404
correct to optimise [asr (lsl x 1) 1] into [x]. *)
432
405
| Cop (Clsl , [c; Cconst_int (1 , _)], _)
433
406
when n = 1 && guaranteed_to_be_small_int c ->
434
407
c
408
+ | Cop (Cor, [inner ; Cconst_int (x , _ )], _ ) when n < Sys. int_size ->
409
+ let inner = asr_const inner n dbg in
410
+ let x = x asr n in
411
+ if x = 0 then inner else Cop (Cor , [inner; Cconst_int (x, dbg)], dbg)
435
412
| c1' -> Cop (Casr , [c1'; c2], dbg))
413
+ | Cop (Casr, [x ; (Cconst_int _ as y )], z ), c2 ->
414
+ (* prefer putting the constant shift on the outside to help enable further
415
+ peephole optimizations *)
416
+ Cop (Casr , [Cop (Casr , [x; c2], dbg); y], z)
436
417
| _ -> Cop (Casr , [c1; c2], dbg)
437
418
438
- let asr_const c n dbg = asr_int c (Cconst_int (n, dbg)) dbg
419
+ and lsl_int c1 c2 dbg =
420
+ match c1, c2 with
421
+ | c1 , Cconst_int (0 , _ ) -> c1
422
+ | Cop (Clsl , [c; Cconst_int (n1, _)], _), Cconst_int (n2, _)
423
+ when n1 > 0 && n2 > 0 && n1 + n2 < size_int * 8 ->
424
+ Cop (Clsl , [c; Cconst_int (n1 + n2, dbg)], dbg)
425
+ | Cop (Caddi , [c1; Cconst_int (n1, _)], _), Cconst_int (n2, _)
426
+ when Misc. no_overflow_lsl n1 n2 ->
427
+ add_const (lsl_int c1 c2 dbg) (n1 lsl n2) dbg
428
+ | Cop (Cor , [c1; Cconst_int (n1, _)], _), Cconst_int (n2, _)
429
+ when Misc. no_overflow_lsl n1 n2 ->
430
+ Cop (Cor , [lsl_int c1 c2 dbg; Cconst_int (n1 lsl n2, dbg)], dbg)
431
+ | Cop (Clsl, [x ; (Cconst_int _ as y )], z ), c2 ->
432
+ (* prefer putting the constant shift on the outside to help enable further
433
+ peephole optimizations *)
434
+ Cop (Clsl , [Cop (Clsl , [x; c2], dbg); y], z)
435
+ | _ , _ -> Cop (Clsl , [c1; c2], dbg)
436
+
437
+ and lsl_const c n dbg = lsl_int c (Cconst_int (n, dbg)) dbg
438
+
439
+ and asr_const c n dbg = asr_int c (Cconst_int (n, dbg)) dbg
440
+
441
+ and lsr_const c n dbg = lsr_int c (Cconst_int (n, dbg)) dbg
442
+
443
+ let is_power2 n = n = 1 lsl Misc. log2 n
444
+
445
+ and mult_power2 c n dbg = lsl_int c (Cconst_int (Misc. log2 n, dbg)) dbg
446
+
447
+ let rec mul_int c1 c2 dbg =
448
+ match c1, c2 with
449
+ | c , Cconst_int (0 , _ ) | Cconst_int (0 , _ ), c ->
450
+ Csequence (c, Cconst_int (0 , dbg))
451
+ | c , Cconst_int (1 , _ ) | Cconst_int (1 , _ ), c -> c
452
+ | c , Cconst_int (- 1 , _ ) | Cconst_int (-1 , _ ), c ->
453
+ sub_int (Cconst_int (0 , dbg)) c dbg
454
+ | c , Cconst_int (n , _ ) when is_power2 n -> mult_power2 c n dbg
455
+ | Cconst_int (n , _ ), c when is_power2 n -> mult_power2 c n dbg
456
+ | Cop (Caddi , [c; Cconst_int (n, _)], _), Cconst_int (k, _)
457
+ | Cconst_int (k, _), Cop (Caddi , [c; Cconst_int (n, _)], _)
458
+ when Misc. no_overflow_mul n k ->
459
+ add_const (mul_int c (Cconst_int (k, dbg)) dbg) (n * k) dbg
460
+ | c1 , c2 -> Cop (Cmuli , [c1; c2], dbg)
439
461
440
462
let tag_int i dbg =
441
463
match i with
442
464
| Cconst_int (n , _ ) -> int_const dbg n
443
465
| Cop (Casr, [c ; Cconst_int (n , _ )], _ ) when n > 0 ->
444
466
Cop
445
467
(Cor , [asr_int c (Cconst_int (n - 1 , dbg)) dbg; Cconst_int (1 , dbg)], dbg)
468
+ | Cop (Clsr, [c ; Cconst_int (n , _ )], _ ) when n > 0 ->
469
+ Cop (Cor , [lsr_const c (n - 1 ) dbg; Cconst_int (1 , dbg)], dbg)
446
470
| c -> incr_int (lsl_int c (Cconst_int (1 , dbg)) dbg) dbg
447
471
448
472
let untag_int i dbg =
449
473
match i with
450
474
| Cconst_int (n , _ ) -> Cconst_int (n asr 1 , dbg)
451
475
| Cop (Cor , [Cop (Casr , [c; Cconst_int (n, _)], _); Cconst_int (1 , _)], _)
452
476
when n > 0 && n < (size_int * 8 ) - 1 ->
453
- Cop ( Casr , [c; Cconst_int (n + 1 , dbg)], dbg)
477
+ asr_const c (n + 1 ) dbg
454
478
| Cop (Cor , [Cop (Clsr , [c; Cconst_int (n, _)], _); Cconst_int (1 , _)], _)
455
479
when n > 0 && n < (size_int * 8 ) - 1 ->
456
480
Cop (Clsr , [c; Cconst_int (n + 1 , dbg)], dbg)
457
481
| c -> asr_int c (Cconst_int (1 , dbg)) dbg
458
482
459
483
let mk_not dbg cmm =
460
484
match cmm with
461
- | Cop (Caddi , [Cop (Clsl , [c; Cconst_int (1 , _)], _); Cconst_int (1 , _)], dbg')
462
- -> (
485
+ | Cop
486
+ ( (Caddi | Cor ),
487
+ [Cop (Clsl , [c; Cconst_int (1 , _)], _); Cconst_int (1 , _)],
488
+ dbg' ) -> (
463
489
match c with
464
490
| Cop (Ccmpi cmp , [c1 ; c2 ], dbg'' ) ->
465
491
tag_int
@@ -799,8 +825,10 @@ let mod_int ?dividend_cannot_be_min_int c1 c2 dbg =
799
825
800
826
let test_bool dbg cmm =
801
827
match cmm with
802
- | Cop (Caddi , [Cop (Clsl , [c; Cconst_int (1 , _)], _); Cconst_int (1 , _)], _)
803
- ->
828
+ | Cop
829
+ ( (Caddi | Cor ),
830
+ [Cop (Clsl , [c; Cconst_int (1 , _)], _); Cconst_int (1 , _)],
831
+ _ ) ->
804
832
c
805
833
| Cconst_int (n , dbg ) ->
806
834
if n = 1 then Cconst_int (0 , dbg) else Cconst_int (1 , dbg)
@@ -1035,8 +1063,10 @@ let array_indexing ?typ log2size ptr ofs dbg =
1035
1063
if i = 0
1036
1064
then ptr
1037
1065
else Cop (add, [ptr; Cconst_int (i lsl log2size, dbg)], dbg)
1038
- | Cop (Caddi , [Cop (Clsl , [c; Cconst_int (1 , _)], _); Cconst_int (1 , _)], dbg')
1039
- ->
1066
+ | Cop
1067
+ ( (Caddi | Cor ),
1068
+ [Cop (Clsl , [c; Cconst_int (1 , _)], _); Cconst_int (1 , _)],
1069
+ dbg' ) ->
1040
1070
Cop (add, [ptr; lsl_const c log2size dbg], dbg')
1041
1071
| Cop (Caddi, [c ; Cconst_int (n , _ )], dbg' ) when log2size = 0 ->
1042
1072
Cop
0 commit comments