// 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])
		}
	}
}
