aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorElias Naur <[email protected]>2024-10-14 18:59:07 +0200
committerAyke <[email protected]>2024-10-18 17:42:20 +0200
commit539cc5c47bb1bc46bcaf663d8f963670a7fbb111 (patch)
treea77a2c8ee9771317b9ef02c52cb51dbc57c62c88
parent45cc5b58cd8fa164c60ef72c934e9fe16f2ba2de (diff)
downloadtinygo-539cc5c47bb1bc46bcaf663d8f963670a7fbb111.tar.gz
tinygo-539cc5c47bb1bc46bcaf663d8f963670a7fbb111.zip
transform: optimize range over []byte(string)
Fixes #2700
-rw-r--r--transform/testdata/stringtobytes.ll8
-rw-r--r--transform/testdata/stringtobytes.out.ll5
-rw-r--r--transform/util.go9
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
}