From 75102afce77f1376b0aab3f1d5fee9b881d0f68a Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 5 Nov 2015 14:59:47 -0800 Subject: [dev.ssa] cmd/compile: better register allocation Use a more precise computation of next use. It properly detects lifetime holes and deallocates values during those holes. It also uses a more precise version of distance to next use which affects which values get spilled. Change-Id: I49eb3ebe2d2cb64842ecdaa7fb4f3792f8afb90b Reviewed-on: https://go-review.googlesource.com/16760 Run-TryBot: Keith Randall Reviewed-by: David Chase --- src/cmd/compile/internal/ssa/sparsemap.go | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/cmd/compile/internal/ssa/sparsemap.go (limited to 'src/cmd/compile/internal/ssa/sparsemap.go') diff --git a/src/cmd/compile/internal/ssa/sparsemap.go b/src/cmd/compile/internal/ssa/sparsemap.go new file mode 100644 index 0000000000..6c0043b230 --- /dev/null +++ b/src/cmd/compile/internal/ssa/sparsemap.go @@ -0,0 +1,69 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ssa + +// from http://research.swtch.com/sparse +// in turn, from Briggs and Torczon + +type sparseEntry struct { + key ID + val int32 +} + +type sparseMap struct { + dense []sparseEntry + sparse []int +} + +// newSparseMap returns a sparseMap that can map +// integers between 0 and n-1 to int32s. +func newSparseMap(n int) *sparseMap { + return &sparseMap{nil, make([]int, n)} +} + +func (s *sparseMap) size() int { + return len(s.dense) +} + +func (s *sparseMap) contains(k ID) bool { + i := s.sparse[k] + return i < len(s.dense) && s.dense[i].key == k +} + +func (s *sparseMap) get(k ID) int32 { + i := s.sparse[k] + if i < len(s.dense) && s.dense[i].key == k { + return s.dense[i].val + } + return -1 +} + +func (s *sparseMap) set(k ID, v int32) { + i := s.sparse[k] + if i < len(s.dense) && s.dense[i].key == k { + s.dense[i].val = v + return + } + s.dense = append(s.dense, sparseEntry{k, v}) + s.sparse[k] = len(s.dense) - 1 +} + +func (s *sparseMap) remove(k ID) { + i := s.sparse[k] + if i < len(s.dense) && s.dense[i].key == k { + y := s.dense[len(s.dense)-1] + s.dense[i] = y + s.sparse[y.key] = i + s.dense = s.dense[:len(s.dense)-1] + } +} + +func (s *sparseMap) clear() { + s.dense = s.dense[:0] +} + +func (s *sparseMap) contents() []sparseEntry { + return s.dense +} -- cgit v1.3