From baf2c3ec4ade20b3a56022983d20373ea9ea49b7 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Mon, 10 Aug 2015 14:01:04 -0700 Subject: [PATCH] [dev.ssa] cmd/compile: detect rewrite loops of length > 1 Use a version of Floyd's cycle finding algorithm, but advance by 1 and 1/2 steps per cycle rather than by 1 and 2. It is simpler and should be cheaper in the normal, acyclic case. This should fix the 386 and arm builds, which are currently hung. Change-Id: If8bd443011b28a5ecb004a549239991d3dfc862b Reviewed-on: https://go-review.googlesource.com/13473 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/rewrite.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index a02f1d50b2..39fc48df4a 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -44,9 +44,18 @@ func applyRewrite(f *Func, rb func(*Block) bool, rv func(*Value, *Config) bool) } // Rewriting can generate OpCopy loops. // They are harmless (see removePredecessor), - // but take care not to loop forever. - for a.Op == OpCopy && a != a.Args[0] { + // but take care to stop if we find a cycle. + slow := a // advances every other iteration + var advance bool + for a.Op == OpCopy { a = a.Args[0] + if slow == a { + break + } + if advance { + slow = a + } + advance = !advance } v.Args[i] = a }