On 05/19/2014 07:30 AM, Tom de Vries wrote: > + for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn)) > + { > + HARD_REG_SET insn_used_regs; > + > + if (!NONDEBUG_INSN_P (insn)) > + continue; > + > + find_all_hard_reg_sets (insn, &insn_used_regs, false); > + > + if (CALL_P (insn) > + && !get_call_reg_set_usage (insn, &insn_used_regs, call_used_reg_set)) > + { > + CLEAR_HARD_REG_SET (node->function_used_regs); > + return; > + } > + > + IOR_HARD_REG_SET (node->function_used_regs, insn_used_regs); > + }
As an aside, wouldn't it work out better if we collect into a local variable instead of writing to memory here in node->function_used_regs each time? But not the main point... Let's suppose that we've got a rather large function, with only local calls for which we can acquire usage. Let's suppose that even one of those callees further calls something else, such that insn_used_regs == call_used_reg_set. We fill node->function_used_regs immediately, but keep scanning the rest of the large function. > + > + /* Be conservative - mark fixed and global registers as used. */ > + IOR_HARD_REG_SET (node->function_used_regs, fixed_reg_set); > + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) > + if (global_regs[i]) > + SET_HARD_REG_BIT (node->function_used_regs, i); > + > +#ifdef STACK_REGS > + /* Handle STACK_REGS conservatively, since the df-framework does not > + provide accurate information for them. */ > + > + for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++) > + SET_HARD_REG_BIT (node->function_used_regs, i); > +#endif > + > + node->function_used_regs_valid = 1; Wouldn't it be better to compare the collected function_used_regs; if it contains all of call_used_reg_set, decline to set function_used_regs_valid. That way, we'll early exit from the above loop whenever we see that we can't improve over the default call-clobber set. Although perhaps function_used_regs_valid is no longer the best name in that case... r~