Vladimir, On 25/01/13 16:36, Vladimir Makarov wrote: > On 01/25/2013 08:05 AM, Tom de Vries wrote: >> Vladimir, >> >> this patch adds analysis of register usage of functions for usage by IRA. >> >> The patch: >> - adds analysis in pass_final to track which hard registers are set or >> clobbered >> by the function body, and stores that information in a struct cgraph_node. >> - adds a target hook fn_other_hard_reg_usage to list hard registers that are >> set or clobbered by a call to a function, but are not listed as such in >> the >> function body, such as f.i. registers clobbered by veneers inserted by the >> linker. >> - adds a reg-note REG_CALL_DECL, to be able to easily link call_insns to >> their >> corresponding declaration, even after the calls may have been split into >> an >> insn (set register to function address) and a call_insn (call register), >> which >> can happen for f.i. sh, and mips with -mabi-calls. >> - uses the register analysis in IRA. >> - adds an option -fuse-caller-save to control the optimization, on by default >> at -Os and -O2 and higher.
<SNIP> >> Bootstrapped and reg-tested on x86_64, Ada inclusive. Build and reg-tested on >> mips, arm, ppc and sh. No issues found. OK for stage1 trunk? >> >> > Thanks for the patch. I'll look at it during the next week. > Did you get a chance to look at this? > Right now I see that the code is based on reload which uses > caller-saves.c. LRA does not use caller-saves.c at all. Right now we > have LRA support only for x86/x86-64 but the next version will probably > have a few more targets based on LRA. Fortunately, LRA modification > will be pretty easy with all this machinery. > I see, thanks for noticing that. Btw I'm now working on a testsuite construct dg-size-compare to be able to do dg-size-compare "text" "-fuse-caller-save" "<" "-fno-use-caller-save" which I could have used to create a generic testcase, which would have demonstrated that the optimization didn't work for x86_64. I'm also currently looking at how to use the analysis in LRA. AFAIU, in lra-constraints.c we do a backward scan over the insns, and keep track of how many calls we've seen (calls_num), and mark insns with that number. Then when looking at a live-range segment consisting of a def or use insn a and a following use insn b, we can compare the number of calls seen for each insn, and if they're not equal there is at least one call between the 2 insns, and if the corresponding hard register is clobbered by calls, we spill after insn a and restore before insn b. That is too coarse-grained to use with our analysis, since we need to know which calls occur in between insn a and insn b, and more precisely which registers those calls clobbered. I wonder though if we can do something similar: we keep an array call_clobbers_num[FIRST_PSEUDO_REG], initialized at 0 when we start scanning. When encountering a call, we increase the call_clobbers_num entries for the hard registers clobbered by the call. When encountering a use, we set the call_clobbers_num field of the use to call_clobbers_num[reg_renumber[original_regno]]. And when looking at a live-range segment, we compare the clobbers_num field of insn a and insn b, and if it is not equal, the hard register was clobbered by at least one call between insn a and insn b. Would that work? WDYT? > I am going to use ira-improv branch for some my future work for gcc4.9. > And I am going to regularly (about once per month) merge trunk into it. > So if you want you could use the branch for your work too. But this is > absolutely up to you. I don't mind if you put this patch directly to > the trunk at stage1 when the review is finished. > OK, I'd say stage1 then unless during review a reason pops up why it's better to use the ira-improv branch. Thanks, - Tom