MCPcopy Index your code
hub / github.com/tinygo-org/tinygo / OptimizeStringToBytes

Function OptimizeStringToBytes

transform/rtcalls.go:16–72  ·  view source on GitHub ↗

OptimizeStringToBytes transforms runtime.stringToBytes(...) calls into const []byte slices whenever possible. This optimizes the following pattern: w.Write([]byte("foo")) where Write does not store to the slice.

(mod llvm.Module)

Source from the content-addressed store, hash-verified

14//
15// where Write does not store to the slice.
16func OptimizeStringToBytes(mod llvm.Module) {
17 stringToBytes := mod.NamedFunction("runtime.stringToBytes")
18 if stringToBytes.IsNil() {
19 // nothing to optimize
20 return
21 }
22
23 for _, call := range getUses(stringToBytes) {
24 strptr := call.Operand(0)
25 strlen := call.Operand(1)
26
27 // strptr is always constant because strings are always constant.
28
29 var pointerUses []llvm.Value
30 canConvertPointer := true
31 for _, use := range getUses(call) {
32 if use.IsAExtractValueInst().IsNil() {
33 // Expected an extractvalue, but this is something else.
34 canConvertPointer = false
35 break
36 }
37 switch use.Type().TypeKind() {
38 case llvm.IntegerTypeKind:
39 // A length (len or cap). Propagate the length value.
40 // This can always be done because the byte slice is always the
41 // same length as the original string.
42 use.ReplaceAllUsesWith(strlen)
43 use.EraseFromParentAsInstruction()
44 case llvm.PointerTypeKind:
45 // The string pointer itself.
46 if !isReadOnly(use) {
47 // There is a store to the byte slice. This means that none
48 // of the pointer uses can't be propagated.
49 canConvertPointer = false
50 break
51 }
52 // It may be that the pointer value can be propagated, if all of
53 // the pointer uses are readonly.
54 pointerUses = append(pointerUses, use)
55 default:
56 // should not happen
57 panic("unknown return type of runtime.stringToBytes: " + use.Type().String())
58 }
59 }
60 if canConvertPointer {
61 // All pointer uses are readonly, so they can be converted.
62 for _, use := range pointerUses {
63 use.ReplaceAllUsesWith(strptr)
64 use.EraseFromParentAsInstruction()
65 }
66
67 // Call to runtime.stringToBytes can be eliminated: both the input
68 // and the output is constant.
69 call.EraseFromParentAsInstruction()
70 }
71 }
72}
73

Callers 2

OptimizeFunction · 0.85

Calls 5

getUsesFunction · 0.85
isReadOnlyFunction · 0.85
IsNilMethod · 0.80
StringMethod · 0.65
TypeMethod · 0.45

Tested by 1