|  | // Copyright 2016 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package ssa | 
|  |  | 
|  | // Code to compute lowest common ancestors in the dominator tree. | 
|  | // https://en.wikipedia.org/wiki/Lowest_common_ancestor | 
|  | // https://en.wikipedia.org/wiki/Range_minimum_query#Solution_using_constant_time_and_linearithmic_space | 
|  |  | 
|  | // lcaRange is a data structure that can compute lowest common ancestor queries | 
|  | // in O(n lg n) precomputed space and O(1) time per query. | 
|  | type lcaRange struct { | 
|  | // Additional information about each block (indexed by block ID). | 
|  | blocks []lcaRangeBlock | 
|  |  | 
|  | // Data structure for range minimum queries. | 
|  | // rangeMin[k][i] contains the ID of the minimum depth block | 
|  | // in the Euler tour from positions i to i+1<<k-1, inclusive. | 
|  | rangeMin [][]ID | 
|  | } | 
|  |  | 
|  | type lcaRangeBlock struct { | 
|  | b          *Block | 
|  | parent     ID    // parent in dominator tree.  0 = no parent (entry or unreachable) | 
|  | firstChild ID    // first child in dominator tree | 
|  | sibling    ID    // next child of parent | 
|  | pos        int32 // an index in the Euler tour where this block appears (any one of its occurrences) | 
|  | depth      int32 // depth in dominator tree (root=0, its children=1, etc.) | 
|  | } | 
|  |  | 
|  | func makeLCArange(f *Func) *lcaRange { | 
|  | dom := f.Idom() | 
|  |  | 
|  | // Build tree | 
|  | blocks := make([]lcaRangeBlock, f.NumBlocks()) | 
|  | for _, b := range f.Blocks { | 
|  | blocks[b.ID].b = b | 
|  | if dom[b.ID] == nil { | 
|  | continue // entry or unreachable | 
|  | } | 
|  | parent := dom[b.ID].ID | 
|  | blocks[b.ID].parent = parent | 
|  | blocks[b.ID].sibling = blocks[parent].firstChild | 
|  | blocks[parent].firstChild = b.ID | 
|  | } | 
|  |  | 
|  | // Compute euler tour ordering. | 
|  | // Each reachable block will appear #children+1 times in the tour. | 
|  | tour := make([]ID, 0, f.NumBlocks()*2-1) | 
|  | type queueEntry struct { | 
|  | bid ID // block to work on | 
|  | cid ID // child we're already working on (0 = haven't started yet) | 
|  | } | 
|  | q := []queueEntry{{f.Entry.ID, 0}} | 
|  | for len(q) > 0 { | 
|  | n := len(q) - 1 | 
|  | bid := q[n].bid | 
|  | cid := q[n].cid | 
|  | q = q[:n] | 
|  |  | 
|  | // Add block to tour. | 
|  | blocks[bid].pos = int32(len(tour)) | 
|  | tour = append(tour, bid) | 
|  |  | 
|  | // Proceed down next child edge (if any). | 
|  | if cid == 0 { | 
|  | // This is our first visit to b. Set its depth. | 
|  | blocks[bid].depth = blocks[blocks[bid].parent].depth + 1 | 
|  | // Then explore its first child. | 
|  | cid = blocks[bid].firstChild | 
|  | } else { | 
|  | // We've seen b before. Explore the next child. | 
|  | cid = blocks[cid].sibling | 
|  | } | 
|  | if cid != 0 { | 
|  | q = append(q, queueEntry{bid, cid}, queueEntry{cid, 0}) | 
|  | } | 
|  | } | 
|  |  | 
|  | // Compute fast range-minimum query data structure | 
|  | var rangeMin [][]ID | 
|  | rangeMin = append(rangeMin, tour) // 1-size windows are just the tour itself. | 
|  | for logS, s := 1, 2; s < len(tour); logS, s = logS+1, s*2 { | 
|  | r := make([]ID, len(tour)-s+1) | 
|  | for i := 0; i < len(tour)-s+1; i++ { | 
|  | bid := rangeMin[logS-1][i] | 
|  | bid2 := rangeMin[logS-1][i+s/2] | 
|  | if blocks[bid2].depth < blocks[bid].depth { | 
|  | bid = bid2 | 
|  | } | 
|  | r[i] = bid | 
|  | } | 
|  | rangeMin = append(rangeMin, r) | 
|  | } | 
|  |  | 
|  | return &lcaRange{blocks: blocks, rangeMin: rangeMin} | 
|  | } | 
|  |  | 
|  | // find returns the lowest common ancestor of a and b. | 
|  | func (lca *lcaRange) find(a, b *Block) *Block { | 
|  | if a == b { | 
|  | return a | 
|  | } | 
|  | // Find the positions of a and bin the Euler tour. | 
|  | p1 := lca.blocks[a.ID].pos | 
|  | p2 := lca.blocks[b.ID].pos | 
|  | if p1 > p2 { | 
|  | p1, p2 = p2, p1 | 
|  | } | 
|  |  | 
|  | // The lowest common ancestor is the minimum depth block | 
|  | // on the tour from p1 to p2.  We've precomputed minimum | 
|  | // depth blocks for powers-of-two subsequences of the tour. | 
|  | // Combine the right two precomputed values to get the answer. | 
|  | logS := uint(log2(int64(p2 - p1))) | 
|  | bid1 := lca.rangeMin[logS][p1] | 
|  | bid2 := lca.rangeMin[logS][p2-1<<logS+1] | 
|  | if lca.blocks[bid1].depth < lca.blocks[bid2].depth { | 
|  | return lca.blocks[bid1].b | 
|  | } | 
|  | return lca.blocks[bid2].b | 
|  | } |