internal/gocore/dominator.go
func (d *ltDom) initialize() {
	type workItem struct {
		name       vName
		parentName vName
	}

	// Initialize objs for mapping from object index back to Object.
	i := 0
	d.p.ForEachObject(func(x Object) bool {
		d.objs[i] = x
		i++
		return true
	})

	// Add roots to the work stack, essentially pretending to visit
	// the pseudo-root, numbering it 0.
	d.semis[pseudoRoot] = 0
	d.parents[pseudoRoot] = -1
	d.vertices[0] = pseudoRoot
	var work []workItem
	for i := 1; i < 1+d.nRoots; i++ {
		work = append(work, workItem{name: vName(i), parentName: 0})
	}

	n := vNumber(1) // 0 was the pseudo-root.

	// Build the spanning tree, assigning vertex numbers to each object
	// and initializing semi and parent.
	for len(work) != 0 {
		item := work[len(work)-1]
		work = work[:len(work)-1]

		if d.semis[item.name] != -1 {
			continue
		}

		d.semis[item.name] = n
		d.parents[item.name] = item.parentName
		d.vertices[n] = item.name
		n++

		visitChild := func(_ int64, child Object, _ int64) bool {
			childIdx, _ := d.p.findObjectIndex(d.p.Addr(child))
			work = append(work, workItem{name: vName(childIdx + d.nRoots + 1), parentName: item.name})
			return true
		}

		root, object := d.findVertexByName(item.name)
		if root != nil {
			d.p.ForEachRootPtr(root, visitChild)
		} else {
			d.p.ForEachPtr(object, visitChild)
		}

	}
}
func (d *ltDom) initialize() {
	type workItem struct {
		name       vName
		parentName vName
	}

	// Initialize objs for mapping from object index back to Object.
	i := 0
	d.p.ForEachObject(func(x Object) bool {
		d.objs[i] = x
		i++
		return true
	})

	// Add roots to the work stack, essentially pretending to visit
	// the pseudo-root, numbering it 0.
	d.semis[pseudoRoot] = 0
	d.parents[pseudoRoot] = -1
	d.vertices[0] = pseudoRoot
	var work []workItem
	for i := 1; i < 1+d.nRoots; i++ {
		work = append(work, workItem{name: vName(i), parentName: 0})
	}

	n := vNumber(1) // 0 was the pseudo-root.

	// Build the spanning tree, assigning vertex numbers to each object
	// and initializing semi and parent.
	for len(work) != 0 {
		item := work[len(work)-1]
		work = work[:len(work)-1]

		if d.semis[item.name] != -1 {
			continue
		}

		d.semis[item.name] = n
		d.parents[item.name] = item.parentName
		d.vertices[n] = item.name
		n++

		visitChild := func(_ int64, child Object, _ int64) bool {
			childIdx, _ := d.p.findObjectIndex(d.p.Addr(child))
			work = append(work, workItem{name: vName(childIdx + d.nRoots + 1), parentName: item.name})
			return true
		}

		root, object := d.findVertexByName(item.name)
		if root != nil {
			d.p.ForEachRootPtr(root, visitChild)
		} else {
			d.p.ForEachPtr(object, visitChild)
		}

	}
}
// initialize implements step 1 of LT.