Commit 2b4f24a2 authored by Keith Randall's avatar Keith Randall

cmd/compile: randomize value order in block for testing

A little bit of compiler stress testing. Randomize the order
of the values in a block before every phase. This randomization
makes sure that we're not implicitly depending on that order.

Currently the random seed is a hash of the function name.
It provides determinism, but sacrifices some coverage.
Other arrangements are possible (env var, ...) but require
more setup.

Fixes #20178

Change-Id: Idae792a23264bd9a3507db6ba49b6d591a608e83
Reviewed-on: https://go-review.googlesource.com/c/33909Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
parent ff9481ec
...@@ -8,7 +8,9 @@ import ( ...@@ -8,7 +8,9 @@ import (
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
"hash/crc32"
"log" "log"
"math/rand"
"os" "os"
"regexp" "regexp"
"runtime" "runtime"
...@@ -29,6 +31,11 @@ func Compile(f *Func) { ...@@ -29,6 +31,11 @@ func Compile(f *Func) {
f.Logf("compiling %s\n", f.Name) f.Logf("compiling %s\n", f.Name)
} }
var rnd *rand.Rand
if checkEnabled {
rnd = rand.New(rand.NewSource(int64(crc32.ChecksumIEEE(([]byte)(f.Name)))))
}
// hook to print function & phase if panic happens // hook to print function & phase if panic happens
phaseName := "init" phaseName := "init"
defer func() { defer func() {
...@@ -68,6 +75,17 @@ func Compile(f *Func) { ...@@ -68,6 +75,17 @@ func Compile(f *Func) {
runtime.ReadMemStats(&mStart) runtime.ReadMemStats(&mStart)
} }
if checkEnabled && !f.scheduled {
// Test that we don't depend on the value order, by randomizing
// the order of values in each block. See issue 18169.
for _, b := range f.Blocks {
for i := 0; i < len(b.Values)-1; i++ {
j := i + rnd.Intn(len(b.Values)-i)
b.Values[i], b.Values[j] = b.Values[j], b.Values[i]
}
}
}
tStart := time.Now() tStart := time.Now()
p.fn(f) p.fn(f)
tEnd := time.Now() tEnd := time.Now()
......
...@@ -290,6 +290,6 @@ func nilcheckelim2(f *Func) { ...@@ -290,6 +290,6 @@ func nilcheckelim2(f *Func) {
b.Values = b.Values[:i] b.Values = b.Values[:i]
// TODO: if b.Kind == BlockPlain, start the analysis in the subsequent block to find // TODO: if b.Kind == BlockPlain, start the analysis in the subsequent block to find
// more unnecessary nil checks. Would fix test/nilptr3_ssa.go:157. // more unnecessary nil checks. Would fix test/nilptr3.go:159.
} }
} }
...@@ -559,6 +559,19 @@ func (t *test) run() { ...@@ -559,6 +559,19 @@ func (t *test) run() {
} }
args = args[1:] args = args[1:]
} }
if action == "errorcheck" {
found := false
for i, f := range flags {
if strings.HasPrefix(f, "-d=") {
flags[i] = f + ",ssa/check/on"
found = true
break
}
}
if !found {
flags = append(flags, "-d=ssa/check/on")
}
}
t.makeTempDir() t.makeTempDir()
if !*keep { if !*keep {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment