[PATCH] [llgo] irgen: fix canAvoid*
Andrew Wilkins
axwalk at gmail.com
Tue Dec 16 01:32:57 PST 2014
Hi pcc,
canAvoidElementLoad and canAvoidLoad were incorrectly
eliding loads when an index expression is used as an
another array index expression. This led to a panic.
See comments on https://github.com/go-llvm/llgo/issues/175
http://reviews.llvm.org/D6676
Files:
irgen/ssa.go
test/irgen/avoidload.go
Index: irgen/ssa.go
===================================================================
--- irgen/ssa.go
+++ irgen/ssa.go
@@ -663,7 +663,7 @@
return value
}
- panic("Instruction not visited yet")
+ panic(fmt.Errorf("Instruction %q not visited yet", v.Name()))
}
func (fr *frame) llvmvalue(v ssa.Value) llvm.Value {
@@ -696,11 +696,14 @@
}
}
-func (fr *frame) canAvoidElementLoad(refs []ssa.Instruction) bool {
- for _, ref := range refs {
- switch ref.(type) {
- case *ssa.Field, *ssa.Index:
- // ok
+func (fr *frame) canAvoidElementLoad(ptr ssa.Value) bool {
+ for _, ref := range *ptr.Referrers() {
+ switch ref := ref.(type) {
+ case *ssa.Field:
+ case *ssa.Index:
+ if ref.X != ptr {
+ return false
+ }
default:
return false
}
@@ -724,11 +727,14 @@
// We only know how to avoid loads if they are used to create an interface
// or read an element of the structure. If we see any other referrer, abort.
for _, ref := range *instr.Referrers() {
- switch ref.(type) {
+ switch ref := ref.(type) {
case *ssa.MakeInterface:
esc = true
- case *ssa.Field, *ssa.Index:
- // ok
+ case *ssa.Field:
+ case *ssa.Index:
+ if ref.X != instr {
+ return false
+ }
default:
return false
}
@@ -895,7 +901,7 @@
fieldtyp := instr.Type()
if p, ok := fr.ptr[instr.X]; ok {
field := fr.builder.CreateStructGEP(p, instr.Field, instr.Name())
- if fr.canAvoidElementLoad(*instr.Referrers()) {
+ if fr.canAvoidElementLoad(instr) {
fr.ptr[instr] = field
} else {
fr.env[instr] = newValue(fr.builder.CreateLoad(field, ""), fieldtyp)
@@ -959,7 +965,7 @@
fr.condBrRuntimeError(cond, gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS)
addr := fr.builder.CreateGEP(arrayptr, []llvm.Value{zero, index}, "")
- if fr.canAvoidElementLoad(*instr.Referrers()) {
+ if fr.canAvoidElementLoad(instr) {
fr.ptr[instr] = addr
} else {
fr.env[instr] = newValue(fr.builder.CreateLoad(addr, ""), instr.Type())
Index: test/irgen/avoidload.go
===================================================================
--- /dev/null
+++ test/irgen/avoidload.go
@@ -0,0 +1,15 @@
+// RUN: llgo -S -emit-llvm -o - %s | FileCheck %s
+
+package foo
+
+type X struct {
+ indices [1]int
+}
+
+// CHECK-NOT: load [200 x i64]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}, i64 160000, i32 1, i1 false)
+var _ = [100][200]int{}[0][0]
+
+// CHECK-NOT: load [1024 x i64]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}, i64 8192, i32 1, i1 false)
+var _ = [1024]int{}[X{}.indices[0]]
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D6676.17322.patch
Type: text/x-patch
Size: 2552 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141216/157367d5/attachment.bin>
More information about the llvm-commits
mailing list