File: where-scheduling.f90

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (153 lines) | stat: -rw-r--r-- 6,893 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
! Test scheduling of WHERE in lower-hlfir-ordered-assignments pass.

! RUN: bbc -hlfir -o - -pass-pipeline="builtin.module(lower-hlfir-ordered-assignments)" --debug-only=flang-ordered-assignment -flang-dbg-order-assignment-schedule-only %s 2>&1 | FileCheck %s
! REQUIRES: asserts

subroutine no_conflict(x, y)
  real :: x(:), y(:)
  where (y.gt.0) x = y
end subroutine

subroutine fake_conflict(x, y)
  ! The conflict here could be avoided because the read and write are
  ! aligned, so there would not be any read after write at the element
  ! level, but this will require a bit more work to detect this (like
  ! comparing the hlfir.designate operations).
  real :: x(:), y(:)
  where (x.gt.y) x = y
end subroutine

subroutine only_once(x, y, z)
  interface
    impure function call_me_only_once()
      logical :: call_me_only_once(10)
    end function
  end interface
  real :: x(:), y(:), z(:)
  where (call_me_only_once())
    x = y
    z = y
  end where
end subroutine

subroutine rhs_lhs_conflict(x, y)
  real :: x(:, :), y(:, :)
  where (y.gt.0.) x = transpose(x)
end subroutine

subroutine where_construct_no_conflict(x, y, z, mask1, mask2)
  real :: x(:), y(:), z(:)
  logical :: mask1(:), mask2(:)
  where (mask1)
    x = y
  elsewhere (mask2)
    z = y
  end where
end subroutine

subroutine where_construct_conflict(x, y)
  real :: x(:, :), y(:, :)
  where (y.gt.0.)
    x = y
  elsewhere (x.gt.0)
    y = x
  end where
end subroutine

subroutine where_construct_conflict_2(x, y)
  real :: x(:, :), y(:, :)
  where (x.gt.0.)
    x = y
  elsewhere (y.gt.0)
    y = x
  end where
end subroutine

subroutine where_vector_subscript_conflict_1(x, vec1)
  real :: x(10)
  integer :: vec1(10)
  where (x(vec1).lt.0.) x = 42.
end subroutine

subroutine where_vector_subscript_conflict_2(x, vec1)
  integer :: x(10)
  real :: y(10)
  where (y(x).lt.0.) x = 0
end subroutine

subroutine where_in_forall_conflict(x)
  real :: x(:, :)
  forall (i = 1:10)
    where (x(i, :).gt.0) x(:, i) = x(i, :)
  end forall
end subroutine

subroutine no_need_to_make_lhs_temp(x, y, i, j)
  integer :: j, i, x(:, :), y(:, :)
  call internal
contains
subroutine internal
  ! The internal procedure context currently gives a hard time to
  ! FIR alias analysis that flags the read of i,j and y as conflicting
  ! with the write to x. But this is not a reason to create a temporary
  ! storage for the LHS: the address is anyway fully computed in
  ! a descriptor (fir.box) before assigning any element of x.

  ! Note that the where mask is also saved while there is no real
  ! need to: it is addressing x elements in the same order as they
  ! are being assigned. But this will require more work in the
  ! conflict analysis to prove that the lowered DAG of `x(:, y(i, j))`
  ! are the same and that the access to this designator is done in the
  ! same ordered inside the mask and LHS.
  where (x(:, y(i, j)) == y(i, j))  x(:, y(i, j)) = 42
end subroutine
end subroutine

!CHECK-LABEL: ------------ scheduling where in _QPno_conflict ------------
!CHECK-NEXT: run 1 evaluate: where/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPfake_conflict ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?xf32>>' at index: 0
!CHECK-NEXT: run 1 save    : where/mask
!CHECK-NEXT: run 2 evaluate: where/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPonly_once ------------
!CHECK-NEXT: unknown effect: %9 = fir.call @llvm.stacksave() fastmath<contract> : () -> !fir.ref<i8>
!CHECK-NEXT: run 1 save  (w): where/mask
!CHECK-NEXT: run 2 evaluate: where/region_assign1
!CHECK-NEXT: run 3 evaluate: where/region_assign2
!CHECK-LABEL: ------------ scheduling where in _QPrhs_lhs_conflict ------------
!CHECK-NEXT: unknown effect: %2 = hlfir.transpose %0#0 : (!fir.box<!fir.array<?x?xf32>>) -> !hlfir.expr<?x?xf32>
!CHECK-NEXT: run 1 save  (w): where/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: where/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPwhere_construct_no_conflict ------------
!CHECK-NEXT: run 1 evaluate: where/region_assign1
!CHECK-NEXT: run 2 evaluate: where/elsewhere1/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPwhere_construct_conflict ------------
!CHECK-NEXT: run 1 evaluate: where/region_assign1
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1
!CHECK-NEXT: run 2 save    : where/mask
!CHECK-NEXT: run 3 evaluate: where/elsewhere1/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPwhere_construct_conflict_2 ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0
!CHECK-NEXT: run 1 save    : where/mask
!CHECK-NEXT: run 2 evaluate: where/region_assign1
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 1
!CHECK-NEXT: run 3 save    : where/elsewhere1/mask
!CHECK-NEXT: run 4 evaluate: where/elsewhere1/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPwhere_vector_subscript_conflict_1 ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.ref<!fir.array<10xf32>>' at index: 0 W:<block argument> of type '!fir.ref<!fir.array<10xf32>>' at index: 0
!CHECK-NEXT: run 1 save    : where/mask
!CHECK-NEXT: run 2 evaluate: where/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QPwhere_vector_subscript_conflict_2 ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.ref<!fir.array<10xi32>>' at index: 0 W:<block argument> of type '!fir.ref<!fir.array<10xi32>>' at index: 0
!CHECK-NEXT: run 1 save    : where/mask
!CHECK-NEXT: run 2 evaluate: where/region_assign1
!CHECK-LABEL: ------------ scheduling forall in _QPwhere_in_forall_conflict ------------
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0
!CHECK-NEXT: run 1 save    : forall/where1/mask
!CHECK-NEXT: conflict: R/W: <block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0 W:<block argument> of type '!fir.box<!fir.array<?x?xf32>>' at index: 0
!CHECK-NEXT: run 1 save    : forall/where1/region_assign1/rhs
!CHECK-NEXT: run 2 evaluate: forall/where1/region_assign1
!CHECK-LABEL: ------------ scheduling where in _QFno_need_to_make_lhs_tempPinternal ------------
!CHECK-NEXT: conflict: R/W: %7 = fir.load %6 : !fir.llvm_ptr<!fir.ref<i32>> W:%13 = fir.load %12 : !fir.ref<!fir.box<!fir.array<?x?xi32>>>
!CHECK-NEXT: run 1 save    : where/mask
!CHECK-NEXT: run 2 evaluate: where/region_assign1