aboutsummaryrefslogtreecommitdiff
path: root/vendor/honnef.co/go/tools/functions/loops.go
diff options
context:
space:
mode:
authorJoseph Richey <joerichey94@gmail.com>2018-02-11 20:34:07 -0800
committerJoseph Richey <joerichey94@gmail.com>2018-02-11 20:34:07 -0800
commit23b8c7b4eab0375b3d59cf4b2a1f3d7356515f95 (patch)
tree6ec67f8d6b15420c3870d2b7c43b2b636fbb8349 /vendor/honnef.co/go/tools/functions/loops.go
parentfff13ea9041a3945e36d5f002c3c0a1e0e93c825 (diff)
vendor: include source for tools
This change vendors the source for all our build, formatting, and linting tools. Generated by running "dep ensure".
Diffstat (limited to 'vendor/honnef.co/go/tools/functions/loops.go')
-rw-r--r--vendor/honnef.co/go/tools/functions/loops.go50
1 files changed, 50 insertions, 0 deletions
diff --git a/vendor/honnef.co/go/tools/functions/loops.go b/vendor/honnef.co/go/tools/functions/loops.go
new file mode 100644
index 0000000..63011cf
--- /dev/null
+++ b/vendor/honnef.co/go/tools/functions/loops.go
@@ -0,0 +1,50 @@
+package functions
+
+import "honnef.co/go/tools/ssa"
+
+type Loop map[*ssa.BasicBlock]bool
+
+func findLoops(fn *ssa.Function) []Loop {
+ if fn.Blocks == nil {
+ return nil
+ }
+ tree := fn.DomPreorder()
+ var sets []Loop
+ for _, h := range tree {
+ for _, n := range h.Preds {
+ if !h.Dominates(n) {
+ continue
+ }
+ // n is a back-edge to h
+ // h is the loop header
+ if n == h {
+ sets = append(sets, Loop{n: true})
+ continue
+ }
+ set := Loop{h: true, n: true}
+ for _, b := range allPredsBut(n, h, nil) {
+ set[b] = true
+ }
+ sets = append(sets, set)
+ }
+ }
+ return sets
+}
+
+func allPredsBut(b, but *ssa.BasicBlock, list []*ssa.BasicBlock) []*ssa.BasicBlock {
+outer:
+ for _, pred := range b.Preds {
+ if pred == but {
+ continue
+ }
+ for _, p := range list {
+ // TODO improve big-o complexity of this function
+ if pred == p {
+ continue outer
+ }
+ }
+ list = append(list, pred)
+ list = allPredsBut(pred, but, list)
+ }
+ return list
+}