Discussion:
[Open64-devel] r4037 - trunk/osprey/be/com
s***@open64.net
2012-10-16 10:39:47 UTC
Permalink
Author: laijx
Date: 2012-10-16 06:39:46 -0400 (Tue, 16 Oct 2012)
New Revision: 4037

Modified:
trunk/osprey/be/com/wn_lower.cxx
Log:
Fix bug #969, #970.

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.

Approved by Sun Chan. Thanks Huan Luo to test this patch on PPC.



Modified: trunk/osprey/be/com/wn_lower.cxx
===================================================================
--- trunk/osprey/be/com/wn_lower.cxx 2012-10-12 13:51:07 UTC (rev 4036)
+++ trunk/osprey/be/com/wn_lower.cxx 2012-10-16 10:39:46 UTC (rev 4037)
@@ -7250,6 +7250,30 @@

/* ====================================================================
*
+ * TYPE_ID adjust_type_for_return_info(TYPE_ID& rtype, INT32 size)
+ *
+ * adjust the desc and ret type for return info according to the size.
+ * ==================================================================== */
+static TYPE_ID adjust_type_for_return_info(TYPE_ID& rtype, INT32 size)
+{
+ if (MTYPE_byte_size(rtype) <= size)
+ return rtype;
+
+ INT align = MTYPE_is_integral(rtype) ? 1 : 4;
+ TYPE_ID desc = Mtype_AlignmentClass(align, MTYPE_type_class(rtype));
+ Is_True(desc != MTYPE_UNKNOWN,
+ ("Unable to find the type %s with align %d", Mtype_Name(rtype), align));
+ while (MTYPE_byte_size(desc) < size) {
+ desc = Mtype_next_alignment(desc);
+ }
+ // there is no CVT for non-integer type, change the rtype to desc
+ if (!MTYPE_is_integral(rtype) && rtype != desc)
+ rtype = desc;
+ return desc;
+}
+
+/* ====================================================================
+ *
* WN *lower_return_mstid(WN *block, WN *tree, LOWER_ACTIONS actions)
*
* "tree" must be an MSTID whose kid is MLDID of Return_Val_Preg (-1).
@@ -7299,43 +7323,25 @@
}
else { // return via 1 or more return registers
TYPE_ID mtype, desc;
+ UINT copied = 0;
for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
if (i != 0)
WN_INSERT_BlockLast (block, wn); // insert the last STID created
mtype = RETURN_INFO_mtype(return_info, i);
- desc = mtype;
-#ifdef KEY
- if (MTYPE_byte_size(mtype) > TY_size(ty_idx) && !MTYPE_float(mtype)){
- desc = Mtype_AlignmentClass(1, MTYPE_type_class(mtype));
- while (MTYPE_byte_size(desc) < TY_size(ty_idx))
- desc = Mtype_next_alignment(desc);
- }
-#endif
+ desc = adjust_type_for_return_info(mtype, TY_size(ty_idx) - copied);
preg_st = Standard_Preg_For_Mtype(mtype);
-
-#if defined(TARG_PPC32)
- if (preg_st == Int_Preg) {
- UINT rem = TY_size(ty_idx) - i * 4;
- if (1 == rem) desc = MTYPE_I1;
- if (2 == rem) desc = MTYPE_I2;
- }
n_rhs = WN_CreateLdid(OPR_LDID, mtype, desc,
RETURN_INFO_preg(return_info, i), preg_st,
Be_Type_Tbl(mtype));
-#else
- n_rhs = WN_CreateLdid(OPR_LDID, mtype,mtype,
- RETURN_INFO_preg(return_info, i), preg_st,
- Be_Type_Tbl(mtype));
-#endif
-
#ifndef KEY
if (TY_align(ST_type(WN_st(tree))) < MTYPE_alignment(mtype)) {
DevWarn("return_info struct alignment is smaller than register size, may produce wrong results");
}
#endif
wn = WN_CreateStid(OPR_STID, MTYPE_V, desc,
- WN_store_offset(tree)+i*MTYPE_byte_size(mtype),
+ WN_store_offset(tree) + copied,
WN_st_idx(tree), Be_Type_Tbl(desc), n_rhs);
+ copied += MTYPE_byte_size(desc);
wn = lower_store (block, wn, actions);
WN_Set_Linenum(wn, current_srcpos);
}
@@ -7359,7 +7365,8 @@
ST *preg_st;
WN *n_rhs;
WN *wn = NULL; // init to prevent upward-exposed use
- RETURN_INFO return_info = Get_Return_Info(WN_ty(WN_kid0(tree)),
+ TY_IDX ty_idx = WN_ty(WN_kid0(tree));
+ RETURN_INFO return_info = Get_Return_Info(ty_idx,
Complex_Not_Simulated
#ifdef TARG_X8664
, last_call_ff2c_abi
@@ -7394,20 +7401,23 @@
}
else { // return via 1 or more return registers
WN *base_expr;
+ UINT copied = 0;
for (INT32 i = 0; i < RETURN_INFO_count(return_info); i++) {
if (i != 0)
WN_INSERT_BlockLast (block, wn); // insert the last STID created
mtype = RETURN_INFO_mtype(return_info, i);
+ TYPE_ID desc = adjust_type_for_return_info(mtype, TY_size(ty_idx) - copied);
preg_st = Standard_Preg_For_Mtype(mtype);
- n_rhs = WN_CreateLdid(OPR_LDID, mtype, mtype,
+ n_rhs = WN_CreateLdid(OPR_LDID, mtype, desc,
RETURN_INFO_preg(return_info, i), preg_st,
Be_Type_Tbl(mtype));
base_expr = WN_COPY_Tree(WN_kid1(tree));
// 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),
+ wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc,
+ WN_store_offset(tree) + copied,
Make_Pointer_Type(Be_Type_Tbl(mtype), FALSE), n_rhs, base_expr);
+ copied += MTYPE_byte_size(desc);
WN_Set_Linenum(wn, WN_Get_Linenum(tree));
wn = lower_store (block, wn, actions);
WN_Set_Linenum (wn, WN_Get_Linenum(tree));
@@ -12285,42 +12295,24 @@
("expected RETURN_VAL kid not type M"));

algn = TY_align(ty_idx);
+ UINT copied = 0;
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
ty_idx_used = Be_Type_Tbl(mtype);
Set_TY_align(ty_idx_used, algn);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);
-#if defined(TARG_PPC32)
- TYPE_ID desc = mtype;
- if (preg_st == Int_Preg) {
- UINT rem = TY_size(ty_idx) - i * 4;
- if (1 == rem) desc = MTYPE_I1;
- if (2 == rem) desc = MTYPE_I2;
- }
-#endif
-#ifdef KEY // bug 12812
+ TYPE_ID desc = adjust_type_for_return_info(mtype, TY_size(ty_idx) - copied);
+
if (WN_opcode(o_rhs) == OPC_MMLDID && WN_st(o_rhs) == Return_Val_Preg)
-#if defined(TARG_PPC32)
- n_rhs = WN_CreateLdid(OPR_LDID, mtype, desc, preg, preg_st,
+ n_rhs = WN_CreateLdid(OPR_LDID, mtype, desc, preg, preg_st,
Be_Type_Tbl(mtype));
-#else
- n_rhs = WN_CreateLdid(OPR_LDID, mtype, mtype, preg, preg_st,
- Be_Type_Tbl(mtype));
-#endif
else
-#endif
-#if defined(TARG_PPC32)
- n_rhs = WN_CreateLdid (OPR_LDID, mtype, desc,
- WN_load_offset(o_rhs)
- + i * MTYPE_byte_size(mtype),
+ n_rhs = WN_CreateLdid (OPR_LDID, mtype, desc,
+ WN_load_offset(o_rhs) + copied,
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),
- WN_st_idx(o_rhs), ty_idx_used);
-#endif
+
+ copied += MTYPE_byte_size(desc);
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,18 +12324,20 @@
("expected RETURN_VAL kid not type M"));

algn = TY_align(ty_idx);
+ UINT copied = 0;
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
+ TYPE_ID desc = adjust_type_for_return_info(mtype, TY_size(ty_idx) - copied);
ty_idx_used = Be_Type_Tbl(mtype);
Set_TY_align(ty_idx_used, algn);
if (i == 0)
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),
+ n_rhs = WN_CreateIload(OPR_ILOAD, mtype, desc,
+ WN_load_offset(o_rhs) + copied,
ty_idx_used,
Make_Pointer_Type(ty_idx_used), n_rhs);
+ copied += MTYPE_byte_size(desc);
n_rhs = lower_expr(block, n_rhs, actions);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);
@@ -12357,18 +12351,20 @@
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)));
+ UINT copied = 0;
for (i = 0; i < RETURN_INFO_count(return_info); i++) {
mtype = RETURN_INFO_mtype(return_info, i);
+ TYPE_ID desc = adjust_type_for_return_info(mtype, TY_size(ty_idx) - copied);
ty_idx_used = Be_Type_Tbl(mtype);
Set_TY_align(ty_idx_used, algn);
if (i == 0)
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),
+ n_rhs = WN_CreateIload(OPR_ILOAD, mtype, desc,
+ WN_load_offset(o_rhs) + copied,
ty_idx_used,
Make_Pointer_Type(ty_idx_used), n_rhs);
+ copied += MTYPE_byte_size(desc);
n_rhs = lower_expr(block, n_rhs, actions);
preg = RETURN_INFO_preg (return_info, i);
preg_st = Standard_Preg_For_Mtype(mtype);

Loading...