Skip to content

Commit

Permalink
[opaque pointers][flang2] Remove redundant bitcast instructions and
Browse files Browse the repository at this point in the history
rewrite typed pointer with 'ptr'.

1. In the function 'make_bitcast()', a copy of the source with the type of
   the dest is returned when both the data types of source and dest are LL_PTR.
2. Due to the above modification, in function 'make_load()', flang should
   always get the load type from ll_type in the operand.
3. Remove the bitcast instruction used to store different types of results to
   the address of the return variable when processing ENTRY statements.
4. For some hard-coded typed pointers in code blocks controlled by conditional
   compilation macros, rewrite them with 'ptr'.
  • Loading branch information
xinliu-hnc authored and bryanpkc committed Dec 19, 2022
1 parent b09d207 commit 2d211cf
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 124 deletions.
4 changes: 2 additions & 2 deletions test/directives/getarg.f90
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ subroutine test()

call getarg(pos, arg)
end subroutine
! CHECK: bitcast ptr @f90_getarga to ptr,
! CHECK-NOT: bitcast ptr @getarg_ to ptr,
! CHECK: call void {{.*}}@f90_getarga(ptr {{.*}}, ptr {{.*}}, ptr {{.*}}, i64{{.*}}),
! CHECK-NOT: call void {{.*}}@getarg_(i8 {{.*}}, i8 {{.*}}, i64{{.*}}),
4 changes: 1 addition & 3 deletions test/directives/prefetch.f90
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ subroutine prefetch_dir(a1, a2)
end subroutine prefetch_dir

!! Ensure that the offset generated for the prefetch of a2(i + 256) is correct.
! CHECK-PREFETCH: [[a1:%[0-9]+]] = bitcast ptr %a1 to ptr
! CHECK-PREFETCH: [[a2:%[0-9]+]] = bitcast ptr %a2 to ptr
! CHECK-PREFETCH: [[a2base:%[0-9]+]] = getelementptr i8, ptr [[a2]], i64 1020
! CHECK-PREFETCH: [[a2base:%[0-9]+]] = getelementptr i8, ptr %a2, i64 1020
! CHECK-PREFETCH: [[i:%[0-9]+]] = load i32
! CHECK-PREFETCH: [[TMP1:%[0-9]+]] = sext i32 [[i]] to i64
! CHECK-PREFETCH: [[TMP2:%[0-9]+]] = mul nsw i64 [[TMP1]], 4
Expand Down
3 changes: 1 addition & 2 deletions test/llvm_ir_correct/save.f90
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ program msave
! NOSAVE: alloca i32
integer :: x
! NOSAVE: store i32 5, ptr %x
! SAVE: bitcast ptr @.BSS1 to ptr
! SAVE: store i32 5, ptr
! SAVE: store i32 5, ptr @.BSS1
x = 5
end program

Expand Down
53 changes: 16 additions & 37 deletions tools/flang2/flang2exe/cgmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4381,7 +4381,7 @@ gen_va_start(int ilix)
if (!va_start_defined) {
va_start_defined = true;
gname = (char *)getitem(LLVM_LONGTERM_AREA, strlen(va_start_name) + 35);
sprintf(gname, "declare void %s(i8*)", va_start_name);
sprintf(gname, "declare void %s(ptr)", va_start_name);
exfunc = (EXFUNC_LIST *)getitem(LLVM_LONGTERM_AREA, sizeof(EXFUNC_LIST));
memset(exfunc, 0, sizeof(EXFUNC_LIST));
exfunc->func_def = gname;
Expand Down Expand Up @@ -4596,7 +4596,7 @@ gen_va_end(int ilix)
if (!va_end_defined) {
va_end_defined = true;
gname = (char *)getitem(LLVM_LONGTERM_AREA, strlen(va_end_name) + 35);
sprintf(gname, "declare void %s(i8*)", va_end_name);
sprintf(gname, "declare void %s(ptr)", va_end_name);
exfunc = (EXFUNC_LIST *)getitem(LLVM_LONGTERM_AREA, sizeof(EXFUNC_LIST));
memset(exfunc, 0, sizeof(EXFUNC_LIST));
exfunc->func_def = gname;
Expand Down Expand Up @@ -6501,6 +6501,13 @@ make_bitcast(OPERAND *cast_op, LL_Type *rslt_type)
TMPS *new_tmps;
INSTR_LIST *Curr_Instr, *instr;

if (cast_op->ll_type->data_type == LL_PTR &&
rslt_type->data_type == LL_PTR) {
operand = gen_copy_op(cast_op);
operand->ll_type = rslt_type;
return operand;
}

if (strict_match(cast_op->ll_type, rslt_type))
return gen_copy_op(cast_op);

Expand Down Expand Up @@ -6962,11 +6969,7 @@ make_load(int ilix, OPERAND *load_op, LL_Type *rslt_type, MSZ msz,
return cse_op;
}
}
if (load_op->ot_type == OT_VAR && ll_type_is_pointer_to_function(rslt_type)) {
load_type = LLTYPE(load_op->val.sptr);
} else {
load_type = load_op->ll_type;
}
load_type = load_op->ll_type;

DBGTRACEIN2(" ilix %d, load op: %p", ilix, load_op)
DBGDUMPLLTYPE("result type ", rslt_type)
Expand Down Expand Up @@ -14238,43 +14241,19 @@ reset_expr_id(void)
static void
store_return_value_for_entry(OPERAND *p, int i_name)
{
TMPS *tmp = make_tmps();

if (p->ot_type != OT_VAR || !DT_ISCMPLX(DTYPEG(p->val.sptr))) {
print_token("\t");
print_tmp_name(tmp);
print_token(" = bitcast ");
write_type(make_generic_dummy_lltype());
print_token(" %");
print_token(get_entret_arg_name());
print_token(" to ");
write_type(make_ptr_lltype(p->ll_type));
print_nl();

print_token("\tstore ");
write_type(p->ll_type);
print_space(1);
write_operand(p, "", FLG_OMIT_OP_TYPE);
print_token(", ");

write_type(make_ptr_lltype(p->ll_type));
print_space(1);
print_tmp_name(tmp);
print_token(" %");
print_token(get_entret_arg_name());
print_token(", align 4\n");
} else {
TMPS *loadtmp;
/* %10 = bitcast i64* %__master_entry_rslt323 to <{float, float}>* */
print_token("\t");
print_tmp_name(tmp);
print_token(" = bitcast ");
write_type(make_generic_dummy_lltype());
print_token(" %");
print_token(get_entret_arg_name());
print_token(" to ");
write_type(p->ll_type);
print_nl();

/* %11 = load <{float, float}>, <{float, float}>* %cp1_300, align 4 */
/* %11 = load <{float, float}>, ptr %cp1_300, align 4 */
loadtmp = make_tmps();
print_token("\t");
print_tmp_name(loadtmp);
Expand All @@ -14286,16 +14265,16 @@ store_return_value_for_entry(OPERAND *p, int i_name)
write_operand(p, "", FLG_OMIT_OP_TYPE);
print_token(", align 4\n");

/* store <{float, float}> %11, <{float, float}>* %10, align 4 */
/* store <{float, float}> %11, ptr %__master_entry_rslt323, align 4 */
print_token("\tstore ");
write_type(p->ll_type->sub_types[0]);
print_space(1);
print_tmp_name(loadtmp);
print_token(", ");

write_type(p->ll_type);
print_space(1);
print_tmp_name(tmp);
print_token(" %");
print_token(get_entret_arg_name());
print_token(", align 4\n");
}

Expand Down
49 changes: 10 additions & 39 deletions tools/flang2/flang2exe/ll_ftn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ print_entry_subroutine(LL_Module *module)
LL_Type *dummy_type;
hashset_t formals; /* List of formal params for each entry trampoline */
sclen *pd_len = NULL, *pd_len_last = NULL;
bool has_char_args;
bool has_char_args, ret_scalar;
SPTR arg;

if (SYMLKG(sptr) <= NOSYM)
Expand Down Expand Up @@ -1129,23 +1129,7 @@ print_entry_subroutine(LL_Module *module)
} else {
rettype = DT_NONE;
}
if (fval && SCG(fval) != SC_DUMMY && SCG(fval) != SC_BASED) {
/* Bitcast fval which is local variable to i8*.
* We will pass this fval to master routine.
*/
tmp = make_tmps();
tmp->id = 0;
print_token("\t");
print_tmp_name(tmp);
print_token(" = bitcast ");
write_type(make_ptr_lltype(make_lltype_from_dtype(rettype)));
print_space(1);
print_token(SNAME(fval));
print_token(" to ");
write_type(dummy_type);
print_space(1);
print_nl();
}
ret_scalar = fval && SCG(fval) != SC_DUMMY && SCG(fval) != SC_BASED;

/* call the master */
if (gbl.arets) {
Expand All @@ -1169,12 +1153,11 @@ print_entry_subroutine(LL_Module *module)
/* if function, the second argument is the return value. The third argument
can also be a return value if the return value is a dummy argument
(happens when types are different). */
if (tmp) {
/* pass the tmp about */
if (ret_scalar) {
print_token(", ");
write_type(dummy_type);
print_space(1);
print_tmp_name(tmp);
print_token(SNAME(fval));
} else if (fval && SCG(fval) != SC_DUMMY && SCG(fval) != SC_BASED &&
fval != FVALG(gbl.currsub)) {
TY_KIND ThisIsABug; // FIXME
Expand Down Expand Up @@ -1227,7 +1210,7 @@ print_entry_subroutine(LL_Module *module)
}
if (i == 0)
continue; /* skip choice */
if (tmp && i == 1)
if (ret_scalar && i == 1)
continue; /* skip return value */
print_token(", ");
if (PASSBYVALG(sym))
Expand All @@ -1253,7 +1236,7 @@ print_entry_subroutine(LL_Module *module)
int sym = *dpdscp++;
if (i == 0) /* Skip choice */
continue;
if (tmp && i == 1)
if (ret_scalar && i == 1)
continue; /* Skip non-character, return value */
if (DTYG(DTYPEG(sym)) == TY_CHAR || DTYG(DTYPEG(sym)) == TY_NCHAR) {
clen = CLENG(sym);
Expand Down Expand Up @@ -1286,14 +1269,14 @@ print_entry_subroutine(LL_Module *module)

print_token(")\n\t");

if (tmp) {
if (ret_scalar) {
/* load return value and return it */
LL_Type *return_ll_type;

if (!DT_ISCMPLX(rettype) || !CMPLXFUNC_C) {
return_ll_type = make_lltype_from_dtype(rettype);

/* %1 = load i32, i32* %cp1_300, align 4 */
/* %1 = load i32, ptr %cp1_300, align 4 */
tmp = make_tmps();
print_tmp_name(tmp);
print_token(" = load ");
Expand All @@ -1309,21 +1292,9 @@ print_entry_subroutine(LL_Module *module)
print_nl();
} else {
/* complex entry, default C return conventions */
TMPS *addrtmp;
return_ll_type = make_lltype_from_abi_arg(&abi->arg[0]);

/* %1 = bitcast <{float, float}>* %cp1_300 to double* */
addrtmp = make_tmps();
print_tmp_name(addrtmp);
print_token(" = bitcast ");
write_type(make_ptr_lltype(make_lltype_from_dtype(rettype)));
print_space(1);
print_token(SNAME(fval));
print_token(" to ");
write_type(make_ptr_lltype(return_ll_type));
print_nl();

/* %2 = load double, double* %1, align 4 */
/* %1 = load double, ptr %cp1_300, align 4 */
tmp = make_tmps();
print_token("\t");
print_tmp_name(tmp);
Expand All @@ -1333,7 +1304,7 @@ print_entry_subroutine(LL_Module *module)
print_token(", ");
write_type(make_ptr_lltype(return_ll_type));
print_space(1);
print_tmp_name(addrtmp);
print_token(SNAME(fval));
print_token(", align 4\n");
}
if (abi->extend_abi_return) {
Expand Down
58 changes: 19 additions & 39 deletions tools/flang2/flang2exe/ll_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,8 +728,8 @@ ll_write_local_objects(FILE *out, LL_Function *function)
assert(object->sptr && strcmp(object->address.data, SNAME(object->sptr)),
"Missing local storage", object->sptr, ERR_Fatal);
LL_Type * llt = make_lltype_from_sptr((SPTR)object->sptr);
fprintf(out, "\t%s = bitcast %s* %s to %s",
SNAME(object->sptr), object->type->str, object->address.data, llt->str);
fprintf(out, "\t%s = bitcast ptr %s to %s",
SNAME(object->sptr), object->address.data, llt->str);
fputc('\n', out);
}
#endif
Expand All @@ -738,60 +738,40 @@ ll_write_local_objects(FILE *out, LL_Function *function)
if (XBIT(217, 0x1)) {
name = object->address.data;
if (ll_type_bytes(object->type) == 4) {
if (object->type->data_type == LL_I32) {
fprintf(out, "\tstore i32 %s, i32* %s, align 4\n",
POWER_STACK_32_BIT_NAN, name);
} else {
fprintf(out, "\t%s.temp = bitcast %s* %s to i32*\n", name,
object->type->str, name);
fprintf(out, "\tstore i32 %s, i32* %s.temp, align 4\n",
POWER_STACK_32_BIT_NAN, name);
}
fprintf(out, "\tstore i32 %s, ptr %s, align 4\n",
POWER_STACK_32_BIT_NAN, name);
} else if (ll_type_bytes(object->type) == 8) {
if (object->type->data_type == LL_I64) {
fprintf(out, "\tstore i64 %s, i64* %s, align 8\n",
POWER_STACK_64_BIT_NAN, name);
} else {
fprintf(out, "\t%s.temp = bitcast %s* %s to i64*\n", name,
object->type->str, name);
fprintf(out, "\tstore i64 %s, i64* %s.temp, align 8\n",
POWER_STACK_64_BIT_NAN, name);
}
fprintf(out, "\tstore i64 %s, ptr %s, align 8\n",
POWER_STACK_64_BIT_NAN, name);
} else if (ll_type_bytes(object->type) > 4) {
fprintf(out, "\t%s.temp = bitcast %s* %s to i32*\n", name,
object->type->str, name);
fprintf(out, "\t%s.ptr = alloca i32*, align 4\n", name);
fprintf(out, "\t%s.ptr = alloca ptr, align 4\n", name);
fprintf(out, "\t%s.count = alloca i32, align 4\n", name);
fprintf(out, "\tstore i32 %d, i32* %s.count, align 4\n",
fprintf(out, "\tstore i32 %d, ptr %s.count, align 4\n",
(int)(ll_type_bytes(object->type) / 4), name);
fprintf(out, "\t%s.temp0 = bitcast i32* %s.temp to i8*\n", name, name);
fprintf(out, "\t%s.temp1 = bitcast i32** %s.ptr to i8**\n", name, name);
fprintf(out, "\tstore i8* %s.temp0, i8** %s.temp1, align 4\n", name,
fprintf(out, "\tstore ptr %s, ptr %s.ptr, align 4\n", name,
name);
fprintf(out, "\tbr label %%L.st.init.%04d.1\n", curr_nan_label_count);
fprintf(out, "L.st.init.%04d.1:\n", curr_nan_label_count);
fprintf(out, "\t%s.temp2 = load i32, i32* %s.count, align 4\n", name,
fprintf(out, "\t%s.temp = load i32, ptr %s.count, align 4\n", name,
name);
fprintf(out, "\t%s.temp3 = icmp sle i32 %s.temp2, 0\n", name, name);
fprintf(out, "\t%s.temp0 = icmp sle i32 %s.temp, 0\n", name, name);
fprintf(out,
"\tbr i1 %s.temp3, label %%L.st.init.%04d.0,"
"\tbr i1 %s.temp0, label %%L.st.init.%04d.0,"
" label %%L.st.init.%04d.2\n",
name, curr_nan_label_count + 1, curr_nan_label_count);
fprintf(out, "L.st.init.%04d.2:\n", curr_nan_label_count);
fprintf(out, "\t%s.temp4 = load i32*, i32** %s.ptr, align 4\n", name,
fprintf(out, "\t%s.temp1 = load ptr, ptr %s.ptr, align 4\n", name,
name);
fprintf(out, "\tstore i32 %s, i32* %s.temp4, align 4\n",
fprintf(out, "\tstore i32 %s, ptr %s.temp1, align 4\n",
POWER_STACK_32_BIT_NAN, name);
fprintf(out, "\t%s.temp5 = bitcast i32* %s.temp4 to i8*\n", name, name);
fprintf(out, "\t%s.temp6 = getelementptr i8, i8* %s.temp5, i32 4\n",
fprintf(out, "\t%s.temp2 = getelementptr i8, ptr %s.temp1, i32 4\n",
name, name);
fprintf(out, "\t%s.temp7 = bitcast i32** %s.ptr to i8**\n", name, name);
fprintf(out, "\tstore i8* %s.temp6, i8** %s.temp7, align 4\n", name,
fprintf(out, "\tstore ptr %s.temp2, ptr %s.ptr, align 4\n", name,
name);
fprintf(out, "\t%s.temp8 = load i32, i32* %s.count, align 4\n", name,
fprintf(out, "\t%s.temp3 = load i32, ptr %s.count, align 4\n", name,
name);
fprintf(out, "\t%s.temp9 = sub i32 %s.temp8, 1\n", name, name);
fprintf(out, "\tstore i32 %s.temp9, i32* %s.count, align 4\n", name,
fprintf(out, "\t%s.temp4 = sub i32 %s.temp3, 1\n", name, name);
fprintf(out, "\tstore i32 %s.temp4, ptr %s.count, align 4\n", name,
name);
fprintf(out, "\tbr label %%L.st.init.%04d.1\n", curr_nan_label_count);
curr_nan_label_count++;
Expand Down
4 changes: 2 additions & 2 deletions tools/flang2/flang2exe/llassem_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ emit_init(DTYPE tdtype, ISZ_T tconval, ISZ_T *addr, ISZ_T *repeat_cnt,
#ifdef OMP_OFFLOAD_LLVM
// TODO ompaccel. Hackery for TGT structs. It must be fixed later.
if (flg.omptarget)
fprintf(ASMFIL, " i8* ");
fprintf(ASMFIL, " ptr ");
else
#endif
*cptr = put_next_member(*cptr);
Expand All @@ -285,7 +285,7 @@ emit_init(DTYPE tdtype, ISZ_T tconval, ISZ_T *addr, ISZ_T *repeat_cnt,
#ifdef OMP_OFFLOAD_LLVM
// TODO ompaccel. Hackery for TGT structs. It must be fixed later.
if (flg.omptarget)
fprintf(ASMFIL, " i8* ");
fprintf(ASMFIL, " ptr ");
else
#endif
*cptr = put_next_member(*cptr);
Expand Down

0 comments on commit 2d211cf

Please sign in to comment.