From 6cda87ebfb89ceba07369bb05d75a58750a3f1fa Mon Sep 17 00:00:00 2001 From: yinjiawei2023 Date: Fri, 19 May 2023 00:17:21 +0800 Subject: [PATCH] add align pragma for derived type --- 20-add-align-prgma-for-derived-type.patch | 767 ++++++++++++++++++++++ flang.spec | 6 +- 2 files changed, 772 insertions(+), 1 deletion(-) create mode 100644 20-add-align-prgma-for-derived-type.patch diff --git a/20-add-align-prgma-for-derived-type.patch b/20-add-align-prgma-for-derived-type.patch new file mode 100644 index 0000000..cde5082 --- /dev/null +++ b/20-add-align-prgma-for-derived-type.patch @@ -0,0 +1,767 @@ +From 2e0b17c3cc9b949dc7ad0f5403c4664a0d159dac Mon Sep 17 00:00:00 2001 +From: yinjiawei2023 +Date: Thu, 1 Jun 2023 22:27:41 +0800 +Subject: [PATCH] [flang] Add align pragma for derived type + +This patch add align pragma for derived type, +and add some test cases for this pragma. +--- + test/directives/align_derived_type.f90 | 200 ++++++++++++++++++++++++ + test/directives/align_not_supported.f90 | 35 +++++ + tools/flang1/flang1exe/dtypeutl.c | 21 +++ + tools/flang1/flang1exe/exterf.c | 8 +- + tools/flang1/flang1exe/global.h | 2 +- + tools/flang1/flang1exe/interf.c | 1 + + tools/flang1/flang1exe/lowersym.c | 6 +- + tools/flang1/utils/symtab/sharedefs.h | 6 +- + tools/flang1/utils/symtab/symtab.in.h | 1 + + tools/flang2/docs/xflag.n | 5 +- + tools/flang2/flang2exe/cgmain.cpp | 39 ++++- + tools/flang2/flang2exe/dtypeutl.cpp | 5 +- + tools/flang2/flang2exe/llassem.cpp | 27 +++- + tools/flang2/flang2exe/upper.cpp | 1 + + tools/flang2/utils/symtab/sharedefs.h | 6 +- + tools/flang2/utils/symtab/symtab.in.h | 1 + + tools/shared/miscutil.c | 10 +- + tools/shared/pragma.c | 24 ++- + tools/shared/sharedefs.h | 6 +- + tools/shared/utils/sharedefs.h | 6 +- + 20 files changed, 385 insertions(+), 25 deletions(-) + create mode 100644 test/directives/align_derived_type.f90 + create mode 100644 test/directives/align_not_supported.f90 + +diff --git a/test/directives/align_derived_type.f90 b/test/directives/align_derived_type.f90 +new file mode 100644 +index 0000000..b71c425 +--- /dev/null ++++ b/test/directives/align_derived_type.f90 +@@ -0,0 +1,200 @@ ++! RUN: %flang -O0 -S -emit-llvm %s -o - | FileCheck %s ++ ++! CHECK: %struct[[BLOCK1:\.BSS[0-9]+]] = type <{ [264 x i8] }> ++! CHECK: %struct[[BLOCK2:\.BSS[0-9]+]] = type <{ [520 x i8] }> ++! CHECK: %struct[[BLOCK3:\.BSS[0-9]+]] = type <{ [1032 x i8] }> ++! CHECK: %struct[[BLOCK4:\.BSS[0-9]+]] = type <{ [2056 x i8] }> ++! CHECK: %struct[[BLOCK5:_module_align_derived_[0-9]+_]] = type <{ [136 x i8] }> ++! CHECK: @[[BLOCK1]] = internal global %struct[[BLOCK1]] zeroinitializer, align 256 ++! CHECK: @[[BLOCK2]] = internal global %struct[[BLOCK2]] zeroinitializer, align 512 ++! CHECK: @[[BLOCK3]] = internal global %struct[[BLOCK3]] zeroinitializer, align 1024 ++! CHECK: @[[BLOCK4]] = internal global %struct[[BLOCK4]] zeroinitializer, align 2048 ++! CHECK: @[[BLOCK5]] = common global %struct[[BLOCK5]] zeroinitializer, align 128 ++ ++module module_align_derived ++implicit none ++ ++ !dir$ align 128 ++ type T1 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T1 ++ ++ !dir$ align 128 ++ type T2 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T2 ++ ++ type(T1) :: v1 ++ type(T2) :: v2 ++ ++ interface ++ module subroutine module_interface_subroutine() ++ end subroutine module_interface_subroutine ++ end interface ++ ++end module module_align_derived ++ ++submodule (module_align_derived) submodule_align_derived ++ ++ contains ++ module subroutine module_interface_subroutine() ++ ++ !dir$ align 256 ++ type T3 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T3 ++ ++ !dir$ align 256 ++ type T4 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T4 ++ ++ type(T3) :: v3 ++ type(T4) :: v4 ++ ++ v3%f1 = 101 ++! CHECK: store i16 101, ptr @[[BLOCK1]], align ++ ++ v3%f2 = 102 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 4 ++! CHECK: store i32 102, ptr %[[TEMP]], align ++ ++ v4%f1 = 103 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 256 ++! CHECK: store i16 103, ptr %[[TEMP]], align ++ ++ v4%f2 = 104 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK1]], i64 260 ++! CHECK: store i32 104, ptr %[[TEMP]], align ++ ++ end subroutine module_interface_subroutine ++end submodule submodule_align_derived ++ ++ ++ ++program align ++use module_align_derived ++implicit none ++ ++ !dir$ align 512 ++ type T5 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T5 ++ ++ !dir$ align 512 ++ type T6 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T6 ++ ++ type(T5) :: v5 ++ type(T6) :: v6 ++ ++ v5%f1 = 201 ++! CHECK: store i16 201, ptr @[[BLOCK2]], align ++ ++ v5%f2 = 202 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 4 ++! CHECK: store i32 202, ptr %[[TEMP]], align ++ ++ v6%f1 = 203 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 512 ++! CHECK: store i16 203, ptr %[[TEMP]], align ++ ++ v6%f2 = 204 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK2]], i64 516 ++! CHECK: store i32 204, ptr %[[TEMP]], align ++ ++ v1%f1 = 81 ++! CHECK: store i16 81, ptr @[[BLOCK5]], align ++ ++ v1%f2 = 82 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 4 ++! CHECK: store i32 82, ptr %[[TEMP]], align ++ ++ v2%f1 = 83 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 128 ++! CHECK: store i16 83, ptr %[[TEMP]], align ++ ++ v2%f2 = 84 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK5]], i64 132 ++! CHECK: store i32 84, ptr %[[TEMP]], align ++ ++end program align ++ ++ ++subroutine subroutine_align() ++ ++ !dir$ align 1024 ++ type T7 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T7 ++ ++ !dir$ align 1024 ++ type T8 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T8 ++ ++ type(T7) :: v7 ++ type(T8) :: v8 ++ ++ v7%f1 = 401 ++! CHECK: store i16 401, ptr @[[BLOCK3]], align ++ ++ v7%f2 = 402 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 4 ++! CHECK: store i32 402, ptr %[[TEMP]], align ++ ++ v8%f1 = 403 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 1024 ++! CHECK: store i16 403, ptr %[[TEMP]], align ++ ++ v8%f2 = 404 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK3]], i64 1028 ++! CHECK: store i32 404, ptr %[[TEMP]], align ++ ++ return ++end subroutine subroutine_align ++ ++ ++function function_align() ++ ++ !dir$ align 2048 ++ type T9 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T9 ++ ++ !dir$ align 2048 ++ type T10 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T10 ++ ++ type(T9) :: v9 ++ type(T10) :: v10 ++ ++ v9%f1 = 801 ++! CHECK: store i16 801, ptr @[[BLOCK4]], align ++ ++ v9%f2 = 802 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 4 ++! CHECK: store i32 802, ptr %[[TEMP]], align ++ ++ v10%f1 = 803 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 2048 ++! CHECK: store i16 803, ptr %[[TEMP]], align ++ ++ v10%f2 = 804 ++! CHECK: %[[TEMP:[0-9]+]] = getelementptr i8, ptr @[[BLOCK4]], i64 2052 ++! CHECK: store i32 804, ptr %[[TEMP]], align ++ ++ return ++end function function_align +diff --git a/test/directives/align_not_supported.f90 b/test/directives/align_not_supported.f90 +new file mode 100644 +index 0000000..7232078 +--- /dev/null ++++ b/test/directives/align_not_supported.f90 +@@ -0,0 +1,35 @@ ++! RUN: %flang -O0 -c %s 2>&1 | FileCheck %s ++ ++program align ++implicit none ++ ++ !dir$ align alignment ++ type T1 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T1 ++! CHECK: F90-W-0280-Syntax error in directive ALIGN: allow int alignment only ++ ++ !dir$ align -3 ++ type T2 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T2 ++! CHECK: F90-W-0280-Syntax error in directive ALIGN: allow int alignment only ++ ++ !dir$ align 0 ++ type T3 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T3 ++! CHECK: F90-W-0280-Syntax error in directive ALIGN: allow power of 2 alignment only ++ ++ !dir$ align 3 ++ type T4 ++ integer(kind=2) :: f1 ++ integer(kind=4) :: f2 ++ end type T4 ++! CHECK: F90-W-0280-Syntax error in directive ALIGN: allow power of 2 alignment only ++ ++ ++end program align +diff --git a/tools/flang1/flang1exe/dtypeutl.c b/tools/flang1/flang1exe/dtypeutl.c +index 1cc6993..33fa5bc 100644 +--- a/tools/flang1/flang1exe/dtypeutl.c ++++ b/tools/flang1/flang1exe/dtypeutl.c +@@ -1227,6 +1227,8 @@ alignment(DTYPE dtype) + case TY_STRUCT: + case TY_UNION: + case TY_DERIVED: ++ if (DTA(dtype) > DTY(dtype + 4)) ++ return DTA(dtype); + return DTY(dtype + 4); + + default: +@@ -1393,6 +1395,25 @@ get_type(int n, TY_KIND v1, int v2) + } + if (dtype == 0) { + dtype = STG_NEXT_SIZE(stb.dt, n); ++ ++ /* handle the possible !dir$ align XX, ++ * ++ * flang1 reaches here only when creating ++ * new dtype. So flang1 should handle the ++ * possible align pragma for new type here. ++ * ++ * flang1 should store the alignment from flg.x[251] ++ * to DTA, later it will updates the dtype alignment ++ * when in alignment() or lower_put_datatype(). ++ * ++ * Note that this pragma should only be used to ++ * this strucutre, so flang1 need to clear the flg.x[251] ++ */ ++ if (flg.x[251]) { ++ DTA(dtype) = flg.x[251] - 1; ++ flg.x[251] = 0; ++ } ++ + DTY(dtype) = v1; + DTY(dtype + 1) = v2; + if (v1 == TY_CHAR || is_nchar) { +diff --git a/tools/flang1/flang1exe/exterf.c b/tools/flang1/flang1exe/exterf.c +index 140ebc2..51f412d 100644 +--- a/tools/flang1/flang1exe/exterf.c ++++ b/tools/flang1/flang1exe/exterf.c +@@ -2109,8 +2109,12 @@ export_dt(int dtype) + case TY_STRUCT: + case TY_DERIVED: + /* print dtype and descriptor entry */ +- lzprintf(outlz, " %d %d %d %d", (int)DTY(dtype + 1), (int)DTY(dtype + 2), +- (int)DTY(dtype + 3), (int)DTY(dtype + 4)); ++ lzprintf(outlz, " %d %d %d", (int)DTY(dtype + 1), (int)DTY(dtype + 2), ++ (int)DTY(dtype + 3)); ++ if (DTA(dtype) > DTY(dtype + 4)) ++ lzprintf(outlz, " %d", (int)DTA(dtype)); ++ else ++ lzprintf(outlz, " %d", (int)DTY(dtype + 4)); + break; + + case TY_CHAR: +diff --git a/tools/flang1/flang1exe/global.h b/tools/flang1/flang1exe/global.h +index 6554cbd..947cc0d 100644 +--- a/tools/flang1/flang1exe/global.h ++++ b/tools/flang1/flang1exe/global.h +@@ -184,7 +184,7 @@ typedef struct { + LOGICAL endian; + LOGICAL terse; + int dollar; /* defines the char to which '$' is translated */ +- int x[251]; /* x flags */ ++ int x[252]; /* x flags */ + LOGICAL quad; /* quad align "unconstrained objects" if sizeof >= 16 */ + int anno; + LOGICAL qa; /* TRUE => -qa appeared on command line */ +diff --git a/tools/flang1/flang1exe/interf.c b/tools/flang1/flang1exe/interf.c +index 8d1c573..ac77826 100644 +--- a/tools/flang1/flang1exe/interf.c ++++ b/tools/flang1/flang1exe/interf.c +@@ -2170,6 +2170,7 @@ import(lzhandle *fdlz, WantPrivates wantPrivates, int ivsn) + DTY(new_id + 3) = get_num(10); /* (old) tag */ + DTY(new_id + 4) = get_num(10); /* align */ + DTY(new_id + 5) = 0; /* ICT */ ++ DTA(new_id) = DTY(new_id + 4); + break; + case TY_CHAR: + case TY_NCHAR: +diff --git a/tools/flang1/flang1exe/lowersym.c b/tools/flang1/flang1exe/lowersym.c +index 1705447..87c22be 100644 +--- a/tools/flang1/flang1exe/lowersym.c ++++ b/tools/flang1/flang1exe/lowersym.c +@@ -2632,7 +2632,11 @@ lower_put_datatype(int dtype, int usage) + putsym("member", DTY(dtype + 1)); + putval("size", DTY(dtype + 2)); + putsym("tag", DTY(dtype + 3)); +- putval("align", DTY(dtype + 4)); ++ ++ if (DTA(dtype) > DTY(dtype + 4)) ++ putval("align", DTA(dtype)); ++ else ++ putval("align", DTY(dtype + 4)); + break; + + case TY_NUMERIC: +diff --git a/tools/flang1/utils/symtab/sharedefs.h b/tools/flang1/utils/symtab/sharedefs.h +index 30ae371..50495fc 100644 +--- a/tools/flang1/utils/symtab/sharedefs.h ++++ b/tools/flang1/utils/symtab/sharedefs.h +@@ -30,21 +30,21 @@ + + /* declare: + * struct{ +- * dt* stg_base; ++ * dt* stg_base, *stg_align; + * unsigned int stg_size, stg_avail, stg_free, stg_cleared, + * stg_dtsize; + * void* stg_sidecar; * }name; */ + + /* declare the stg_ members; useful in a struct that also has other members */ + #define STG_MEMBERS(dt) \ +- dt *stg_base; \ ++ dt *stg_base, *stg_align; \ + unsigned int stg_size, stg_avail, stg_free, stg_cleared, stg_dtsize, \ + stg_freelink_offset, stg_flags; \ + const char *stg_name; \ + void *stg_sidecar + + /* to statically initialize STG_MEMBERS */ +-#define STG_INIT NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL ++#define STG_INIT NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL + + /* declare a struct with the stg_members */ + #define STG_DECLARE(name, dt) \ +diff --git a/tools/flang1/utils/symtab/symtab.in.h b/tools/flang1/utils/symtab/symtab.in.h +index 29c3d06..f8c820a 100644 +--- a/tools/flang1/utils/symtab/symtab.in.h ++++ b/tools/flang1/utils/symtab/symtab.in.h +@@ -51,6 +51,7 @@ + + + #define DTY(d) (stb.dt.stg_base[d]) ++#define DTA(d) (stb.dt.stg_align[d]) + + /* for fast DT checking -- define table indexed by TY_ */ + extern short dttypes[TY_MAX+1]; +diff --git a/tools/flang2/docs/xflag.n b/tools/flang2/docs/xflag.n +index 4108e59..f5e3745 100644 +--- a/tools/flang2/docs/xflag.n ++++ b/tools/flang2/docs/xflag.n +@@ -5549,6 +5549,9 @@ where, n = flg.x[249] + .XF "250:" + Set number of bigbuffers for multi-buffer memory management for AMD GPU. + (moved to 202) ++ + .XF "251:" +-(NOT available - check declaration in global.h for flg.x[], all compilers) ++Reserved to save an derived type alignment passed by pragma `!dir$ align XX` + ++.XF "252:" ++(NOT available - check declaration in global.h for flg.x[], all compilers) +\ No newline at end of file +diff --git a/tools/flang2/flang2exe/cgmain.cpp b/tools/flang2/flang2exe/cgmain.cpp +index 3c08aa2..ac0d963 100644 +--- a/tools/flang2/flang2exe/cgmain.cpp ++++ b/tools/flang2/flang2exe/cgmain.cpp +@@ -12065,7 +12065,7 @@ gen_address_operand(int addr_op, int nme, bool lda, LL_Type *llt_expected, + static OPERAND * + gen_acon_expr(int ilix, LL_Type *expected_type) + { +- SPTR sptr; ++ SPTR sptr, ag; + DTYPE dtype; + ISZ_T idx; + LL_Type *ty1; +@@ -12103,6 +12103,7 @@ gen_acon_expr(int ilix, LL_Type *expected_type) + /* Handle pointer constants with no base symbol table pointer. + * This also becomes a pointer-sized integer */ + sptr = SymConval1(opnd); ++ dtype = DTYPEG(sptr); + if (!sptr) { + num = ACONOFFG(opnd); + ISZ_2_INT64(num, val); +@@ -12111,11 +12112,30 @@ gen_acon_expr(int ilix, LL_Type *expected_type) + sym_is_refd(sptr); + idx = (STYPEG(sptr) == ST_STRUCT || STYPEG(sptr) == ST_ARRAY + || ACONOFFG(opnd) < 0) ? 0 : ACONOFFG(opnd); +- process_sptr_offset(sptr, variable_offset_in_aggregate(sptr, idx)); ++ if (DTA(dtype)) { ++ /* handle the flang1's pragma !dir$ align ++ * adjust the sptr's offset in ag to be aligned with ++ * sptr's alignment. ++ * */ ++ process_sptr_offset(sptr, idx + ALIGN( ++ variable_offset_in_aggregate(sptr, 0), ++ DTA(dtype))); ++ }else { ++ process_sptr_offset(sptr, variable_offset_in_aggregate(sptr, idx)); ++ } + idx = ACONOFFG(opnd); /* byte offset */ + + ty1 = make_lltype_from_dtype(DT_ADDR); +- idx = variable_offset_in_aggregate(sptr, idx); ++ if (DTA(dtype)) { ++ /* handle the flang1's pragma !dir$ align ++ * adjust the sptr's offset in ag to be aligned with ++ * sptr's alignment. ++ * */ ++ idx += ALIGN(variable_offset_in_aggregate(sptr, 0), DTA(dtype)); ++ }else { ++ idx = variable_offset_in_aggregate(sptr, idx); ++ } ++ + if (idx) { + base_op = gen_sptr(sptr); + index_op = NULL; +@@ -12138,6 +12158,19 @@ gen_acon_expr(int ilix, LL_Type *expected_type) + } + } + ++ if (DTA(dtype)) { ++ /* handle the flang1 pragma !dir$ align ++ * Here we record the sptr's alignment ++ * to its belonging ag, so its ag's alignment ++ * can be aligned to this alignment ++ */ ++ char gname[MXIDLN + 50]; ++ sprintf(gname, "struct%s", get_llvm_name(sptr)); ++ ag = find_ag(gname); ++ if (DTA(dtype) >= AG_ALIGN(ag)) ++ AG_ALIGN(ag) = DTA(dtype) + 1; ++ } ++ + if (operand->ll_type && VOLG(sptr)) + operand->flags |= OPF_VOLATILE; + return operand; +diff --git a/tools/flang2/flang2exe/dtypeutl.cpp b/tools/flang2/flang2exe/dtypeutl.cpp +index 7c247df..46cd9f8 100644 +--- a/tools/flang2/flang2exe/dtypeutl.cpp ++++ b/tools/flang2/flang2exe/dtypeutl.cpp +@@ -504,7 +504,10 @@ alignment(DTYPE dtype) + + case TY_STRUCT: + case TY_UNION: +- return DTyAlgTyAlign(dtype); ++ align_bits = DTyAlgTyAlign(dtype); ++ if (DTA(dtype) > align_bits) ++ return DTA(dtype); ++ return align_bits; + + default: + interr("alignment: bad dtype ", ty, ERR_Severe); +diff --git a/tools/flang2/flang2exe/llassem.cpp b/tools/flang2/flang2exe/llassem.cpp +index ef0440e..1aa2822 100644 +--- a/tools/flang2/flang2exe/llassem.cpp ++++ b/tools/flang2/flang2exe/llassem.cpp +@@ -1168,6 +1168,13 @@ assemble_end(void) + fprintf(ASMFIL, "%%struct%s = type < { %s } > \n", name, typed); + fprintf(ASMFIL, "@%s = %s global %%struct%s ", name, + AG_ISMOD(gblsym) ? "external" : "common", name); ++ ++ /* handle the flang1 pragma !dir$ align ++ * Here we refer common block's alignment from ++ * its belonging ag's alignment ++ */ ++ align_value = AG_ALIGN(tdefsym) > align_value ? ++ AG_ALIGN(tdefsym) : align_value; + fprintf(ASMFIL, "%s, align %d", + AG_ISMOD(gblsym) ? "" : " zeroinitializer", align_value); + for (llObjtodbgFirst(listp, &i); !llObjtodbgAtEnd(&i); +@@ -1492,12 +1499,24 @@ write_bss(void) + char *bss_nm = bss_name; + + if (gbl.bss_addr) { ++ char gname[MXIDLN + 50]; ++ int align; ++ SPTR ag; ++ ++ /* handle the flang1 pragma !dir$ align ++ * Here we refer bss's alignment from ++ * its belonging ag's alignment ++ */ ++ sprintf(gname, "struct%s", bss_nm); ++ ag = find_ag(gname); ++ align = AG_ALIGN(ag) > 32 ? AG_ALIGN(ag) : 32; ++ + fprintf(ASMFIL, "%%struct%s = type <{[%" ISZ_PF "d x i8]}>\n", bss_nm, + gbl.bss_addr); + fprintf(ASMFIL, + "@%s = %s %%struct%s <{[%" ISZ_PF "d x i8] " +- "zeroinitializer }> , align 32", +- bss_nm, type_str, bss_nm, gbl.bss_addr); ++ "zeroinitializer }> , align %d", ++ bss_nm, type_str, bss_nm, gbl.bss_addr, align); + ll_write_object_dbg_references(ASMFIL, cpu_llvm_module, bss_dbg_list); + bss_dbg_list = NULL; + fputc('\n', ASMFIL); +@@ -4263,6 +4282,10 @@ assn_static_off(SPTR sptr, DTYPE dtype, ISZ_T size) + } else { + a = align_unconstrained(dtype); + } ++ ++ if (DTA(dtype) > a) ++ a = DTA(dtype); ++ + addr = ALIGN(addr, a); + ADDRESSP(sptr, addr); + if (DINITG(sptr)) { +diff --git a/tools/flang2/flang2exe/upper.cpp b/tools/flang2/flang2exe/upper.cpp +index d11655d..664b868 100644 +--- a/tools/flang2/flang2exe/upper.cpp ++++ b/tools/flang2/flang2exe/upper.cpp +@@ -1708,6 +1708,7 @@ read_datatype(void) + dt = get_type(6, dval, NOSYM); + datatypexref[dtype] = dt; + DTySetAlgTy(dt, member, size, tag, align, 0); ++ DTA(dt) = align; + break; + case TY_CHAR: + size = getval("len"); +diff --git a/tools/flang2/utils/symtab/sharedefs.h b/tools/flang2/utils/symtab/sharedefs.h +index 30ae371..50495fc 100644 +--- a/tools/flang2/utils/symtab/sharedefs.h ++++ b/tools/flang2/utils/symtab/sharedefs.h +@@ -30,21 +30,21 @@ + + /* declare: + * struct{ +- * dt* stg_base; ++ * dt* stg_base, *stg_align; + * unsigned int stg_size, stg_avail, stg_free, stg_cleared, + * stg_dtsize; + * void* stg_sidecar; * }name; */ + + /* declare the stg_ members; useful in a struct that also has other members */ + #define STG_MEMBERS(dt) \ +- dt *stg_base; \ ++ dt *stg_base, *stg_align; \ + unsigned int stg_size, stg_avail, stg_free, stg_cleared, stg_dtsize, \ + stg_freelink_offset, stg_flags; \ + const char *stg_name; \ + void *stg_sidecar + + /* to statically initialize STG_MEMBERS */ +-#define STG_INIT NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL ++#define STG_INIT NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL + + /* declare a struct with the stg_members */ + #define STG_DECLARE(name, dt) \ +diff --git a/tools/flang2/utils/symtab/symtab.in.h b/tools/flang2/utils/symtab/symtab.in.h +index 884aa31..889850e 100644 +--- a/tools/flang2/utils/symtab/symtab.in.h ++++ b/tools/flang2/utils/symtab/symtab.in.h +@@ -29,6 +29,7 @@ + #define DT_CPTR DT_ADDR + + #define DTY(d) (stb.dt.stg_base[d]) ++#define DTA(d) (stb.dt.stg_align[d]) + + /* for fast DT checking -- define table indexed by TY_ */ + extern short dttypes[TY_MAX+1]; +diff --git a/tools/shared/miscutil.c b/tools/shared/miscutil.c +index 05dd030..e747680 100644 +--- a/tools/shared/miscutil.c ++++ b/tools/shared/miscutil.c +@@ -147,6 +147,8 @@ stg_alloc_base(STG *stg, int dtsize, BIGUINT64 size, const char *name) + stg->stg_cleared = 0; + stg->stg_name = name; + stg->stg_base = (void *)sccalloc(stg->stg_dtsize * size); ++ stg->stg_align = (void *)sccalloc(stg->stg_dtsize * size); ++ memset(stg->stg_align, 0, stg->stg_dtsize * size); + } else { + invalid_size("stg_alloc", dtsize, size, name); + } +@@ -210,8 +212,10 @@ stg_delete(STG *stg) + if (DBGBIT(7,0x10)) + fprintf(gbl.dbgfil, "stg_delete(stg=%p, dtsize=%d, size=%d, name=%s)\n", + stg, stg->stg_dtsize, stg->stg_size, stg->stg_name); +- if (stg->stg_base) ++ if (stg->stg_base) { + sccfree((char *)stg->stg_base); ++ sccfree((char *)stg->stg_align); ++ } + memset(stg, 0, sizeof(STG)); + } /* stg_delete */ + +@@ -256,6 +260,10 @@ stg_need(STG *stg) + thisstg->stg_size = newsize; + thisstg->stg_base = (void *)sccrelal( + (char *)thisstg->stg_base, newsize * thisstg->stg_dtsize); ++ thisstg->stg_align = (void *)sccrelal( ++ (char *)thisstg->stg_align, newsize * thisstg->stg_dtsize); ++ memset((char*)thisstg->stg_align + oldsize * thisstg->stg_dtsize, 0, ++ (newsize - oldsize) * thisstg->stg_dtsize); + } + /* we have to clear all newly allocated elements, in case there + * are sidecars with the NOCLEAR flag set, so they get initially cleared */ +diff --git a/tools/shared/pragma.c b/tools/shared/pragma.c +index 0956139..4105b3b 100644 +--- a/tools/shared/pragma.c ++++ b/tools/shared/pragma.c +@@ -994,7 +994,29 @@ do_sw(void) + case SW_ESCTYALIAS: + break; + case SW_ALIGN: +- break; ++ /* declaration align XX */ ++ if (gtok() != T_INT) { ++ int backup_nowarn = gbl.nowarn; ++ gbl.nowarn = false; ++ error((error_code_t)280, ERR_Warning, lineno, \ ++ "ALIGN: allow int alignment only", 0); ++ gbl.nowarn = backup_nowarn; ++ return true; ++ } ++ ++ /* check whether the alignment is power of 2 */ ++ if (itok <= 0 || ((itok & (itok - 1)) != 0)) { ++ int backup_nowarn = gbl.nowarn; ++ gbl.nowarn = false; ++ error((error_code_t)280, ERR_Warning, lineno, \ ++ "ALIGN: allow power of 2 alignment only", 0); ++ gbl.nowarn = backup_nowarn; ++ return true; ++ } ++ ++ TR1("SW_ALIGN alignment[%d]\n", itok); ++ flg.x[251] = itok; ++ return true; + case SW_BOUNDS: + if (no_specified) { + bclr(DIR_OFFSET(currdir, x[70]), 0x02); +diff --git a/tools/shared/sharedefs.h b/tools/shared/sharedefs.h +index 30ae371..50495fc 100644 +--- a/tools/shared/sharedefs.h ++++ b/tools/shared/sharedefs.h +@@ -30,21 +30,21 @@ + + /* declare: + * struct{ +- * dt* stg_base; ++ * dt* stg_base, *stg_align; + * unsigned int stg_size, stg_avail, stg_free, stg_cleared, + * stg_dtsize; + * void* stg_sidecar; * }name; */ + + /* declare the stg_ members; useful in a struct that also has other members */ + #define STG_MEMBERS(dt) \ +- dt *stg_base; \ ++ dt *stg_base, *stg_align; \ + unsigned int stg_size, stg_avail, stg_free, stg_cleared, stg_dtsize, \ + stg_freelink_offset, stg_flags; \ + const char *stg_name; \ + void *stg_sidecar + + /* to statically initialize STG_MEMBERS */ +-#define STG_INIT NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL ++#define STG_INIT NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL + + /* declare a struct with the stg_members */ + #define STG_DECLARE(name, dt) \ +diff --git a/tools/shared/utils/sharedefs.h b/tools/shared/utils/sharedefs.h +index a941cde..45093b9 100644 +--- a/tools/shared/utils/sharedefs.h ++++ b/tools/shared/utils/sharedefs.h +@@ -38,21 +38,21 @@ + + /* declare: + * struct{ +- * dt* stg_base; ++ * dt* stg_base, *stg_align; + * unsigned int stg_size, stg_avail, stg_free, stg_cleared, + * stg_dtsize; + * void* stg_sidecar; * }name; */ + + /* declare the stg_ members; useful in a struct that also has other members */ + #define STG_MEMBERS(dt) \ +- dt *stg_base; \ ++ dt *stg_base, *stg_align; \ + unsigned int stg_size, stg_avail, stg_free, stg_cleared, stg_dtsize, \ + stg_freelink_offset, stg_flags; \ + char *stg_name; \ + void *stg_sidecar + + /* to statically initialize STG_MEMBERS */ +-#define STG_INIT NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL ++#define STG_INIT NULL, NULL, 0, 0, 0, 0, 0, 0, 0, NULL, NULL + + /* declare a struct with the stg_members */ + #define STG_DECLARE(name, dt) \ +-- +2.25.1 + diff --git a/flang.spec b/flang.spec index 1366364..80f860e 100644 --- a/flang.spec +++ b/flang.spec @@ -2,7 +2,7 @@ Name: flang Version: flang_20210324 -Release: 23 +Release: 24 Summary: Fortran language compiler targeting LLVM License: Apache-2.0 @@ -30,6 +30,7 @@ Patch15: 16-add-c-and-cxx-memory-align-investigation.patch Patch16: 17-add-fortran-memory-align-investigation.patch Patch17: 18-add-test-cases-for-attribute-declarations-and-specifications-3.patch Patch18: 19-add-test-cases-for-types-3.patch +Patch19: 20-add-align-prgma-for-derived-type.patch %description Flang depends on a fork of the LLVM project (https://github.com/flang-compiler/classic-flang-llvm-project). The fork made some changes to the upstream LLVM project to support Flang toolchain. Flang cannot build independently for now. @@ -51,6 +52,9 @@ TODO: support build Flang. %changelog +* Thu May 18 2023 yinjiawei2023 - flang_20210324-24 +- Add patch for add align prgma for derived type and add some relative test cases + * Thu Feb 16 2023 xieyihui - flang_20210324-23 - Fix patch 4-add-test-cases-for-openmp-optimization.patch to correct test007 and test020 and change the way of measuring time in test008 -- Gitee