Author: syang
Date: 2010-12-09 14:17:22 -0500 (Thu, 09 Dec 2010)
New Revision: 3427

Modified:
   trunk/osprey/common/com/intrn_entry.def
   trunk/osprey/wgen/wgen_expr.cxx
Log:
Fix to bug #586 about "unresolved symbol of __builtin_object_size()". 

Approved by: Jianxin


Modified: trunk/osprey/common/com/intrn_entry.def
===================================================================
--- trunk/osprey/common/com/intrn_entry.def     2010-12-09 01:28:24 UTC (rev 
3426)
+++ trunk/osprey/common/com/intrn_entry.def     2010-12-09 19:17:22 UTC (rev 
3427)
@@ -7671,6 +7671,11 @@
                 DOES_RETURN, NOT_ACTUAL, NOT_CGINTRINSIC, NOT_SLAVE, 
                 IRETURN_PPI4, "__ctype_tolower_loc", "CTYPE_TOLOWER_LOC", 
"__ctype_tolower_loc")
 
+/* corresponding to gcc extension __builtin_object_size()*/
+DEF_INTRN_ENTRY(INTRN_OBJ_SZ, "BUILTIN_OBJECT_SIZE", BYVAL, PURE, 
NO_SIDEEFFECTS, 
+                DOES_RETURN, ACTUAL, NOT_CGINTRINSIC, NOT_SLAVE, 
+                IRETURN_SZT, NULL, NULL, "dummy_name")
+
 /* END of DEF_INTRN_ENTRY */
 
 #if defined (DEF_INTRN_ENTRY)

Modified: trunk/osprey/wgen/wgen_expr.cxx
===================================================================
--- trunk/osprey/wgen/wgen_expr.cxx     2010-12-09 01:28:24 UTC (rev 3426)
+++ trunk/osprey/wgen/wgen_expr.cxx     2010-12-09 19:17:22 UTC (rev 3427)
@@ -5699,6 +5699,65 @@
 #endif // FE_GNU_4_2_0
 #endif // KEY
 
+
+// Following function is a quick kludge to bug# 586 reported in 
bugs.open64.net.
+// The problem is that open64's backend currently does not fold 
+// __builtin_object_size() into constant, causing "unresolved symbol" problem 
+// at link time.
+//
+// This function is part of GCC extension; gcc tries to fold this function in 
+// many places (see fold_builtin_object_size()@builtins.c for details), and it 
+// has a pass called "objsz" dedicated to that purpose (see tree-object-size.c 
for 
+// details).
+//
+// fold_builtin_object_size() is called prior to the generic -> gspin 
conversion;
+// it is able to fold some simple cases; but in general, most cases have to 
handled
+// by the "objsz" pass which relies on SSA. 
+//
+//   The value the function "__builtin_object_size(void* p, int type)" 
evaluated to 
+// depends on the capability of compiler data flow analysis. Basically, if 
compiler
+// reveals that pointer <p> points to object O with type T, it will return 
sizeof(T);
+// otherwise it returns "type < 2 ? -1 : 0".
+//
+//  This function simply substitute the "__builtin_object_size(p, ty)" with 
+//  "ty < 2 ? -1 : 0".
+//  
+static WN*
+Fold_Object_Size (WN* intrinsic_op) {
+
+    Is_True (WN_operator (intrinsic_op) == OPR_INTRINSIC_OP && 
+             WN_intrinsic (intrinsic_op) ==  INTRN_OBJ_SZ,
+             ("Invalid intrisic op"));
+    
+    // the rtype should be the type corresponing to high level type size_t
+    //
+    TYPE_ID rtype = WN_rtype (intrinsic_op);
+
+    // step 1: Get the 2nd actual of __builtin_object_size()
+    //
+    WN* arg1 = WN_kid0(WN_kid1(intrinsic_op));
+    arg1 = WN_COPY_Tree (arg1);
+    WN_DELETE_Tree (intrinsic_op);
+
+    // step 2: construct expression : "<arg1> < 2 ? -1 : 0"
+    // 
+
+    // step 2.1 create condition "<arg1> < 2".
+    //
+    WN* cond = WN_CreateExp2 (OPC_BI4LT,
+                              WN_Type_Conversion (arg1, MTYPE_I4),
+                              WN_CreateIntconst (OPC_I4INTCONST, 2));
+    
+    // step 2.2 create the selection exp
+    WN* res = WN_CreateExp3 (OPR_SELECT, MTYPE_I4, MTYPE_V, 
+                             cond,
+                             WN_CreateIntconst (OPC_I4INTCONST, -1),
+                             WN_CreateIntconst (OPC_I4INTCONST, 0));
+
+    res = WN_Type_Conversion (res, rtype);
+    return res;
+}
+
 WN * 
 WGEN_Expand_Expr (gs_t exp,
                  bool need_result,
@@ -9002,6 +9061,11 @@
                whirl_generated = TRUE;
                break;
        
+             case GSBI_BUILT_IN_OBJECT_SIZE:
+               iopc = INTRN_OBJ_SZ;
+               intrinsic_op = TRUE;
+               break;
+               
              case GSBI_BUILT_IN_POPCOUNT:
                iopc = INTRN_I4POPCNT;
                intrinsic_op = TRUE;
@@ -9439,6 +9503,12 @@
                                      iopc, num_args, ikids);
             WN_Set_Deref_If_Needed(wn);
 
+        if (iopc == INTRN_OBJ_SZ) {
+            // kludge to the undefined __builtin_object_size() problem (bug 
#586).  
+            //
+            wn = Fold_Object_Size (wn);
+        }
+
 #ifdef KEY
            if (cvt_to != MTYPE_UNKNOWN) // bug 8251
               wn = WN_Cvt (ret_mtype, cvt_to, wn);


------------------------------------------------------------------------------
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to