diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 313baf6c36d2860472afcee2792020f22b37098a..12aa9e3ad018fe203f5701951f18162375a6b75c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2010-07-21  Richard Guenther  <rguenther@suse.de>
+
+	PR middle-end/45013
+	* tree-ssa.c (useless_type_conversion_p): Dispatch to
+	gimple_types_compatible_p only when in lto.
+	* gimple.c (gimple_types_compatible_p): Use canonical types
+	to speed up comparison.
+
 2010-07-21  Richard Guenther  <rguenther@suse.de>
 
 	* tree-flow.h (referenced_var): Move define ...
diff --git a/gcc/gimple.c b/gcc/gimple.c
index a3b1bba97c53999bf4c1733ca85fc1ab8d9913c3..5ad79aaa071eada09e4173ee2cc03dd2f7c89fd6 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3360,6 +3360,12 @@ gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
   if (t1 == NULL_TREE || t2 == NULL_TREE)
     return 0;
 
+  /* If the types have been previously registered and found equal
+     they still are.  */
+  if (TYPE_CANONICAL (t1)
+      && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2))
+    return 1;
+
   /* Can't be the same type if the types don't have the same code.  */
   if (TREE_CODE (t1) != TREE_CODE (t2))
     return 0;
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 0be459118e5a59286475a2f906477a736480dadf..ba28c64fc83b7bfdd09bcca3bb98b491f80a70f6 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1426,7 +1426,8 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
      compared types.  */
   else if (AGGREGATE_TYPE_P (inner_type)
 	   && TREE_CODE (inner_type) == TREE_CODE (outer_type))
-    return gimple_types_compatible_p (outer_type, inner_type, false);
+    return (in_lto_p
+	    && gimple_types_compatible_p (outer_type, inner_type, false));
 
   return false;
 }