* combine.c (try_combine): If insns need to be kept around,
authorjiez <jiez@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 25 Oct 2010 09:37:19 +0000 (09:37 +0000)
committerjiez <jiez@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 25 Oct 2010 09:37:19 +0000 (09:37 +0000)
check that they can be copied in the merged instruction.

testsuite/
g++.dg/opt/combine.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165911 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/combine.C [new file with mode: 0644]

index c48d9d7..f51500c 100644 (file)
@@ -1,3 +1,8 @@
+2010-10-25  Jie Zhang  <jie@codesourcery.com>
+
+       * combine.c (try_combine): If insns need to be kept around,
+       check that they can be copied in the merged instruction.
+
 2010-10-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * reg-stack.c (convert_regs_1): Return boolean value, true if the CFG
index 556228f..5ec7ee3 100644 (file)
@@ -2917,6 +2917,18 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
   else
     added_sets_0 = 0;
 
+  /* We are about to copy insns for the case where they need to be kept
+     around.  Check that they can be copied in the merged instruction.  */
+
+  if (targetm.cannot_copy_insn_p
+      && ((added_sets_2 && targetm.cannot_copy_insn_p (i2))
+         || (i1 && added_sets_1 && targetm.cannot_copy_insn_p (i1))
+         || (i0 && added_sets_0 && targetm.cannot_copy_insn_p (i0))))
+    {
+      undo_all ();
+      return 0;
+    }
+
   /* If the set in I2 needs to be kept around, we must make a copy of
      PATTERN (I2), so that when we substitute I1SRC for I1DEST in
      PATTERN (I2), we are only substituting for the original I1DEST, not into
index 5e202cb..76bd610 100644 (file)
@@ -1,3 +1,7 @@
+2010-10-25  Jie Zhang  <jie@codesourcery.com>
+
+       g++.dg/opt/combine.c: New test.
+
 2010-10-24  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/opt7.ad[sb]: New test.
diff --git a/gcc/testsuite/g++.dg/opt/combine.C b/gcc/testsuite/g++.dg/opt/combine.C
new file mode 100644 (file)
index 0000000..a9a4bb7
--- /dev/null
@@ -0,0 +1,72 @@
+// { dg-do assemble { target fpic } }
+// { dg-options "-O2 -fweb -fPIC -fvisibility=hidden" }
+
+class QBasicAtomicInt
+{
+public:
+  volatile int _q_value;
+  inline operator int () const {return _q_value;}
+};
+class QVariant;
+class QScriptContext;
+class QScriptEngine;
+class QScriptValue
+{
+public:
+  QVariant toVariant () const;
+};
+class QScriptDebuggerBackendPrivate
+{
+  static QScriptValue trace (QScriptContext *context);
+};
+template <typename T> struct QMetaTypeId { };
+template <typename T> struct QMetaTypeId2
+{
+  static inline int qt_metatype_id ()
+  {
+    return QMetaTypeId<T>::qt_metatype_id () ;
+  }
+};
+template <typename T> inline int qMetaTypeId (T * = 0)
+{
+  return QMetaTypeId2<T>::qt_metatype_id () ;
+}
+class QVariant { };
+template<typename T> inline T qvariant_cast (const QVariant &v)
+{
+  const int vid = qMetaTypeId<T> ((0)) ;
+};
+class QScriptContext
+{
+public: 
+  QScriptValue callee () const;
+};
+class QScriptEngine  
+{
+public:
+  static bool convertV2 (const QScriptValue &value , int type , void *ptr) ;
+};
+inline bool qscriptvalue_cast_helper (const QScriptValue &value , int type , void *ptr)
+{
+  return QScriptEngine::convertV2 (value, type, ptr) ;
+}
+template<typename T> T qscriptvalue_cast (const QScriptValue &value)
+{
+  T t;
+  const int id = qMetaTypeId<T> () ;
+  if ( qscriptvalue_cast_helper (value, id, &t))
+    return qvariant_cast<T> (value.toVariant ()) ;
+}
+template <> struct QMetaTypeId< QScriptDebuggerBackendPrivate* >
+{
+  static int qt_metatype_id ()
+  {
+    static QBasicAtomicInt metatype_id = { (0) };
+    return metatype_id;
+  }
+};
+QScriptValue QScriptDebuggerBackendPrivate::trace (QScriptContext *context)
+{
+  QScriptValue data = context->callee () ;
+  QScriptDebuggerBackendPrivate *self = qscriptvalue_cast<QScriptDebuggerBackendPrivate*> (data) ;
+}