GoPLS Viewer

Home|gopls/go/pointer/opt.go
1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package pointer
6
7// This file implements renumbering, a pre-solver optimization to
8// improve the efficiency of the solver's points-to set representation.
9//
10// TODO(adonovan): rename file "renumber.go"
11
12import "fmt"
13
14// renumber permutes a.nodes so that all nodes within an addressable
15// object appear before all non-addressable nodes, maintaining the
16// order of nodes within the same object (as required by offsetAddr).
17//
18// renumber must update every nodeid in the analysis (constraints,
19// Pointers, callgraph, etc) to reflect the new ordering.
20//
21// This is an optimisation to increase the locality and efficiency of
22// sparse representations of points-to sets.  (Typically only about
23// 20% of nodes are within an object.)
24//
25// NB: nodes added during solving (e.g. for reflection, SetFinalizer)
26// will be appended to the end.
27//
28// Renumbering makes the PTA log inscrutable.  To aid debugging, later
29// phases (e.g. HVN) must not rely on it having occurred.
30func (a *analysisrenumber() {
31    if a.log != nil {
32        fmt.Fprintf(a.log"\n\n==== Renumbering\n\n")
33    }
34
35    N := nodeid(len(a.nodes))
36    newNodes := make([]*nodeN)
37    renumbering := make([]nodeidN// maps old to new
38
39    var ij nodeid
40
41    // The zero node is special.
42    newNodes[j] = a.nodes[i]
43    renumbering[i] = j
44    i++
45    j++
46
47    // Pass 1: object nodes.
48    for i < N {
49        obj := a.nodes[i].obj
50        if obj == nil {
51            i++
52            continue
53        }
54
55        end := i + nodeid(obj.size)
56        for i < end {
57            newNodes[j] = a.nodes[i]
58            renumbering[i] = j
59            i++
60            j++
61        }
62    }
63    nobj := j
64
65    // Pass 2: non-object nodes.
66    for i = 1i < N; {
67        obj := a.nodes[i].obj
68        if obj != nil {
69            i += nodeid(obj.size)
70            continue
71        }
72
73        newNodes[j] = a.nodes[i]
74        renumbering[i] = j
75        i++
76        j++
77    }
78
79    if j != N {
80        panic(fmt.Sprintf("internal error: j=%d, N=%d"jN))
81    }
82
83    // Log the remapping table.
84    if a.log != nil {
85        fmt.Fprintf(a.log"Renumbering nodes to improve density:\n")
86        fmt.Fprintf(a.log"(%d object nodes of %d total)\n"nobjN)
87        for oldnew := range renumbering {
88            fmt.Fprintf(a.log"\tn%d -> n%d\n"oldnew)
89        }
90    }
91
92    // Now renumber all existing nodeids to use the new node permutation.
93    // It is critical that all reachable nodeids are accounted for!
94
95    // Renumber nodeids in queried Pointers.
96    for vptr := range a.result.Queries {
97        ptr.n = renumbering[ptr.n]
98        a.result.Queries[v] = ptr
99    }
100    for vptr := range a.result.IndirectQueries {
101        ptr.n = renumbering[ptr.n]
102        a.result.IndirectQueries[v] = ptr
103    }
104    for _queries := range a.config.extendedQueries {
105        for _query := range queries {
106            if query.ptr != nil {
107                query.ptr.n = renumbering[query.ptr.n]
108            }
109        }
110    }
111
112    // Renumber nodeids in global objects.
113    for vid := range a.globalobj {
114        a.globalobj[v] = renumbering[id]
115    }
116
117    // Renumber nodeids in constraints.
118    for _c := range a.constraints {
119        c.renumber(renumbering)
120    }
121
122    // Renumber nodeids in the call graph.
123    for _cgn := range a.cgnodes {
124        cgn.obj = renumbering[cgn.obj]
125        for _site := range cgn.sites {
126            site.targets = renumbering[site.targets]
127        }
128    }
129
130    a.nodes = newNodes
131}
132
MembersX
analysis.renumber.BlockStmt.RangeStmt_2136.old
analysis.renumber.RangeStmt_2410.ptr
analysis.renumber.RangeStmt_2510.v
analysis.renumber.RangeStmt_2833.id
analysis.renumber.a
analysis.renumber.renumbering
analysis.renumber.nobj
analysis.renumber.RangeStmt_3048.cgn
analysis.renumber.RangeStmt_3048.BlockStmt.RangeStmt_3115.site
analysis.renumber
analysis.renumber.RangeStmt_2626.queries
analysis.renumber.RangeStmt_2943.c
analysis.renumber.RangeStmt_2510.ptr
analysis.renumber.BlockStmt.obj
analysis.renumber.BlockStmt.RangeStmt_2136.new
analysis.renumber.RangeStmt_2410.v
analysis.renumber.j
analysis.renumber.RangeStmt_2626.BlockStmt.RangeStmt_2679.query
analysis.renumber.RangeStmt_2833.v
analysis.renumber.N
analysis.renumber.newNodes
analysis.renumber.i
Members
X