Jian-Xin Lai
2012-07-31 08:15:45 UTC
Hi,
Could someone review the patch for open64 bug #969, #970? Thank you very much.
1. test case
#969 and #970 can be simplified to the following case:
struct I3 {
int a, b, c;
};
extern struct I3 foo();
void bar() {
struct I3 a;
a = foo();
}
The struct I1 can also be replaced by:
struct F3 {
float a, b, c;
};
2. IR dump
Open64 will allocate a temporary on stack for the return value. The IR
after MSTID lowering looks like:
MCALL 126 <1,51,foo> # flags 0x7e {line: 1/7}
I8I8LDID 1 <1,5,.preg_I8> T<5,.predef_I8,8> # $r1
I8STID 0 <2,2,_temp_.Mreturn.foo0> T<5,.predef_I8,8> {line: 0/0}
I8I8LDID 7 <1,5,.preg_I8> T<5,.predef_I8,8> # $r7
I8STID 8 <2,2,_temp_.Mreturn.foo0> T<5,.predef_I8,8> {line: 0/0}
[2]: _temp_.Mreturn.foo0 <2,2> Variable of type I1 (#53, KIND_STRUCT)
Address: 0(_temp_.Mreturn.foo0<2,2>) Alignment: 8 bytes
location: file (null), line 0
Flags: 0x00400000 temp, XLOCAL
Sclass: AUTO
[53]: I3 : (f: 0x1000 content_seen) size 12 M: STRUCT
0 a .predef_I4 (#4) align 4
fl:0x0000
4 b .predef_I4 (#4) align 4
fl:0x0000
8 c .predef_I4 (#4) align 4
fl:0x0001 last_field
The size of _temp_.Mreturn.foo0 is only 12 byte. The I8STID will
overwrite some other variables on stack. For float struct F3, two
F8STID will be generated.
3. Patch
Index: osprey/be/com/wn_lower.cxx
===================================================================
--- osprey/be/com/wn_lower.cxx (revision 3998)
+++ osprey/be/com/wn_lower.cxx (working copy)
@@ -7299,6 +7299,7 @@
}
else { // return via 1 or more return registers
TYPE_ID mtype, desc;
+ WN_OFFSET st_ofst = WN_store_offset(tree);
for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
if (i != 0)
WN_INSERT_BlockLast (block, wn); // insert the last STID created
@@ -7334,8 +7335,9 @@
}
#endif
wn = WN_CreateStid(OPR_STID, MTYPE_V, desc,
- WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+ st_ofst,
WN_st_idx(tree), Be_Type_Tbl(desc), n_rhs);
+ st_ofst += MTYPE_byte_size(mtype);
wn = lower_store (block, wn, actions);
WN_Set_Linenum(wn, current_srcpos);
}
@@ -7394,6 +7396,7 @@
}
else { // return via 1 or more return registers
WN *base_expr;
+ WN_OFFSET st_ofst = WN_store_offset(tree);
for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
if (i != 0)
WN_INSERT_BlockLast (block, wn); // insert the last STID created
@@ -7406,8 +7409,9 @@
// OSP-438: The type of Istore node should be a pointer to mtype.
// (Previously, we just use Be_Type_Tbl(mtype) as the type of Istore).
wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, mtype,
- WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+ st_ofst,
Make_Pointer_Type(Be_Type_Tbl(mtype),
FALSE), n_rhs, base_expr);
+ st_ofst += MTYPE_byte_size(mtype);
WN_Set_Linenum(wn, WN_Get_Linenum(tree));
wn = lower_store (block, wn, actions);
WN_Set_Linenum (wn, WN_Get_Linenum(tree));
@@ -12285,6 +12289,7 @@
("expected RETURN_VAL kid not type M"));
algn = TY_align(ty_idx);
+ WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
@@ -12312,15 +12317,14 @@
#endif
#if defined(TARG_PPC32)
n_rhs = WN_CreateLdid (OPR_LDID, mtype, desc,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
WN_st_idx(o_rhs), ty_idx_used);
#else
n_rhs = WN_CreateLdid (OPR_LDID, mtype, mtype,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
WN_st_idx(o_rhs), ty_idx_used);
#endif
+ ld_ofst += MTYPE_byte_size(mtype);
wn = WN_CreateStid(OPR_STID, MTYPE_V, mtype, preg, preg_st,
Be_Type_Tbl(mtype), n_rhs);
WN_Set_Linenum(wn, current_srcpos); // Bug 1268
@@ -12332,6 +12336,7 @@
("expected RETURN_VAL kid not type M"));
algn = TY_align(ty_idx);
+ WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
@@ -12340,10 +12345,10 @@
n_rhs = WN_kid0(o_rhs);
else n_rhs = WN_COPY_Tree(WN_kid0(o_rhs));
n_rhs = WN_CreateIload(OPR_ILOAD, mtype, mtype,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
ty_idx_used,
Make_Pointer_Type(ty_idx_used), n_rhs);
+ ld_ofst += MTYPE_byte_size(mtype);
n_rhs = lower_expr(block, n_rhs, actions);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);
@@ -12357,6 +12362,7 @@
Is_True(WN_operator(WN_kid1(o_rhs)) == OPR_INTCONST,
("expected RETURN_VAL's MLOAD kid to be of constant size"));
algn = TY_align(TY_pointed(WN_load_addr_ty(o_rhs)));
+ WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
@@ -12365,10 +12371,10 @@
n_rhs = WN_kid0(o_rhs);
else n_rhs = WN_COPY_Tree(WN_kid0(o_rhs));
n_rhs = WN_CreateIload(OPR_ILOAD, mtype, mtype,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
ty_idx_used,
Make_Pointer_Type(ty_idx_used), n_rhs);
+ ld_ofst += MTYPE_byte_size(mtype);
n_rhs = lower_expr(block, n_rhs, actions);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);
Index: osprey/common/com/x8664/targ_sim.cxx
===================================================================
--- osprey/common/com/x8664/targ_sim.cxx (revision 3998)
+++ osprey/common/com/x8664/targ_sim.cxx (working copy)
@@ -673,13 +673,13 @@
}
else {
if (classes[0] == X86_64_SSE_CLASS) {
- info.mtype[0] = SIM_INFO.dbl_type;
+ info.mtype[0] = (size > 4) ? MTYPE_F8 : MTYPE_F4;
info.preg[0] = PR_first_reg(SIM_INFO.dbl_results);
next_float_return_num = PR_last_reg(SIM_INFO.dbl_results);
next_int_return_num = PR_first_reg(SIM_INFO.int_results);
}
else {
- info.mtype[0] = SIM_INFO.int_type;
+ info.mtype[0] = (size > 4) ? MTYPE_I8 : MTYPE_I4;
info.preg[0] = PR_first_reg(SIM_INFO.int_results);
next_float_return_num = PR_first_reg(SIM_INFO.dbl_results);
next_int_return_num = PR_last_reg(SIM_INFO.int_results);
@@ -687,11 +687,11 @@
if (n > 1) {
if (classes[1] == X86_64_SSE_CLASS) {
- info.mtype[1] = SIM_INFO.dbl_type;
+ info.mtype[1] = (size > 12) ? MTYPE_F8 : MTYPE_F4;
info.preg[1] = next_float_return_num;
}
else {
- info.mtype[1] = SIM_INFO.int_type;
+ info.mtype[1] = (size > 12) ? MTYPE_I8 : MTYPE_I4;
info.preg[1] = next_int_return_num;
}
}
Could someone review the patch for open64 bug #969, #970? Thank you very much.
1. test case
#969 and #970 can be simplified to the following case:
struct I3 {
int a, b, c;
};
extern struct I3 foo();
void bar() {
struct I3 a;
a = foo();
}
The struct I1 can also be replaced by:
struct F3 {
float a, b, c;
};
2. IR dump
Open64 will allocate a temporary on stack for the return value. The IR
after MSTID lowering looks like:
MCALL 126 <1,51,foo> # flags 0x7e {line: 1/7}
I8I8LDID 1 <1,5,.preg_I8> T<5,.predef_I8,8> # $r1
I8STID 0 <2,2,_temp_.Mreturn.foo0> T<5,.predef_I8,8> {line: 0/0}
I8I8LDID 7 <1,5,.preg_I8> T<5,.predef_I8,8> # $r7
I8STID 8 <2,2,_temp_.Mreturn.foo0> T<5,.predef_I8,8> {line: 0/0}
[2]: _temp_.Mreturn.foo0 <2,2> Variable of type I1 (#53, KIND_STRUCT)
Address: 0(_temp_.Mreturn.foo0<2,2>) Alignment: 8 bytes
location: file (null), line 0
Flags: 0x00400000 temp, XLOCAL
Sclass: AUTO
[53]: I3 : (f: 0x1000 content_seen) size 12 M: STRUCT
0 a .predef_I4 (#4) align 4
fl:0x0000
4 b .predef_I4 (#4) align 4
fl:0x0000
8 c .predef_I4 (#4) align 4
fl:0x0001 last_field
The size of _temp_.Mreturn.foo0 is only 12 byte. The I8STID will
overwrite some other variables on stack. For float struct F3, two
F8STID will be generated.
3. Patch
Index: osprey/be/com/wn_lower.cxx
===================================================================
--- osprey/be/com/wn_lower.cxx (revision 3998)
+++ osprey/be/com/wn_lower.cxx (working copy)
@@ -7299,6 +7299,7 @@
}
else { // return via 1 or more return registers
TYPE_ID mtype, desc;
+ WN_OFFSET st_ofst = WN_store_offset(tree);
for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
if (i != 0)
WN_INSERT_BlockLast (block, wn); // insert the last STID created
@@ -7334,8 +7335,9 @@
}
#endif
wn = WN_CreateStid(OPR_STID, MTYPE_V, desc,
- WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+ st_ofst,
WN_st_idx(tree), Be_Type_Tbl(desc), n_rhs);
+ st_ofst += MTYPE_byte_size(mtype);
wn = lower_store (block, wn, actions);
WN_Set_Linenum(wn, current_srcpos);
}
@@ -7394,6 +7396,7 @@
}
else { // return via 1 or more return registers
WN *base_expr;
+ WN_OFFSET st_ofst = WN_store_offset(tree);
for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
if (i != 0)
WN_INSERT_BlockLast (block, wn); // insert the last STID created
@@ -7406,8 +7409,9 @@
// OSP-438: The type of Istore node should be a pointer to mtype.
// (Previously, we just use Be_Type_Tbl(mtype) as the type of Istore).
wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, mtype,
- WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+ st_ofst,
Make_Pointer_Type(Be_Type_Tbl(mtype),
FALSE), n_rhs, base_expr);
+ st_ofst += MTYPE_byte_size(mtype);
WN_Set_Linenum(wn, WN_Get_Linenum(tree));
wn = lower_store (block, wn, actions);
WN_Set_Linenum (wn, WN_Get_Linenum(tree));
@@ -12285,6 +12289,7 @@
("expected RETURN_VAL kid not type M"));
algn = TY_align(ty_idx);
+ WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
@@ -12312,15 +12317,14 @@
#endif
#if defined(TARG_PPC32)
n_rhs = WN_CreateLdid (OPR_LDID, mtype, desc,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
WN_st_idx(o_rhs), ty_idx_used);
#else
n_rhs = WN_CreateLdid (OPR_LDID, mtype, mtype,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
WN_st_idx(o_rhs), ty_idx_used);
#endif
+ ld_ofst += MTYPE_byte_size(mtype);
wn = WN_CreateStid(OPR_STID, MTYPE_V, mtype, preg, preg_st,
Be_Type_Tbl(mtype), n_rhs);
WN_Set_Linenum(wn, current_srcpos); // Bug 1268
@@ -12332,6 +12336,7 @@
("expected RETURN_VAL kid not type M"));
algn = TY_align(ty_idx);
+ WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
@@ -12340,10 +12345,10 @@
n_rhs = WN_kid0(o_rhs);
else n_rhs = WN_COPY_Tree(WN_kid0(o_rhs));
n_rhs = WN_CreateIload(OPR_ILOAD, mtype, mtype,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
ty_idx_used,
Make_Pointer_Type(ty_idx_used), n_rhs);
+ ld_ofst += MTYPE_byte_size(mtype);
n_rhs = lower_expr(block, n_rhs, actions);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);
@@ -12357,6 +12362,7 @@
Is_True(WN_operator(WN_kid1(o_rhs)) == OPR_INTCONST,
("expected RETURN_VAL's MLOAD kid to be of constant size"));
algn = TY_align(TY_pointed(WN_load_addr_ty(o_rhs)));
+ WN_OFFSET ld_ofst = WN_load_offset(o_rhs);
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
@@ -12365,10 +12371,10 @@
n_rhs = WN_kid0(o_rhs);
else n_rhs = WN_COPY_Tree(WN_kid0(o_rhs));
n_rhs = WN_CreateIload(OPR_ILOAD, mtype, mtype,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ ld_ofst,
ty_idx_used,
Make_Pointer_Type(ty_idx_used), n_rhs);
+ ld_ofst += MTYPE_byte_size(mtype);
n_rhs = lower_expr(block, n_rhs, actions);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);
Index: osprey/common/com/x8664/targ_sim.cxx
===================================================================
--- osprey/common/com/x8664/targ_sim.cxx (revision 3998)
+++ osprey/common/com/x8664/targ_sim.cxx (working copy)
@@ -673,13 +673,13 @@
}
else {
if (classes[0] == X86_64_SSE_CLASS) {
- info.mtype[0] = SIM_INFO.dbl_type;
+ info.mtype[0] = (size > 4) ? MTYPE_F8 : MTYPE_F4;
info.preg[0] = PR_first_reg(SIM_INFO.dbl_results);
next_float_return_num = PR_last_reg(SIM_INFO.dbl_results);
next_int_return_num = PR_first_reg(SIM_INFO.int_results);
}
else {
- info.mtype[0] = SIM_INFO.int_type;
+ info.mtype[0] = (size > 4) ? MTYPE_I8 : MTYPE_I4;
info.preg[0] = PR_first_reg(SIM_INFO.int_results);
next_float_return_num = PR_first_reg(SIM_INFO.dbl_results);
next_int_return_num = PR_last_reg(SIM_INFO.int_results);
@@ -687,11 +687,11 @@
if (n > 1) {
if (classes[1] == X86_64_SSE_CLASS) {
- info.mtype[1] = SIM_INFO.dbl_type;
+ info.mtype[1] = (size > 12) ? MTYPE_F8 : MTYPE_F4;
info.preg[1] = next_float_return_num;
}
else {
- info.mtype[1] = SIM_INFO.int_type;
+ info.mtype[1] = (size > 12) ? MTYPE_I8 : MTYPE_I4;
info.preg[1] = next_int_return_num;
}
}
--
Regards,
Lai Jian-Xin
Regards,
Lai Jian-Xin