On Wed, Feb 13, 2019 at 5:21 PM Ian Lance Taylor <i...@golang.org> wrote: > > Nikhil Benesch noticed that changes in the GCC backend were making the > use of defer functions that call recover less efficient. A defer > thunk is a generated function that looks like this (this is the entire > function body): > > if !runtime.setdeferretaddr(&L) { > deferredFunction() > } > L: > > The idea is that the address of the label passed to setdeferretaddr is > the address to which deferredFunction returns. The code in canrecover > compares the return address of the function to this saved address to > see whether the recover function can return non-nil. This is > explained in marginally more detail at > https://www.airs.com/blog/archives/376 . > > When the return address does not match, the canrecover code does a > more costly check that requires unwinding the stack. What Nikhil > Benesch noticed is that we were always taking that fallback. > > It turned out that the label address passed to setdeferretaddr was not > the label to which the deferred function would return. And that was > because the epilogue was being duplicated by the bb-reorder pass, and > the label was moved to one copy of the epilogue while the deferred > function returned to the other epilogue. > > Of course there is no reason to duplicate the epilogue in such a small > function. One easy way to disable that epilogue duplication is to > compile the function with -Os. That is what this patch does. This > patch compiles all thunks, not just defer thunks, with -Os, but since > they are all small that does no harm. > > Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed > to mainline. > > Ian > > 2019-02-13 Ian Lance Taylor <i...@golang.org> > > * go-gcc.cc: #include "opts.h". > (Gcc_backend::function): Compile thunks with -Os.
This change revealed that changing function optimization attributes can cause the compiler to switch to the options stored in optimization_default_node. That caused the change to flag_strict_aliasing in go_imported_unsafe to be lost. I fixed that with this patch, which simply updates optimization_default_node. I don't know if there is a better way to do this. For this patch bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. Ian 2019-02-14 Ian Lance Taylor <i...@golang.org> * go-backend.c (go_imported_unsafe): Update optimization_default_node.
Index: go-backend.c =================================================================== --- go-backend.c (revision 268917) +++ go-backend.c (working copy) @@ -89,6 +89,7 @@ void go_imported_unsafe (void) { flag_strict_aliasing = false; + TREE_OPTIMIZATION (optimization_default_node)->x_flag_strict_aliasing = false; /* Let the backend know that the options have changed. */ targetm.override_options_after_change ();