@@ -288,8 +288,9 @@ let win64 =
288
288
| "win64" | "mingw64" | "cygwin" -> true
289
289
| _ -> false
290
290
291
- (* Specific operations that are pure *)
292
291
292
+ (* Specific operations that are pure *)
293
+ (* Keep in sync with [Vectorize_specific] *)
293
294
let operation_is_pure = function
294
295
| Ilea _ | Ibswap _ | Isextend32 | Izextend32
295
296
| Ifloatarithmem _ -> true
@@ -300,7 +301,7 @@ let operation_is_pure = function
300
301
| Isimd op -> Simd. is_pure op
301
302
302
303
(* Specific operations that can raise *)
303
-
304
+ (* Keep in sync with [Vectorize_specific] *)
304
305
let operation_can_raise = function
305
306
| Ilea _ | Ibswap _ | Isextend32 | Izextend32
306
307
| Ifloatarithmem _
@@ -309,6 +310,7 @@ let operation_can_raise = function
309
310
| Istore_int (_, _, _) | Ioffset_loc (_, _)
310
311
| Icldemote _ | Iprefetch _ -> false
311
312
313
+ (* Keep in sync with [Vectorize_specific] *)
312
314
let operation_allocates = function
313
315
| Ilea _ | Ibswap _ | Isextend32 | Izextend32
314
316
| Ifloatarithmem _
@@ -410,84 +412,107 @@ let equal_specific_operation left right =
410
412
411
413
(* addressing mode functions *)
412
414
413
- let compare_addressing_mode_without_displ (addressing_mode_1 : addressing_mode ) (addressing_mode_2 : addressing_mode ) =
414
- (* Ignores displ when comparing to show that it is possible to calculate the offset *)
415
+ let equal_addressing_mode_without_displ (addressing_mode_1 : addressing_mode ) (addressing_mode_2 : addressing_mode ) =
416
+ (* Ignores [displ] when comparing to show that it is possible to calculate the offset,
417
+ see [addressing_offset_in_bytes]. *)
415
418
match addressing_mode_1, addressing_mode_2 with
416
419
| Ibased (symbol1 , global1 , _ ), Ibased (symbol2 , global2 , _ ) -> (
417
420
match global1, global2 with
418
421
| Global , Global | Local , Local ->
419
- String. compare symbol1 symbol2
420
- | Global , Local -> - 1
421
- | Local , Global -> 1 )
422
- | Ibased _ , _ -> - 1
423
- | _ , Ibased _ -> 1
424
- | Iindexed _ , Iindexed _ -> 0
425
- | Iindexed _ , _ -> - 1
426
- | _ , Iindexed _ -> 1
427
- | Iindexed2 _ , Iindexed2 _ -> 0
428
- | Iindexed2 _ , _ -> - 1
429
- | _ , Iindexed2 _ -> 1
430
- | Iscaled (scale1 , _ ), Iscaled (scale2 , _ ) -> Int. compare scale1 scale2
431
- | Iscaled _ , _ -> - 1
432
- | _ , Iscaled _ -> 1
422
+ String. equal symbol1 symbol2
423
+ | (Global | Local ), _ -> false )
424
+ | Iindexed _ , Iindexed _ -> true
425
+ | Iindexed2 _ , Iindexed2 _ -> true
426
+ | Iscaled (scale1 , _ ), Iscaled (scale2 , _ ) -> Int. equal scale1 scale2
433
427
| Iindexed2scaled (scale1 , _ ), Iindexed2scaled (scale2 , _ ) ->
434
- Int. compare scale1 scale2
435
-
436
- let compare_addressing_mode_displ (addressing_mode_1 : addressing_mode ) (addressing_mode_2 : addressing_mode ) =
437
- match addressing_mode_1, addressing_mode_2 with
438
- | Ibased (symbol1 , global1 , n1 ), Ibased (symbol2 , global2 , n2 ) -> (
439
- match global1, global2 with
440
- | Global , Global | Local , Local ->
441
- if symbol1 = symbol2 then Some (Int. compare n1 n2) else None
442
- | Global , Local | Local , Global -> None )
443
- | Iindexed n1 , Iindexed n2 -> Some (Int. compare n1 n2)
444
- | Iindexed2 n1 , Iindexed2 n2 -> Some (Int. compare n1 n2)
445
- | Iscaled (scale1 , n1 ), Iscaled (scale2 , n2 ) ->
446
- let scale_compare = scale1 - scale2 in
447
- if scale_compare = 0 then Some (Int. compare n1 n2) else None
448
- | Iindexed2scaled (scale1 , n1 ), Iindexed2scaled (scale2 , n2 ) ->
449
- let scale_compare = scale1 - scale2 in
450
- if scale_compare = 0 then Some (Int. compare n1 n2) else None
451
- | Ibased _ , _ -> None
452
- | Iindexed _ , _ -> None
453
- | Iindexed2 _ , _ -> None
454
- | Iscaled _ , _ -> None
455
- | Iindexed2scaled _ , _ -> None
456
-
457
- let addressing_offset_in_bytes (addressing_mode_1 : addressing_mode ) (addressing_mode_2 : addressing_mode ) =
428
+ Int. equal scale1 scale2
429
+ | (Ibased _ | Iindexed _ | Iindexed2 _ | Iscaled _ | Iindexed2scaled _ ), _ -> false
430
+
431
+ let addressing_offset_in_bytes
432
+ (addressing_mode_1 : addressing_mode )
433
+ (addressing_mode_2 : addressing_mode )
434
+ ~arg_offset_in_bytes
435
+ args_1
436
+ args_2
437
+ =
438
+ let address_arg_offset_in_bytes index =
439
+ arg_offset_in_bytes args_1.(index) args_2.(index)
440
+ in
458
441
match addressing_mode_1, addressing_mode_2 with
459
- | Ibased (symbol1 , global1 , n1 ), Ibased (symbol2 , global2 , n2 ) -> (
460
- match global1, global2 with
461
- | Global , Global | Local , Local ->
462
- if symbol1 = symbol2 then Some (n2 - n1) else None
463
- | Global , Local | Local , Global -> None )
464
- | Iindexed n1 , Iindexed n2 -> Some (n2 - n1)
465
- | Iindexed2 n1 , Iindexed2 n2 -> Some (n2 - n1)
442
+ | Ibased (symbol1 , global1 , n1 ), Ibased (symbol2 , global2 , n2 ) ->
443
+ (* symbol + displ *)
444
+ (match global1, global2 with
445
+ | Global , Global | Local , Local ->
446
+ if String. equal symbol1 symbol2 then Some (n2 - n1) else None
447
+ | Global , Local | Local , Global -> None )
448
+ | Iindexed n1 , Iindexed n2 ->
449
+ (* reg + displ *)
450
+ (match address_arg_offset_in_bytes 0 with
451
+ | Some base_off -> Some (base_off + (n2 - n1))
452
+ | None -> None )
453
+ | Iindexed2 n1 , Iindexed2 n2 ->
454
+ (* reg + reg + displ *)
455
+ (match address_arg_offset_in_bytes 0 , address_arg_offset_in_bytes 1 with
456
+ | Some arg0_offset , Some arg1_offset ->
457
+ Some (arg0_offset + arg1_offset + (n2 - n1))
458
+ | (None , _ |Some _ , _ ) -> None )
466
459
| Iscaled (scale1 , n1 ), Iscaled (scale2 , n2 ) ->
467
- let scale_compare = scale1 - scale2 in
468
- if scale_compare = 0 then Some (n2 - n1) else None
460
+ (* reg * scale + displ *)
461
+ if not (Int. compare scale1 scale2 = 0 ) then None
462
+ else
463
+ (match address_arg_offset_in_bytes 0 with
464
+ | Some offset -> Some ((offset * scale1) + (n2 - n1))
465
+ | None -> None )
469
466
| Iindexed2scaled (scale1 , n1 ), Iindexed2scaled (scale2 , n2 ) ->
470
- let scale_compare = scale1 - scale2 in
471
- if scale_compare = 0 then Some (n2 - n1) else None
467
+ (* reg + reg * scale + displ *)
468
+ if not (Int. compare scale1 scale2 = 0 ) then None else
469
+ (match address_arg_offset_in_bytes 0 , address_arg_offset_in_bytes 1 with
470
+ | Some arg0_offset , Some arg1_offset ->
471
+ Some (arg0_offset + (arg1_offset* scale1) + (n2 - n1))
472
+ | (None , _ |Some _ , _ ) -> None )
472
473
| Ibased _ , _ -> None
473
474
| Iindexed _ , _ -> None
474
475
| Iindexed2 _ , _ -> None
475
476
| Iscaled _ , _ -> None
476
477
| Iindexed2scaled _ , _ -> None
477
478
478
- let can_cross_loads_or_stores (specific_operation : specific_operation ) =
479
- match specific_operation with
480
- | Ilea _ | Istore_int _ | Ioffset_loc _ | Ifloatarithmem _ | Isimd _ | Icldemote _
481
- | Iprefetch _ ->
482
- false
483
- | Ibswap _ | Isextend32 | Izextend32 | Irdtsc | Irdpmc | Ilfence | Isfence | Imfence
484
- | Ipause ->
485
- true
486
-
487
- let may_break_alloc_freshness (specific_operation : specific_operation ) =
488
- match specific_operation with
489
- | Isimd _ -> true
490
- | Ilea _ | Istore_int _ | Ioffset_loc _ | Ifloatarithmem _ | Ibswap _ | Isextend32
491
- | Izextend32 | Irdtsc | Irdpmc | Ilfence | Isfence | Imfence | Ipause | Icldemote _
492
- | Iprefetch _ ->
493
- false
479
+ let isomorphic_specific_operation op1 op2 =
480
+ match op1, op2 with
481
+ | Ilea a1 , Ilea a2 -> equal_addressing_mode_without_displ a1 a2
482
+ | Istore_int (_n1 , a1 , is_assign1 ), Istore_int (_n2 , a2 , is_assign2 ) ->
483
+ equal_addressing_mode_without_displ a1 a2 && Bool. equal is_assign1 is_assign2
484
+ | Ioffset_loc (_n1 , a1 ), Ioffset_loc (_n2 , a2 ) ->
485
+ equal_addressing_mode_without_displ a1 a2
486
+ | Ifloatarithmem (w1 , o1 , a1 ), Ifloatarithmem (w2 , o2 , a2 ) ->
487
+ Cmm. equal_float_width w1 w2 &&
488
+ equal_float_operation o1 o2 &&
489
+ equal_addressing_mode_without_displ a1 a2
490
+ | Ibswap { bitwidth = left } , Ibswap { bitwidth = right } ->
491
+ Int. equal (int_of_bswap_bitwidth left) (int_of_bswap_bitwidth right)
492
+ | Isextend32 , Isextend32 ->
493
+ true
494
+ | Izextend32 , Izextend32 ->
495
+ true
496
+ | Irdtsc , Irdtsc ->
497
+ true
498
+ | Irdpmc , Irdpmc ->
499
+ true
500
+ | Ilfence , Ilfence ->
501
+ true
502
+ | Isfence , Isfence ->
503
+ true
504
+ | Imfence , Imfence ->
505
+ true
506
+ | Ipause , Ipause -> true
507
+ | Icldemote x , Icldemote x' -> equal_addressing_mode_without_displ x x'
508
+ | Iprefetch { is_write = left_is_write; locality = left_locality; addr = left_addr; },
509
+ Iprefetch { is_write = right_is_write; locality = right_locality; addr = right_addr; } ->
510
+ Bool. equal left_is_write right_is_write
511
+ && equal_prefetch_temporal_locality_hint left_locality right_locality
512
+ && equal_addressing_mode_without_displ left_addr right_addr
513
+ | Isimd l , Isimd r ->
514
+ Simd. equal_operation l r
515
+ | (Ilea _ | Istore_int _ | Ioffset_loc _ | Ifloatarithmem _ | Ibswap _ |
516
+ Isextend32 | Izextend32 | Irdtsc | Irdpmc | Ilfence | Isfence | Imfence |
517
+ Ipause | Isimd _ | Icldemote _ | Iprefetch _ ), _ ->
518
+ false
0 commit comments