On Mon, Feb 11, 2013 at 06:15:05PM -0600, Aldy Hernandez wrote: > How does this look?
Looks good to me. > Jakub, what's this you mention in the PR about caching > __optimize__((3))? You also mention I shouldn't compare against > this_target_optabs, but default_target_optabs. But what if > this_target_optabs has changed? (See patch). The reason for that is that this_target_optabs could at that point be simply whatever optabs used the last parsed function. this_target_optabs changes only either because of optimize attribute (not sure if MIPS as the only switchable target? supports that), or because of mips_set_mips16_mode. I think invoke_set_current_function_hook invokes the target hook after the code you've changed, so I'd say it should work fine even on MIPS. CCing Richard for that anyway. > > Tested on x86-64 Linux. It would be nice if someone with access to > a SWITCHABLE_TARGET platform (mips) could also test this. A few nits below. I'm not sure about the behavior of multiple optimize attributes either, let's try it and see how it is handled right now (ignoring optabs). > @@ -6184,6 +6184,41 @@ init_optabs (void) > targetm.init_libfuncs (); > } > > +/* Recompute the optabs. If they have changed, save the new set of > + optabs in the optimization node OPTNODE. */ > + > +void > +save_optabs_if_changed (tree optnode) > +{ > + struct target_optabs *save_target_optabs = this_target_optabs; > + struct target_optabs *tmp_target_optabs = XNEW (struct target_optabs); > + > + /* Generate a new set of optabs into tmp_target_optabs. */ > + memset (tmp_target_optabs, 0, sizeof (struct target_optabs)); I think you should just use XCNEW and drop the memset. > + this_target_optabs = tmp_target_optabs; > + init_all_optabs (); > + this_target_optabs = save_target_optabs; > + > + /* If the optabs changed, record it in the node. */ > + if (memcmp (tmp_target_optabs, this_target_optabs, > + sizeof (struct target_optabs))) > + { > + /* ?? An existing entry in TREE_OPTIMIZATION_OPTABS indicates > + multiple ((optimize)) attributes for the same function. Is > + this even valid? For now, just clobber the existing entry > + with the new optabs. */ > + if (TREE_OPTIMIZATION_OPTABS (optnode)) > + free (TREE_OPTIMIZATION_OPTABS (optnode)); > + > + TREE_OPTIMIZATION_OPTABS (optnode) = tmp_target_optabs; > + } > + else > + { > + TREE_OPTIMIZATION_OPTABS (optnode) = NULL; > + free (tmp_target_optabs); Shouldn't this (and above) be XDELETE to match the allocation style? Jakub