From 6bd63ca3468290003609ba3244f2aa3bede4e36a Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 9 Jun 2015 18:37:26 -0700 Subject: [PATCH] cmd/compile: hide NodeList details in evconst The new code is a bit less efficient, but it does not involve altering the structure of any linked lists. This will make it easier to replace NodeLists with Node slices. We can return to a more efficient algorithm when NodeLists have been replaced. Passes toolstash -cmp. Change-Id: I0bb5ee75e7c0646e6d37fe558c8f0548729d8aa1 Reviewed-on: https://go-review.googlesource.com/20277 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/const.go | 49 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/cmd/compile/internal/gc/const.go b/src/cmd/compile/internal/gc/const.go index ed39dde724f..b825fa76525 100644 --- a/src/cmd/compile/internal/gc/const.go +++ b/src/cmd/compile/internal/gc/const.go @@ -543,33 +543,34 @@ func evconst(n *Node) { // merge adjacent constants in the argument list. case OADDSTR: - var nr *Node - var nl *Node - var l2 *NodeList - for l1 := n.List; l1 != nil; l1 = l1.Next { - if Isconst(l1.N, CTSTR) && l1.Next != nil && Isconst(l1.Next.N, CTSTR) { - // merge from l1 up to but not including l2 - var strs []string - l2 = l1 - for l2 != nil && Isconst(l2.N, CTSTR) { - nr = l2.N - strs = append(strs, nr.Val().U.(string)) - l2 = l2.Next - } - - nl = Nod(OXXX, nil, nil) - *nl = *l1.N - nl.Orig = nl - nl.SetVal(Val{strings.Join(strs, "")}) - l1.N = nl - l1.Next = l2 + // TODO: We make a copy of n.List in order to abstract + // away the details of deleting elements. + // Once n.List is some kind of Node slice, + // re-implement using deletion. + var l *NodeList // replacement list + for l1 := n.List; l1 != nil; { + if !Isconst(l1.N, CTSTR) || l1.Next == nil || !Isconst(l1.Next.N, CTSTR) { + // non-constant string or solitary constant string + l = list(l, l1.N) + l1 = l1.Next + continue } - } - // fix list end pointer. - for l2 := n.List; l2 != nil; l2 = l2.Next { - n.List.End = l2 + first := l1.N + + // merge run of constants + var strs []string + for ; l1 != nil && Isconst(l1.N, CTSTR); l1 = l1.Next { + strs = append(strs, l1.N.Val().U.(string)) + } + + nl := Nod(OXXX, nil, nil) + *nl = *first + nl.Orig = nl + nl.SetVal(Val{strings.Join(strs, "")}) + l = list(l, nl) } + n.List = l // collapse single-constant list to single constant. if count(n.List) == 1 && Isconst(n.List.N, CTSTR) {