Skip to content

Commit 7f17301

Browse files
authored
[flang1][flang2] Add align pragma for derived type and fix shape array/character type
This patch implements parsing for `!DIR$ ALIGN alignment`, which only accepts a power-of-2 integer alignment. flang1 will set `flg.x[251]` with the alignment value if it encounters this pragma. Since the pragma only affects variables in a single statement, `flg.x[251]` is cleared when the parsing of the statement is complete. A new `palign` field is added to `struct SYM` to record a symbol's alignment. The field can be read with `PALIGNG(sptr)` and written with `PALIGNP(sptr)`. tools/flang1/flang1exe/interf.c and tools/flang1/flang1exe/exterf.c are updated to store and load symbol alignment to/from .mod files. tools/flang1/flang1exe/lowersym.c and tools/flang2/flang2exe/upper.cpp are updated to pass symbol alignment information via .stb files. The BSS is aligned to the maximum alignment among all symbols in the BSS; each symbol can then be aligned to smaller alignment values within the BSS. Alignment of statics and common data are also supported. Since a new field has been added in `struct SYM`, the ILM version number is bumped.
1 parent 4df6dac commit 7f17301

30 files changed

+639
-47
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
! RUN: %flang -O0 -S -emit-llvm %s -o - | FileCheck %s
2+
3+
! CHECK: %struct[[BLOCK1:\.BSS[0-9]+]] = type <{ [356 x i8] }>
4+
! CHECK: %struct[[BLOCK2:\.BSS[0-9]+]] = type <{ [612 x i8] }>
5+
! CHECK: %struct[[BLOCK3:\.BSS[0-9]+]] = type <{ [1124 x i8] }>
6+
! CHECK: %struct[[BLOCK4:\.BSS[0-9]+]] = type <{ [2148 x i8] }>
7+
! CHECK: %struct[[BLOCK5:_module_align_array_[0-9]+_]] = type <{ [228 x i8] }>
8+
! CHECK: @[[BLOCK1]] = internal global %struct[[BLOCK1]] zeroinitializer, align 256
9+
! CHECK: @[[BLOCK2]] = internal global %struct[[BLOCK2]] zeroinitializer, align 512
10+
! CHECK: @[[BLOCK3]] = internal global %struct[[BLOCK3]] zeroinitializer, align 1024
11+
! CHECK: @[[BLOCK4]] = internal global %struct[[BLOCK4]] zeroinitializer, align 2048
12+
! CHECK: @[[BLOCK5]] = common global %struct[[BLOCK5]] zeroinitializer, align 128
13+
14+
module module_align_array
15+
implicit none
16+
17+
!DIR$ ALIGN 128
18+
integer, dimension (5,5) :: v1, v2
19+
20+
interface
21+
module subroutine module_interface_subroutine()
22+
end subroutine module_interface_subroutine
23+
end interface
24+
25+
end module module_align_array
26+
27+
submodule (module_align_array) submodule_align_array
28+
29+
contains
30+
module subroutine module_interface_subroutine()
31+
32+
!DIR$ ALIGN 256
33+
integer, dimension (5,5) :: v3, v4
34+
35+
v3(1, 1) = 101
36+
! CHECK: store i32 101, ptr @[[BLOCK1]], align
37+
38+
v3(5, 5) = 102
39+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 96
40+
! CHECK: store i32 102, ptr %[[TEMP]], align
41+
42+
v4(1, 1) = 103
43+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 256
44+
! CHECK: store i32 103, ptr %[[TEMP]], align
45+
46+
v4(5, 5) = 104
47+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 352
48+
! CHECK: store i32 104, ptr %[[TEMP]], align
49+
50+
end subroutine module_interface_subroutine
51+
end submodule submodule_align_array
52+
53+
54+
55+
program align
56+
use module_align_array
57+
implicit none
58+
59+
!DIR$ ALIGN 512
60+
integer, dimension (5,5) :: v5, v6
61+
62+
v5(1, 1) = 201
63+
! CHECK: store i32 201, ptr @[[BLOCK2]], align
64+
65+
v5(5, 5) = 202
66+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 96
67+
! CHECK: store i32 202, ptr %[[TEMP]], align
68+
69+
v6(1, 1) = 203
70+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 512
71+
! CHECK: store i32 203, ptr %[[TEMP]], align
72+
73+
v6(5, 5) = 204
74+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 608
75+
! CHECK: store i32 204, ptr %[[TEMP]], align
76+
77+
v1(1, 1) = 81
78+
! CHECK: store i32 81, ptr @[[BLOCK5]], align
79+
80+
v1(5, 5) = 82
81+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 96
82+
! CHECK: store i32 82, ptr %[[TEMP]], align
83+
84+
v2(1, 1) = 83
85+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 128
86+
! CHECK: store i32 83, ptr %[[TEMP]], align
87+
88+
v2(5, 5) = 84
89+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 224
90+
! CHECK: store i32 84, ptr %[[TEMP]], align
91+
92+
end program align
93+
94+
95+
subroutine subroutine_align()
96+
97+
!DIR$ ALIGN 1024
98+
integer, dimension (5,5) :: v7, v8
99+
100+
v7(1, 1) = 401
101+
! CHECK: store i32 401, ptr @[[BLOCK3]], align
102+
103+
v7(5, 5) = 402
104+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 96
105+
! CHECK: store i32 402, ptr %[[TEMP]], align
106+
107+
v8(1, 1) = 403
108+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 1024
109+
! CHECK: store i32 403, ptr %[[TEMP]], align
110+
111+
v8(5, 5) = 404
112+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 1120
113+
! CHECK: store i32 404, ptr %[[TEMP]], align
114+
115+
return
116+
end subroutine subroutine_align
117+
118+
119+
function function_align()
120+
121+
!DIR$ ALIGN 2048
122+
integer, dimension (5,5) :: v9, v10
123+
124+
v9(1, 1) = 801
125+
! CHECK: store i32 801, ptr @[[BLOCK4]], align
126+
127+
v9(5, 5) = 802
128+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 96
129+
! CHECK: store i32 802, ptr %[[TEMP]], align
130+
131+
v10(1, 1) = 803
132+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 2048
133+
! CHECK: store i32 803, ptr %[[TEMP]], align
134+
135+
v10(5, 5) = 804
136+
! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 2144
137+
! CHECK: store i32 804, ptr %[[TEMP]], align
138+
139+
return
140+
end function function_align
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
! RUN: %flang -O0 -S -emit-llvm %s -o - | FileCheck %s
2+
3+
! CHECK: %struct[[BLOCK1:\.STATICS[0-9]+]] = type <{ [10 x i8] }
4+
! CHECK: %struct[[BLOCK2:\.STATICS[0-9]+]] = type <{ [10 x i8] }
5+
! CHECK: %struct[[BLOCK3:\.STATICS[0-9]+]] = type <{ [10 x i8] }
6+
! CHECK: %struct[[BLOCK4:\.STATICS[0-9]+]] = type <{ [10 x i8] }
7+
! CHECK: %struct[[BLOCK5:_module_align_character_[0-9]+_]] = type <{ [10 x i8] }
8+
! CHECK: %struct[[BLOCK6:_module_align_character_[0-9]+_]] = type <{ [10 x i8] }
9+
! CHECK: @[[BLOCK1]] = internal global %struct[[BLOCK1]] <{{[^>]+}}>, align 256
10+
! CHECK: @[[BLOCK2]] = internal global %struct[[BLOCK2]] <{{[^>]+}}>, align 512
11+
! CHECK: @[[BLOCK3]] = internal global %struct[[BLOCK3]] <{{[^>]+}}>, align 1024
12+
! CHECK: @[[BLOCK4]] = internal global %struct[[BLOCK4]] <{{[^>]+}}>, align 2048
13+
! CHECK: @[[BLOCK5]] = common global %struct[[BLOCK5]] zeroinitializer, align 128
14+
! CHECK: @[[BLOCK6]] = global %struct[[BLOCK6]] <{{[^>]+}}>, align 128
15+
16+
module module_align_character
17+
implicit none
18+
19+
!DIR$ ALIGN 128
20+
character(len=10) :: v1, v2 = "128"
21+
22+
interface
23+
module subroutine module_interface_subroutine()
24+
end subroutine module_interface_subroutine
25+
end interface
26+
27+
end module module_align_character
28+
29+
submodule (module_align_character) submodule_align_character
30+
31+
contains
32+
module subroutine module_interface_subroutine()
33+
34+
!DIR$ ALIGN 256
35+
character(len=10) :: v3, v4 = "256"
36+
! CHECK: %[[V3:v3_[0-9]+]] = alloca [10 x i8], align 256
37+
38+
v3 = "101"
39+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V3]], align
40+
41+
v4 = "102"
42+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK1]], align
43+
44+
end subroutine module_interface_subroutine
45+
end submodule submodule_align_character
46+
47+
program align
48+
use module_align_character
49+
implicit none
50+
51+
!DIR$ ALIGN 512
52+
character(len=10) :: v5, v6 = "512"
53+
! CHECK: %[[V5:v5_[0-9]+]] = alloca [10 x i8], align 512
54+
55+
v5 = "201"
56+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V5]], align
57+
58+
v6 = "202"
59+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK2]], align
60+
61+
v1 = "81"
62+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK5]], align
63+
64+
v2 = "82"
65+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK6]], align
66+
67+
end program align
68+
69+
subroutine subroutine_align()
70+
71+
!DIR$ ALIGN 1024
72+
character(len=10) :: v7, v8 = "1024"
73+
! CHECK: %[[V7:v7_[0-9]+]] = alloca [10 x i8], align 1024
74+
75+
v7 = "401"
76+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V7]], align
77+
78+
v8 = "402"
79+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK3]], align
80+
81+
return
82+
end subroutine subroutine_align
83+
84+
function function_align()
85+
86+
!DIR$ ALIGN 2048
87+
character(len=10) :: v9, v10 = "2048"
88+
! CHECK: %[[V9:v9_[0-9]+]] = alloca [10 x i8], align 2048
89+
90+
v9 = "801"
91+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr %[[V9]], align
92+
93+
v10 = "802"
94+
! CHECK: store volatile i64 %{{[0-9]+}}, ptr @[[BLOCK4]], align
95+
96+
return
97+
end function function_align

0 commit comments

Comments
 (0)