diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-05-31 21:18:39 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-05-31 21:18:39 +0000 |
commit | 6303331c3330222fef94eff8d8d35c99ca1d3e88 (patch) | |
tree | 99ef20c56f1bba3d53736e534b7e49f270169863 /libgo/runtime/go-runtime-error.c | |
parent | 2b5360d7477277e7e0f32a5bd5479afac819b5e1 (diff) | |
download | gcc-6303331c3330222fef94eff8d8d35c99ca1d3e88.zip gcc-6303331c3330222fef94eff8d8d35c99ca1d3e88.tar.gz gcc-6303331c3330222fef94eff8d8d35c99ca1d3e88.tar.bz2 |
compiler: optimize append of make
The gc compiler recognizes append(s, make([]T, n)...), and
generates code to directly zero the tail instead of allocating a
new slice and copying. This CL lets the Go frontend do basically
the same.
The difficulty is that at the point we handle append, there may
already be temporaries introduced (e.g. in order_evaluations),
which makes it hard to find the append-of-make pattern. The
compiler could "see through" the value of a temporary, but it is
only safe to do if the temporary is not assigned multiple times.
For this, we add tracking of assignments and uses for temporaries.
This also helps in optimizing non-escape slice make. We already
optimize non-escape slice make with constant len/cap to stack
allocation. But it failed to handle things like f(make([]T, n))
(where the slice doesn't escape and n is constant), because of
the temporary. With tracking of temporary assignments and uses,
it can handle this now as well.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/179597
From-SVN: r271822
Diffstat (limited to 'libgo/runtime/go-runtime-error.c')
-rw-r--r-- | libgo/runtime/go-runtime-error.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/libgo/runtime/go-runtime-error.c b/libgo/runtime/go-runtime-error.c index 5db3555..c9ccf98 100644 --- a/libgo/runtime/go-runtime-error.c +++ b/libgo/runtime/go-runtime-error.c @@ -38,21 +38,24 @@ enum memory locations. */ NIL_DEREFERENCE = 6, - /* Slice length or capacity out of bounds in make: negative or - overflow or length greater than capacity. */ - MAKE_SLICE_OUT_OF_BOUNDS = 7, + /* Slice length out of bounds in make: negative or overflow or length + greater than capacity. */ + MAKE_SLICE_LEN_OUT_OF_BOUNDS = 7, + + /* Slice capacity out of bounds in make: negative. */ + MAKE_SLICE_CAP_OUT_OF_BOUNDS = 8, /* Map capacity out of bounds in make: negative or overflow. */ - MAKE_MAP_OUT_OF_BOUNDS = 8, + MAKE_MAP_OUT_OF_BOUNDS = 9, /* Channel capacity out of bounds in make: negative or overflow. */ - MAKE_CHAN_OUT_OF_BOUNDS = 9, + MAKE_CHAN_OUT_OF_BOUNDS = 10, /* Integer division by zero. */ - DIVISION_BY_ZERO = 10, + DIVISION_BY_ZERO = 11, /* Go statement with nil function. */ - GO_NIL = 11 + GO_NIL = 12 }; extern void __go_runtime_error (int32) __attribute__ ((noreturn)); @@ -88,8 +91,11 @@ __go_runtime_error (int32 i) case NIL_DEREFERENCE: runtime_panicstring ("nil pointer dereference"); - case MAKE_SLICE_OUT_OF_BOUNDS: - runtime_panicstring ("make slice len or cap out of range"); + case MAKE_SLICE_LEN_OUT_OF_BOUNDS: + runtime_panicstring ("make slice len out of range"); + + case MAKE_SLICE_CAP_OUT_OF_BOUNDS: + runtime_panicstring ("make slice cap out of range"); case MAKE_MAP_OUT_OF_BOUNDS: runtime_panicstring ("make map len out of range"); |