// 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

import "cmd/internal/src"

// trim removes blocks with no code in them.
// These blocks were inserted to remove critical edges.
func trim(f *Func) {
	n := 0
	for _, b := range f.Blocks {
		if !trimmableBlock(b) {
			f.Blocks[n] = b
			n++
			continue
		}

		bPos := b.Pos
		bIsStmt := bPos.IsStmt() == src.PosIsStmt

		// Splice b out of the graph. NOTE: `mergePhi` depends on the
		// order, in which the predecessors edges are merged here.
		p, i := b.Preds[0].b, b.Preds[0].i
		s, j := b.Succs[0].b, b.Succs[0].i
		ns := len(s.Preds)
		p.Succs[i] = Edge{s, j}
		s.Preds[j] = Edge{p, i}

		for _, e := range b.Preds[1:] {
			p, i := e.b, e.i
			p.Succs[i] = Edge{s, len(s.Preds)}
			s.Preds = append(s.Preds, Edge{p, i})
		}

		// Attempt to preserve a statement boundary
		if bIsStmt {
			sawStmt := false
			for _, v := range s.Values {
				if isPoorStatementOp(v.Op) {
					continue
				}
				if v.Pos.SameFileAndLine(bPos) {
					v.Pos = v.Pos.WithIsStmt()
				}
				sawStmt = true
				break
			}
			if !sawStmt && s.Pos.SameFileAndLine(bPos) {
				s.Pos = s.Pos.WithIsStmt()
			}
		}
		// If `s` had more than one predecessor, update its phi-ops to
		// account for the merge.
		if ns > 1 {
			for _, v := range s.Values {
				if v.Op == OpPhi {
					mergePhi(v, j, b)
				}

			}
			// Remove the phi-ops from `b` if they were merged into the
			// phi-ops of `s`.
			k := 0
			for _, v := range b.Values {
				if v.Op == OpPhi {
					if v.Uses == 0 {
						v.resetArgs()
						continue
					}
					// Pad the arguments of the remaining phi-ops so
					// they match the new predecessor count of `s`.
					// Since s did not have a Phi op corresponding to
					// the phi op in b, the other edges coming into s
					// must be loopback edges from s, so v is the right
					// argument to v!
					args := make([]*Value, len(v.Args))
					copy(args, v.Args)
					v.resetArgs()
					for x := 0; x < j; x++ {
						v.AddArg(v)
					}
					v.AddArg(args[0])
					for x := j + 1; x < ns; x++ {
						v.AddArg(v)
					}
					for _, a := range args[1:] {
						v.AddArg(a)
					}
				}
				b.Values[k] = v
				k++
			}
			b.Values = b.Values[:k]
		}

		// Merge the blocks' values.
		for _, v := range b.Values {
			v.Block = s
		}
		k := len(b.Values)
		m := len(s.Values)
		for i := 0; i < k; i++ {
			s.Values = append(s.Values, nil)
		}
		copy(s.Values[k:], s.Values[:m])
		copy(s.Values, b.Values)
	}
	if n < len(f.Blocks) {
		f.invalidateCFG()
		tail := f.Blocks[n:]
		for i := range tail {
			tail[i] = nil
		}
		f.Blocks = f.Blocks[:n]
	}
}

// emptyBlock reports whether the block does not contain actual
// instructions.
func emptyBlock(b *Block) bool {
	for _, v := range b.Values {
		if v.Op != OpPhi {
			return false
		}
	}
	return true
}

// trimmableBlock reports whether the block can be trimmed from the CFG,
// subject to the following criteria:
//   - it should not be the first block.
//   - it should be BlockPlain.
//   - it should not loop back to itself.
//   - it either is the single predecessor of the successor block or
//     contains no actual instructions.
func trimmableBlock(b *Block) bool {
	if b.Kind != BlockPlain || b == b.Func.Entry {
		return false
	}
	s := b.Succs[0].b
	return s != b && (len(s.Preds) == 1 || emptyBlock(b))
}

// mergePhi adjusts the number of `v`s arguments to account for merge
// of `b`, which was `i`th predecessor of the `v`s block.
func mergePhi(v *Value, i int, b *Block) {
	u := v.Args[i]
	if u.Block == b {
		if u.Op != OpPhi {
			b.Func.Fatalf("value %s is not a phi operation", u.LongString())
		}
		// If the original block contained u = φ(u0, u1, ..., un) and
		// the current phi is
		//    v = φ(v0, v1, ..., u, ..., vk)
		// then the merged phi is
		//    v = φ(v0, v1, ..., u0, ..., vk, u1, ..., un)
		v.SetArg(i, u.Args[0])
		v.AddArgs(u.Args[1:]...)
	} else {
		// If the original block contained u = φ(u0, u1, ..., un) and
		// the current phi is
		//    v = φ(v0, v1, ...,  vi, ..., vk)
		// i.e. it does not use a value from the predecessor block,
		// then the merged phi is
		//    v = φ(v0, v1, ..., vk, vi, vi, ...)
		for j := 1; j < len(b.Preds); j++ {
			v.AddArg(v.Args[i])
		}
	}
}
