aboutsummaryrefslogtreecommitdiffhomepage
path: root/transform/maps.go
blob: 359d9cc575a79c8de0c6d1c665df2e296e465079 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package transform

import (
	"tinygo.org/x/go-llvm"
)

// OptimizeMaps eliminates created but unused maps.
//
// In the future, this should statically allocate created but never modified
// maps. This has not yet been implemented, however.
func OptimizeMaps(mod llvm.Module) {
	hashmapMake := mod.NamedFunction("runtime.hashmapMake")
	if hashmapMake.IsNil() {
		// nothing to optimize
		return
	}

	hashmapBinarySet := mod.NamedFunction("runtime.hashmapBinarySet")
	hashmapStringSet := mod.NamedFunction("runtime.hashmapStringSet")

	for _, makeInst := range getUses(hashmapMake) {
		updateInsts := []llvm.Value{}
		unknownUses := false // are there any uses other than setting a value?

		for _, use := range getUses(makeInst) {
			if use := use.IsACallInst(); !use.IsNil() {
				switch use.CalledValue() {
				case hashmapBinarySet, hashmapStringSet:
					updateInsts = append(updateInsts, use)
				default:
					unknownUses = true
				}
			} else {
				unknownUses = true
			}
		}

		if !unknownUses {
			// This map can be entirely removed, as it is only created but never
			// used.
			for _, inst := range updateInsts {
				inst.EraseFromParentAsInstruction()
			}
			makeInst.EraseFromParentAsInstruction()
		}
	}
}