diff --git a/go/ssa/testmain.go b/go/ssa/testmain.go
deleted file mode 100644
index b748332..0000000
--- a/go/ssa/testmain.go
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2013 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
-
-// CreateTestMainPackage synthesizes a main package that runs all the
-// tests of the supplied packages.
-// It is closely coupled to $GOROOT/src/cmd/go/test.go and $GOROOT/src/testing.
-//
-// TODO(adonovan): throws this all away now that x/tools/go/packages
-// provides access to the actual synthetic test main files.
-
-import (
-	"bytes"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/types"
-	"log"
-	"os"
-	"strings"
-	"text/template"
-
-	"golang.org/x/tools/internal/typeparams"
-)
-
-// FindTests returns the Test, Benchmark, and Example functions
-// (as defined by "go test") defined in the specified package,
-// and its TestMain function, if any.
-//
-// Deprecated: Use golang.org/x/tools/go/packages to access synthetic
-// testmain packages.
-func FindTests(pkg *Package) (tests, benchmarks, examples []*Function, main *Function) {
-	prog := pkg.Prog
-
-	// The first two of these may be nil: if the program doesn't import "testing",
-	// it can't contain any tests, but it may yet contain Examples.
-	var testSig *types.Signature                              // func(*testing.T)
-	var benchmarkSig *types.Signature                         // func(*testing.B)
-	var exampleSig = types.NewSignature(nil, nil, nil, false) // func()
-
-	// Obtain the types from the parameters of testing.MainStart.
-	if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
-		mainStart := testingPkg.Func("MainStart")
-		params := mainStart.Signature.Params()
-		testSig = funcField(params.At(1).Type())
-		benchmarkSig = funcField(params.At(2).Type())
-
-		// Does the package define this function?
-		//   func TestMain(*testing.M)
-		if f := pkg.Func("TestMain"); f != nil {
-			sig := f.Type().(*types.Signature)
-			starM := mainStart.Signature.Results().At(0).Type() // *testing.M
-			if sig.Results().Len() == 0 &&
-				sig.Params().Len() == 1 &&
-				types.Identical(sig.Params().At(0).Type(), starM) {
-				main = f
-			}
-		}
-	}
-
-	// TODO(adonovan): use a stable order, e.g. lexical.
-	for _, mem := range pkg.Members {
-		if f, ok := mem.(*Function); ok &&
-			ast.IsExported(f.Name()) &&
-			strings.HasSuffix(prog.Fset.Position(f.Pos()).Filename, "_test.go") {
-
-			switch {
-			case testSig != nil && isTestSig(f, "Test", testSig):
-				tests = append(tests, f)
-			case benchmarkSig != nil && isTestSig(f, "Benchmark", benchmarkSig):
-				benchmarks = append(benchmarks, f)
-			case isTestSig(f, "Example", exampleSig):
-				examples = append(examples, f)
-			default:
-				continue
-			}
-		}
-	}
-	return
-}
-
-// Like isTest, but checks the signature too.
-func isTestSig(f *Function, prefix string, sig *types.Signature) bool {
-	return isTest(f.Name(), prefix) && types.Identical(f.Signature, sig)
-}
-
-// Given the type of one of the three slice parameters of testing.Main,
-// returns the function type.
-func funcField(slice types.Type) *types.Signature {
-	return slice.(*types.Slice).Elem().Underlying().(*types.Struct).Field(1).Type().(*types.Signature)
-}
-
-// isTest tells whether name looks like a test (or benchmark, according to prefix).
-// It is a Test (say) if there is a character after Test that is not a lower-case letter.
-// We don't want TesticularCancer.
-// Plundered from $GOROOT/src/cmd/go/test.go
-func isTest(name, prefix string) bool {
-	if !strings.HasPrefix(name, prefix) {
-		return false
-	}
-	if len(name) == len(prefix) { // "Test" is ok
-		return true
-	}
-	return ast.IsExported(name[len(prefix):])
-}
-
-// CreateTestMainPackage creates and returns a synthetic "testmain"
-// package for the specified package if it defines tests, benchmarks or
-// executable examples, or nil otherwise.  The new package is named
-// "main" and provides a function named "main" that runs the tests,
-// similar to the one that would be created by the 'go test' tool.
-//
-// Subsequent calls to prog.AllPackages include the new package.
-// The package pkg must belong to the program prog.
-//
-// Deprecated: Use golang.org/x/tools/go/packages to access synthetic
-// testmain packages.
-func (prog *Program) CreateTestMainPackage(pkg *Package) *Package {
-	if pkg.Prog != prog {
-		log.Fatal("Package does not belong to Program")
-	}
-
-	// Template data
-	var data struct {
-		Pkg                         *Package
-		Tests, Benchmarks, Examples []*Function
-		Main                        *Function
-		Go18                        bool
-	}
-	data.Pkg = pkg
-
-	// Enumerate tests.
-	data.Tests, data.Benchmarks, data.Examples, data.Main = FindTests(pkg)
-	if data.Main == nil &&
-		data.Tests == nil && data.Benchmarks == nil && data.Examples == nil {
-		return nil
-	}
-
-	// Synthesize source for testmain package.
-	path := pkg.Pkg.Path() + "$testmain"
-	tmpl := testmainTmpl
-	if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
-		// In Go 1.8, testing.MainStart's first argument is an interface, not a func.
-		data.Go18 = types.IsInterface(testingPkg.Func("MainStart").Signature.Params().At(0).Type())
-	} else {
-		// The program does not import "testing", but FindTests
-		// returned non-nil, which must mean there were Examples
-		// but no Test, Benchmark, or TestMain functions.
-
-		// We'll simply call them from testmain.main; this will
-		// ensure they don't panic, but will not check any
-		// "Output:" comments.
-		// (We should not execute an Example that has no
-		// "Output:" comment, but it's impossible to tell here.)
-		tmpl = examplesOnlyTmpl
-	}
-	var buf bytes.Buffer
-	if err := tmpl.Execute(&buf, data); err != nil {
-		log.Fatalf("internal error expanding template for %s: %v", path, err)
-	}
-	if false { // debugging
-		fmt.Fprintln(os.Stderr, buf.String())
-	}
-
-	// Parse and type-check the testmain package.
-	f, err := parser.ParseFile(prog.Fset, path+".go", &buf, parser.Mode(0))
-	if err != nil {
-		log.Fatalf("internal error parsing %s: %v", path, err)
-	}
-	conf := types.Config{
-		DisableUnusedImportCheck: true,
-		Importer:                 importer{pkg},
-	}
-	files := []*ast.File{f}
-	info := &types.Info{
-		Types:      make(map[ast.Expr]types.TypeAndValue),
-		Defs:       make(map[*ast.Ident]types.Object),
-		Uses:       make(map[*ast.Ident]types.Object),
-		Implicits:  make(map[ast.Node]types.Object),
-		Scopes:     make(map[ast.Node]*types.Scope),
-		Selections: make(map[*ast.SelectorExpr]*types.Selection),
-	}
-	typeparams.InitInstanceInfo(info)
-	testmainPkg, err := conf.Check(path, prog.Fset, files, info)
-	if err != nil {
-		log.Fatalf("internal error type-checking %s: %v", path, err)
-	}
-
-	// Create and build SSA code.
-	testmain := prog.CreatePackage(testmainPkg, files, info, false)
-	testmain.SetDebugMode(false)
-	testmain.Build()
-	testmain.Func("main").Synthetic = "test main function"
-	testmain.Func("init").Synthetic = "package initializer"
-	return testmain
-}
-
-// An implementation of types.Importer for an already loaded SSA program.
-type importer struct {
-	pkg *Package // package under test; may be non-importable
-}
-
-func (imp importer) Import(path string) (*types.Package, error) {
-	if p := imp.pkg.Prog.ImportedPackage(path); p != nil {
-		return p.Pkg, nil
-	}
-	if path == imp.pkg.Pkg.Path() {
-		return imp.pkg.Pkg, nil
-	}
-	return nil, fmt.Errorf("not found") // can't happen
-}
-
-var testmainTmpl = template.Must(template.New("testmain").Parse(`
-package main
-
-import "io"
-import "os"
-import "testing"
-import p {{printf "%q" .Pkg.Pkg.Path}}
-
-{{if .Go18}}
-type deps struct{}
-
-func (deps) ImportPath() string { return "" }
-func (deps) MatchString(pat, str string) (bool, error) { return true, nil }
-func (deps) SetPanicOnExit0(bool) {}
-func (deps) StartCPUProfile(io.Writer) error { return nil }
-func (deps) StartTestLog(io.Writer) {}
-func (deps) StopCPUProfile() {}
-func (deps) StopTestLog() error { return nil }
-func (deps) WriteHeapProfile(io.Writer) error { return nil }
-func (deps) WriteProfileTo(string, io.Writer, int) error { return nil }
-
-var match deps
-{{else}}
-func match(_, _ string) (bool, error) { return true, nil }
-{{end}}
-
-func main() {
-	tests := []testing.InternalTest{
-{{range .Tests}}
-		{ {{printf "%q" .Name}}, p.{{.Name}} },
-{{end}}
-	}
-	benchmarks := []testing.InternalBenchmark{
-{{range .Benchmarks}}
-		{ {{printf "%q" .Name}}, p.{{.Name}} },
-{{end}}
-	}
-	examples := []testing.InternalExample{
-{{range .Examples}}
-		{Name: {{printf "%q" .Name}}, F: p.{{.Name}}},
-{{end}}
-	}
-	m := testing.MainStart(match, tests, benchmarks, examples)
-{{with .Main}}
-	p.{{.Name}}(m)
-{{else}}
-	os.Exit(m.Run())
-{{end}}
-}
-
-`))
-
-var examplesOnlyTmpl = template.Must(template.New("examples").Parse(`
-package main
-
-import p {{printf "%q" .Pkg.Pkg.Path}}
-
-func main() {
-{{range .Examples}}
-	p.{{.Name}}()
-{{end}}
-}
-`))
diff --git a/go/ssa/testmain_test.go b/go/ssa/testmain_test.go
deleted file mode 100644
index e24b23b..0000000
--- a/go/ssa/testmain_test.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 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_test
-
-// Tests of FindTests.  CreateTestMainPackage is tested via the interpreter.
-// TODO(adonovan): test the 'pkgs' result from FindTests.
-
-import (
-	"fmt"
-	"sort"
-	"testing"
-
-	"golang.org/x/tools/go/loader"
-	"golang.org/x/tools/go/ssa"
-	"golang.org/x/tools/go/ssa/ssautil"
-)
-
-func create(t *testing.T, content string) *ssa.Package {
-	var conf loader.Config
-	f, err := conf.ParseFile("foo_test.go", content)
-	if err != nil {
-		t.Fatal(err)
-	}
-	conf.CreateFromFiles("foo", f)
-
-	lprog, err := conf.Load()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// We needn't call Build.
-	foo := lprog.Package("foo").Pkg
-	return ssautil.CreateProgram(lprog, ssa.SanityCheckFunctions).Package(foo)
-}
-
-func TestFindTests(t *testing.T) {
-	test := `
-package foo
-
-import "testing"
-
-type T int
-
-// Tests:
-func Test(t *testing.T) {}
-func TestA(t *testing.T) {}
-func TestB(t *testing.T) {}
-
-// Not tests:
-func testC(t *testing.T) {}
-func TestD() {}
-func testE(t *testing.T) int { return 0 }
-func (T) Test(t *testing.T) {}
-
-// Benchmarks:
-func Benchmark(*testing.B) {}
-func BenchmarkA(b *testing.B) {}
-func BenchmarkB(*testing.B) {}
-
-// Not benchmarks:
-func benchmarkC(t *testing.T) {}
-func BenchmarkD() {}
-func benchmarkE(t *testing.T) int { return 0 }
-func (T) Benchmark(t *testing.T) {}
-
-// Examples:
-func Example() {}
-func ExampleA() {}
-
-// Not examples:
-func exampleC() {}
-func ExampleD(t *testing.T) {}
-func exampleE() int { return 0 }
-func (T) Example() {}
-`
-	pkg := create(t, test)
-	tests, benchmarks, examples, _ := ssa.FindTests(pkg)
-
-	sort.Sort(funcsByPos(tests))
-	if got, want := fmt.Sprint(tests), "[foo.Test foo.TestA foo.TestB]"; got != want {
-		t.Errorf("FindTests.tests = %s, want %s", got, want)
-	}
-
-	sort.Sort(funcsByPos(benchmarks))
-	if got, want := fmt.Sprint(benchmarks), "[foo.Benchmark foo.BenchmarkA foo.BenchmarkB]"; got != want {
-		t.Errorf("FindTests.benchmarks = %s, want %s", got, want)
-	}
-
-	sort.Sort(funcsByPos(examples))
-	if got, want := fmt.Sprint(examples), "[foo.Example foo.ExampleA]"; got != want {
-		t.Errorf("FindTests examples = %s, want %s", got, want)
-	}
-}
-
-func TestFindTestsTesting(t *testing.T) {
-	test := `
-package foo
-
-// foo does not import "testing", but defines Examples.
-
-func Example() {}
-func ExampleA() {}
-`
-	pkg := create(t, test)
-	tests, benchmarks, examples, _ := ssa.FindTests(pkg)
-	if len(tests) > 0 {
-		t.Errorf("FindTests.tests = %s, want none", tests)
-	}
-	if len(benchmarks) > 0 {
-		t.Errorf("FindTests.benchmarks = %s, want none", benchmarks)
-	}
-	sort.Sort(funcsByPos(examples))
-	if got, want := fmt.Sprint(examples), "[foo.Example foo.ExampleA]"; got != want {
-		t.Errorf("FindTests examples = %s, want %s", got, want)
-	}
-}
-
-type funcsByPos []*ssa.Function
-
-func (p funcsByPos) Len() int           { return len(p) }
-func (p funcsByPos) Less(i, j int) bool { return p[i].Pos() < p[j].Pos() }
-func (p funcsByPos) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
