At one point, that function used to pretty much just call lang_hooks.types_compatible_p. Now it does more. Specifically, it can return TRUE even if the lang hook returns FALSE. That's a problem for the optimizers and causes performance regressions.
For example, I noticed that trivial trail recursion elimination isn't being done for Ada. I used the simple example: function Fact (I: Integer) return Integer is begin if I = 1 then return 1; else return I * Fact (I - 1); end if; end Fact; The problem is the operand "I - 1". The type "Integer" is really a subtype (of Integer'Base). So "I" is of that type. "I - 1", being an operand, is of type Integer'Base. So the call above actually has a conversion from the base type to the subtype. However, those two types look the same to tree_ssa_useless_type_conversion_1 even though the langhook uses the default and says they aren't. That means that gimplification omits the conversion which, in turn, means that the actual and formal aren't the same type if you just use the lang hook. Tail recursion declines to optimize it because of that. The following fixes it: *** tree-tailcall.c 28 Jul 2005 16:29:56 -0000 2.47 --- tree-tailcall.c 30 Sep 2005 18:39:38 -0000 *************** find_tail_calls (basic_block bb, struct *** 447,452 **** we emitted a suitable type conversion statement. */ if (!is_gimple_reg_type (TREE_TYPE (param)) ! || !lang_hooks.types_compatible_p (TREE_TYPE (param), ! TREE_TYPE (arg))) break; --- 447,452 ---- we emitted a suitable type conversion statement. */ if (!is_gimple_reg_type (TREE_TYPE (param)) ! || !tree_ssa_useless_type_conversion_1 (TREE_TYPE (param), ! TREE_TYPE (arg))) break; However, I think that *every* call to lang_hooks.types_compatible_p in the tree-*.c files (and possibly gimplify.c) except for the one in tree_ssa_useless_type_conversion_1 (there are 20 of them) ought to be handled the same as above. Comments?