Home | History | Annotate | Download | only in ssa
      1 // Copyright 2016 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package ssa
      6 
      7 // Code to compute lowest common ancestors in the dominator tree.
      8 // https://en.wikipedia.org/wiki/Lowest_common_ancestor
      9 // https://en.wikipedia.org/wiki/Range_minimum_query#Solution_using_constant_time_and_linearithmic_space
     10 
     11 // lcaRange is a data structure that can compute lowest common ancestor queries
     12 // in O(n lg n) precomputed space and O(1) time per query.
     13 type lcaRange struct {
     14 	// Additional information about each block (indexed by block ID).
     15 	blocks []lcaRangeBlock
     16 
     17 	// Data structure for range minimum queries.
     18 	// rangeMin[k][i] contains the ID of the minimum depth block
     19 	// in the Euler tour from positions i to i+1<<k-1, inclusive.
     20 	rangeMin [][]ID
     21 }
     22 
     23 type lcaRangeBlock struct {
     24 	b          *Block
     25 	parent     ID    // parent in dominator tree.  0 = no parent (entry or unreachable)
     26 	firstChild ID    // first child in dominator tree
     27 	sibling    ID    // next child of parent
     28 	pos        int32 // an index in the Euler tour where this block appears (any one of its occurrences)
     29 	depth      int32 // depth in dominator tree (root=0, its children=1, etc.)
     30 }
     31 
     32 func makeLCArange(f *Func) *lcaRange {
     33 	dom := f.Idom()
     34 
     35 	// Build tree
     36 	blocks := make([]lcaRangeBlock, f.NumBlocks())
     37 	for _, b := range f.Blocks {
     38 		blocks[b.ID].b = b
     39 		if dom[b.ID] == nil {
     40 			continue // entry or unreachable
     41 		}
     42 		parent := dom[b.ID].ID
     43 		blocks[b.ID].parent = parent
     44 		blocks[b.ID].sibling = blocks[parent].firstChild
     45 		blocks[parent].firstChild = b.ID
     46 	}
     47 
     48 	// Compute euler tour ordering.
     49 	// Each reachable block will appear #children+1 times in the tour.
     50 	tour := make([]ID, 0, f.NumBlocks()*2-1)
     51 	type queueEntry struct {
     52 		bid ID // block to work on
     53 		cid ID // child we're already working on (0 = haven't started yet)
     54 	}
     55 	q := []queueEntry{{f.Entry.ID, 0}}
     56 	for len(q) > 0 {
     57 		n := len(q) - 1
     58 		bid := q[n].bid
     59 		cid := q[n].cid
     60 		q = q[:n]
     61 
     62 		// Add block to tour.
     63 		blocks[bid].pos = int32(len(tour))
     64 		tour = append(tour, bid)
     65 
     66 		// Proceed down next child edge (if any).
     67 		if cid == 0 {
     68 			// This is our first visit to b. Set its depth.
     69 			blocks[bid].depth = blocks[blocks[bid].parent].depth + 1
     70 			// Then explore its first child.
     71 			cid = blocks[bid].firstChild
     72 		} else {
     73 			// We've seen b before. Explore the next child.
     74 			cid = blocks[cid].sibling
     75 		}
     76 		if cid != 0 {
     77 			q = append(q, queueEntry{bid, cid}, queueEntry{cid, 0})
     78 		}
     79 	}
     80 
     81 	// Compute fast range-minimum query data structure
     82 	var rangeMin [][]ID
     83 	rangeMin = append(rangeMin, tour) // 1-size windows are just the tour itself.
     84 	for logS, s := 1, 2; s < len(tour); logS, s = logS+1, s*2 {
     85 		r := make([]ID, len(tour)-s+1)
     86 		for i := 0; i < len(tour)-s+1; i++ {
     87 			bid := rangeMin[logS-1][i]
     88 			bid2 := rangeMin[logS-1][i+s/2]
     89 			if blocks[bid2].depth < blocks[bid].depth {
     90 				bid = bid2
     91 			}
     92 			r[i] = bid
     93 		}
     94 		rangeMin = append(rangeMin, r)
     95 	}
     96 
     97 	return &lcaRange{blocks: blocks, rangeMin: rangeMin}
     98 }
     99 
    100 // find returns the lowest common ancestor of a and b.
    101 func (lca *lcaRange) find(a, b *Block) *Block {
    102 	if a == b {
    103 		return a
    104 	}
    105 	// Find the positions of a and bin the Euler tour.
    106 	p1 := lca.blocks[a.ID].pos
    107 	p2 := lca.blocks[b.ID].pos
    108 	if p1 > p2 {
    109 		p1, p2 = p2, p1
    110 	}
    111 
    112 	// The lowest common ancestor is the minimum depth block
    113 	// on the tour from p1 to p2.  We've precomputed minimum
    114 	// depth blocks for powers-of-two subsequences of the tour.
    115 	// Combine the right two precomputed values to get the answer.
    116 	logS := uint(log2(int64(p2 - p1)))
    117 	bid1 := lca.rangeMin[logS][p1]
    118 	bid2 := lca.rangeMin[logS][p2-1<<logS+1]
    119 	if lca.blocks[bid1].depth < lca.blocks[bid2].depth {
    120 		return lca.blocks[bid1].b
    121 	}
    122 	return lca.blocks[bid2].b
    123 }
    124