------- Additional Comments From roger at eyesopen dot com 2004-12-19 23:51 ------- This is perhaps the most bizarre interaction I've yet come across in GCC. Under normal operation, reg_renumber is zero prior to register allocation, then in rest_of_handle_old_regalloc, allocate_reg_info is called to allocate per-pseudo information, which is used two or three function calls later by local_alloc (and should remain valid for the remainder of the function's compilation).
Unfortunately, between allocate_reg_info and local_alloc we call "regclass" which in this test case, unintentionally resets reg_renumber to zero! The incomplete and abridged call stack is reg_class -> scan_one_insn -> extract_insn -> recog_23 -> current_file_function_operand -> make_decl_rtl -> decl_assembler_name -> mangle_decl -> write_mangled_name -> write_encoding -> get_mostly_instantiated_function_type -> pop_access_scope -> pop_from_top_level -> pop_context_function_from. In the middle of pop_context_function_from is the line "reg_renumber = 0"! This problem is either a (i) middle-end issue, (ii) an rs6000 backend issue, or (iii) a C++ front-end issue. (i) I don't think that pop_context_function_from should (or needs to) reset reg_renumber to zero. I would hope that with cgraph, there is only ever a single function being expanded to RTL at a time, so reg_renumber can be left as is. Certainly, if we're not saving the value of reg_renumber (and the arrays contents) in push_function_context_to, then we shouldn't attempt to restore it afterwards. I'm currently testing this fix. (ii) This interaction can also be avoided if the rs6000's function current_file_function_operand used DECL_RTL_SET_P to test whether an identifier is local to a function prior to checking the result of DECL_RTL. This avoids the invocation of make_decl_rtl. Presumably, if we don't know the assembler name for this function, we can't be calling it :) [I'll test this fix next]. (iii) The problem might well be in the C++ front-end and its interaction with cgraph. It's unclear whether DECL_RTL should already have been set on current_function_decl prior to this point in rest_of_compilation. Clearly, this only appears to happen for C++ templates, so the rs6000 backend is perhaps reasonable in assuming DECL_RTL has been set by this point. The above analysis also explains why enabling various tree dumps resolves the segmentation fault, as we end up calling/caching decl_assembler_name for the current function before reaching local register allocation (avoiding this particular interaction). This is probably fall-out from the recent cgraph/varasm reorganizations that attempt to avoid calling decl_assembler_name until as late as physically possible. Calling it for the first time before or after local alloc probably works fine, calling it during (as is done on rs6000 targets) has unanticipated side-effects. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18683