diff options
author | Elias Naur <[email protected]> | 2024-10-14 18:59:07 +0200 |
---|---|---|
committer | Ayke <[email protected]> | 2024-10-18 17:42:20 +0200 |
commit | 539cc5c47bb1bc46bcaf663d8f963670a7fbb111 (patch) | |
tree | a77a2c8ee9771317b9ef02c52cb51dbc57c62c88 | |
parent | 45cc5b58cd8fa164c60ef72c934e9fe16f2ba2de (diff) | |
download | tinygo-539cc5c47bb1bc46bcaf663d8f963670a7fbb111.tar.gz tinygo-539cc5c47bb1bc46bcaf663d8f963670a7fbb111.zip |
transform: optimize range over []byte(string)
Fixes #2700
-rw-r--r-- | transform/testdata/stringtobytes.ll | 8 | ||||
-rw-r--r-- | transform/testdata/stringtobytes.out.ll | 5 | ||||
-rw-r--r-- | transform/util.go | 9 |
3 files changed, 19 insertions, 3 deletions
diff --git a/transform/testdata/stringtobytes.ll b/transform/testdata/stringtobytes.ll index 06373a51b..6d008d023 100644 --- a/transform/testdata/stringtobytes.ll +++ b/transform/testdata/stringtobytes.ll @@ -5,6 +5,8 @@ target triple = "x86_64--linux" declare { ptr, i64, i64 } @runtime.stringToBytes(ptr, i64) +declare void @printByte(i8) + declare void @printSlice(ptr nocapture readonly, i64, i64) declare void @writeToSlice(ptr nocapture, i64, i64) @@ -17,6 +19,12 @@ entry: %2 = extractvalue { ptr, i64, i64 } %0, 1 %3 = extractvalue { ptr, i64, i64 } %0, 2 call fastcc void @printSlice(ptr %1, i64 %2, i64 %3) + + ; print(slice[0]) + %indexaddr.ptr1 = extractvalue { ptr, i64, i64 } %0, 0 + %4 = getelementptr inbounds i8, ptr %indexaddr.ptr1, i64 0 + %5 = load i8, ptr %4, align 1 + call fastcc void @printByte(i8 %5) ret void } diff --git a/transform/testdata/stringtobytes.out.ll b/transform/testdata/stringtobytes.out.ll index b33a17553..b8909755a 100644 --- a/transform/testdata/stringtobytes.out.ll +++ b/transform/testdata/stringtobytes.out.ll @@ -5,6 +5,8 @@ target triple = "x86_64--linux" declare { ptr, i64, i64 } @runtime.stringToBytes(ptr, i64) +declare void @printByte(i8) + declare void @printSlice(ptr nocapture readonly, i64, i64) declare void @writeToSlice(ptr nocapture, i64, i64) @@ -12,6 +14,9 @@ declare void @writeToSlice(ptr nocapture, i64, i64) define void @testReadOnly() { entry: call fastcc void @printSlice(ptr @str, i64 6, i64 6) + %0 = getelementptr inbounds i8, ptr @str, i64 0 + %1 = load i8, ptr %0, align 1 + call fastcc void @printByte(i8 %1) ret void } diff --git a/transform/util.go b/transform/util.go index 9923669d1..7a574d2fc 100644 --- a/transform/util.go +++ b/transform/util.go @@ -38,15 +38,18 @@ func hasFlag(call, param llvm.Value, kind string) bool { func isReadOnly(value llvm.Value) bool { uses := getUses(value) for _, use := range uses { - if !use.IsAGetElementPtrInst().IsNil() { + switch { + case !use.IsAGetElementPtrInst().IsNil(): if !isReadOnly(use) { return false } - } else if !use.IsACallInst().IsNil() { + case !use.IsACallInst().IsNil(): if !hasFlag(use, value, "readonly") { return false } - } else { + case !use.IsALoadInst().IsNil(): + // Loads are read-only. + default: // Unknown instruction, might not be readonly. return false } |