X7ROOT File Manager
Current Path:
/opt/golang/1.19.4/src/cmd/compile/internal/ssa
opt
/
golang
/
1.19.4
/
src
/
cmd
/
compile
/
internal
/
ssa
/
📁
..
📄
README.md
(8.14 KB)
📄
TODO
(950 B)
📄
addressingmodes.go
(23.64 KB)
📄
bench_test.go
(531 B)
📄
biasedsparsemap.go
(2.71 KB)
📄
block.go
(11.1 KB)
📄
branchelim.go
(11.98 KB)
📄
branchelim_test.go
(5.21 KB)
📄
cache.go
(2.46 KB)
📄
check.go
(16.59 KB)
📄
checkbce.go
(956 B)
📄
compile.go
(18.19 KB)
📄
config.go
(11.7 KB)
📄
copyelim.go
(1.83 KB)
📄
copyelim_test.go
(1.29 KB)
📄
critical.go
(3.19 KB)
📄
cse.go
(9.43 KB)
📄
cse_test.go
(4.25 KB)
📄
deadcode.go
(9.61 KB)
📄
deadcode_test.go
(3.49 KB)
📄
deadstore.go
(9.08 KB)
📄
deadstore_test.go
(4.09 KB)
📄
debug.go
(56.34 KB)
📄
debug_lines_test.go
(8.29 KB)
📄
debug_test.go
(28.75 KB)
📄
decompose.go
(13.41 KB)
📄
dom.go
(7.98 KB)
📄
dom_test.go
(13.34 KB)
📄
expand_calls.go
(63.5 KB)
📄
export_test.go
(3.23 KB)
📄
flagalloc.go
(6.68 KB)
📄
flags_amd64_test.s
(533 B)
📄
flags_arm64_test.s
(699 B)
📄
flags_test.go
(2.49 KB)
📄
func.go
(27.08 KB)
📄
func_test.go
(13.07 KB)
📄
fuse.go
(6.5 KB)
📄
fuse_branchredirect.go
(3.24 KB)
📄
fuse_comparisons.go
(4.04 KB)
📄
fuse_test.go
(7.21 KB)
📁
gen
📄
html.go
(34.72 KB)
📄
id.go
(576 B)
📄
layout.go
(4.82 KB)
📄
lca.go
(3.77 KB)
📄
lca_test.go
(1.65 KB)
📄
likelyadjust.go
(15.24 KB)
📄
location.go
(3.06 KB)
📄
loopbce.go
(10.54 KB)
📄
loopreschedchecks.go
(15.86 KB)
📄
looprotate.go
(2.61 KB)
📄
lower.go
(1.36 KB)
📄
magic.go
(15.77 KB)
📄
magic_test.go
(9.1 KB)
📄
nilcheck.go
(11.06 KB)
📄
nilcheck_test.go
(12.17 KB)
📄
numberlines.go
(7.83 KB)
📄
op.go
(18.65 KB)
📄
opGen.go
(1.01 MB)
📄
opt.go
(308 B)
📄
passbm_test.go
(3.14 KB)
📄
phielim.go
(1.48 KB)
📄
phiopt.go
(8.08 KB)
📄
poset.go
(37.2 KB)
📄
poset_test.go
(18.14 KB)
📄
print.go
(3.85 KB)
📄
prove.go
(41.82 KB)
📄
regalloc.go
(83.69 KB)
📄
regalloc_test.go
(6.49 KB)
📄
rewrite.go
(53.49 KB)
📄
rewrite386.go
(289.01 KB)
📄
rewrite386splitload.go
(4.05 KB)
📄
rewriteAMD64.go
(888.95 KB)
📄
rewriteAMD64splitload.go
(21.41 KB)
📄
rewriteARM.go
(487.7 KB)
📄
rewriteARM64.go
(751.84 KB)
📄
rewriteCond_test.go
(10.62 KB)
📄
rewriteLOONG64.go
(193.44 KB)
📄
rewriteMIPS.go
(174.44 KB)
📄
rewriteMIPS64.go
(195.55 KB)
📄
rewritePPC64.go
(431.6 KB)
📄
rewriteRISCV64.go
(159.66 KB)
📄
rewriteS390X.go
(433.4 KB)
📄
rewriteWasm.go
(109.86 KB)
📄
rewrite_test.go
(6.91 KB)
📄
rewritedec.go
(10.16 KB)
📄
rewritedec64.go
(63.77 KB)
📄
rewritegeneric.go
(617.96 KB)
📄
schedule.go
(18.23 KB)
📄
schedule_test.go
(2.91 KB)
📄
shift_test.go
(4.05 KB)
📄
shortcircuit.go
(12.63 KB)
📄
shortcircuit_test.go
(1.31 KB)
📄
sizeof_test.go
(855 B)
📄
softfloat.go
(1.99 KB)
📄
sparsemap.go
(1.98 KB)
📄
sparseset.go
(1.54 KB)
📄
sparsetree.go
(8.05 KB)
📄
stackalloc.go
(12.79 KB)
📄
stackframe.go
(290 B)
📄
stmtlines_test.go
(2.96 KB)
📁
testdata
📄
tighten.go
(4.3 KB)
📄
trim.go
(4.24 KB)
📄
tuple.go
(1.97 KB)
📄
value.go
(15.21 KB)
📄
writebarrier.go
(19.29 KB)
📄
writebarrier_test.go
(1.75 KB)
📄
xposmap.go
(3.29 KB)
📄
zcse.go
(2.07 KB)
📄
zeroextension_test.go
(1.66 KB)
Editing: dom_test.go
// Copyright 2015 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/compile/internal/types" "testing" ) func BenchmarkDominatorsLinear(b *testing.B) { benchmarkDominators(b, 10000, genLinear) } func BenchmarkDominatorsFwdBack(b *testing.B) { benchmarkDominators(b, 10000, genFwdBack) } func BenchmarkDominatorsManyPred(b *testing.B) { benchmarkDominators(b, 10000, genManyPred) } func BenchmarkDominatorsMaxPred(b *testing.B) { benchmarkDominators(b, 10000, genMaxPred) } func BenchmarkDominatorsMaxPredVal(b *testing.B) { benchmarkDominators(b, 10000, genMaxPredValue) } type blockGen func(size int) []bloc // genLinear creates an array of blocks that succeed one another // b_n -> [b_n+1]. func genLinear(size int) []bloc { var blocs []bloc blocs = append(blocs, Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Goto(blockn(0)), ), ) for i := 0; i < size; i++ { blocs = append(blocs, Bloc(blockn(i), Goto(blockn(i+1)))) } blocs = append(blocs, Bloc(blockn(size), Goto("exit")), Bloc("exit", Exit("mem")), ) return blocs } // genLinear creates an array of blocks that alternate between // b_n -> [b_n+1], b_n -> [b_n+1, b_n-1] , b_n -> [b_n+1, b_n+2] func genFwdBack(size int) []bloc { var blocs []bloc blocs = append(blocs, Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto(blockn(0)), ), ) for i := 0; i < size; i++ { switch i % 2 { case 0: blocs = append(blocs, Bloc(blockn(i), If("p", blockn(i+1), blockn(i+2)))) case 1: blocs = append(blocs, Bloc(blockn(i), If("p", blockn(i+1), blockn(i-1)))) } } blocs = append(blocs, Bloc(blockn(size), Goto("exit")), Bloc("exit", Exit("mem")), ) return blocs } // genManyPred creates an array of blocks where 1/3rd have a successor of the // first block, 1/3rd the last block, and the remaining third are plain. func genManyPred(size int) []bloc { var blocs []bloc blocs = append(blocs, Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto(blockn(0)), ), ) // We want predecessor lists to be long, so 2/3rds of the blocks have a // successor of the first or last block. for i := 0; i < size; i++ { switch i % 3 { case 0: blocs = append(blocs, Bloc(blockn(i), Valu("a", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto(blockn(i+1)))) case 1: blocs = append(blocs, Bloc(blockn(i), Valu("a", OpConstBool, types.Types[types.TBOOL], 1, nil), If("p", blockn(i+1), blockn(0)))) case 2: blocs = append(blocs, Bloc(blockn(i), Valu("a", OpConstBool, types.Types[types.TBOOL], 1, nil), If("p", blockn(i+1), blockn(size)))) } } blocs = append(blocs, Bloc(blockn(size), Goto("exit")), Bloc("exit", Exit("mem")), ) return blocs } // genMaxPred maximizes the size of the 'exit' predecessor list. func genMaxPred(size int) []bloc { var blocs []bloc blocs = append(blocs, Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto(blockn(0)), ), ) for i := 0; i < size; i++ { blocs = append(blocs, Bloc(blockn(i), If("p", blockn(i+1), "exit"))) } blocs = append(blocs, Bloc(blockn(size), Goto("exit")), Bloc("exit", Exit("mem")), ) return blocs } // genMaxPredValue is identical to genMaxPred but contains an // additional value. func genMaxPredValue(size int) []bloc { var blocs []bloc blocs = append(blocs, Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto(blockn(0)), ), ) for i := 0; i < size; i++ { blocs = append(blocs, Bloc(blockn(i), Valu("a", OpConstBool, types.Types[types.TBOOL], 1, nil), If("p", blockn(i+1), "exit"))) } blocs = append(blocs, Bloc(blockn(size), Goto("exit")), Bloc("exit", Exit("mem")), ) return blocs } // sink for benchmark var domBenchRes []*Block func benchmarkDominators(b *testing.B, size int, bg blockGen) { c := testConfig(b) fun := c.Fun("entry", bg(size)...) CheckFunc(fun.f) b.SetBytes(int64(size)) b.ResetTimer() for i := 0; i < b.N; i++ { domBenchRes = dominators(fun.f) } } type domFunc func(f *Func) []*Block // verifyDominators verifies that the dominators of fut (function under test) // as determined by domFn, match the map node->dominator func verifyDominators(t *testing.T, fut fun, domFn domFunc, doms map[string]string) { blockNames := map[*Block]string{} for n, b := range fut.blocks { blockNames[b] = n } calcDom := domFn(fut.f) for n, d := range doms { nblk, ok := fut.blocks[n] if !ok { t.Errorf("invalid block name %s", n) } dblk, ok := fut.blocks[d] if !ok { t.Errorf("invalid block name %s", d) } domNode := calcDom[nblk.ID] switch { case calcDom[nblk.ID] == dblk: calcDom[nblk.ID] = nil continue case calcDom[nblk.ID] != dblk: t.Errorf("expected %s as dominator of %s, found %s", d, n, blockNames[domNode]) default: t.Fatal("unexpected dominator condition") } } for id, d := range calcDom { // If nil, we've already verified it if d == nil { continue } for _, b := range fut.blocks { if int(b.ID) == id { t.Errorf("unexpected dominator of %s for %s", blockNames[d], blockNames[b]) } } } } func TestDominatorsSingleBlock(t *testing.T) { c := testConfig(t) fun := c.Fun("entry", Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Exit("mem"))) doms := map[string]string{} CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } func TestDominatorsSimple(t *testing.T) { c := testConfig(t) fun := c.Fun("entry", Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Goto("a")), Bloc("a", Goto("b")), Bloc("b", Goto("c")), Bloc("c", Goto("exit")), Bloc("exit", Exit("mem"))) doms := map[string]string{ "a": "entry", "b": "a", "c": "b", "exit": "c", } CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } func TestDominatorsMultPredFwd(t *testing.T) { c := testConfig(t) fun := c.Fun("entry", Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), If("p", "a", "c")), Bloc("a", If("p", "b", "c")), Bloc("b", Goto("c")), Bloc("c", Goto("exit")), Bloc("exit", Exit("mem"))) doms := map[string]string{ "a": "entry", "b": "a", "c": "entry", "exit": "c", } CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } func TestDominatorsDeadCode(t *testing.T) { c := testConfig(t) fun := c.Fun("entry", Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 0, nil), If("p", "b3", "b5")), Bloc("b2", Exit("mem")), Bloc("b3", Goto("b2")), Bloc("b4", Goto("b2")), Bloc("b5", Goto("b2"))) doms := map[string]string{ "b2": "entry", "b3": "entry", "b5": "entry", } CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } func TestDominatorsMultPredRev(t *testing.T) { c := testConfig(t) fun := c.Fun("entry", Bloc("entry", Goto("first")), Bloc("first", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto("a")), Bloc("a", If("p", "b", "first")), Bloc("b", Goto("c")), Bloc("c", If("p", "exit", "b")), Bloc("exit", Exit("mem"))) doms := map[string]string{ "first": "entry", "a": "first", "b": "a", "c": "b", "exit": "c", } CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } func TestDominatorsMultPred(t *testing.T) { c := testConfig(t) fun := c.Fun("entry", Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), If("p", "a", "c")), Bloc("a", If("p", "b", "c")), Bloc("b", Goto("c")), Bloc("c", If("p", "b", "exit")), Bloc("exit", Exit("mem"))) doms := map[string]string{ "a": "entry", "b": "entry", "c": "entry", "exit": "c", } CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } func TestInfiniteLoop(t *testing.T) { c := testConfig(t) // note lack of an exit block fun := c.Fun("entry", Bloc("entry", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto("a")), Bloc("a", Goto("b")), Bloc("b", Goto("a"))) CheckFunc(fun.f) doms := map[string]string{"a": "entry", "b": "a"} verifyDominators(t, fun, dominators, doms) } func TestDomTricky(t *testing.T) { doms := map[string]string{ "4": "1", "2": "4", "5": "4", "11": "4", "15": "4", // the incorrect answer is "5" "10": "15", "19": "15", } if4 := [2]string{"2", "5"} if5 := [2]string{"15", "11"} if15 := [2]string{"19", "10"} for i := 0; i < 8; i++ { a := 1 & i b := 1 & i >> 1 c := 1 & i >> 2 cfg := testConfig(t) fun := cfg.Fun("1", Bloc("1", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), Goto("4")), Bloc("2", Goto("11")), Bloc("4", If("p", if4[a], if4[1-a])), // 2, 5 Bloc("5", If("p", if5[b], if5[1-b])), //15, 11 Bloc("10", Exit("mem")), Bloc("11", Goto("15")), Bloc("15", If("p", if15[c], if15[1-c])), //19, 10 Bloc("19", Goto("10"))) CheckFunc(fun.f) verifyDominators(t, fun, dominators, doms) verifyDominators(t, fun, dominatorsSimple, doms) } } // generateDominatorMap uses dominatorsSimple to obtain a // reference dominator tree for testing faster algorithms. func generateDominatorMap(fut fun) map[string]string { blockNames := map[*Block]string{} for n, b := range fut.blocks { blockNames[b] = n } referenceDom := dominatorsSimple(fut.f) doms := make(map[string]string) for _, b := range fut.f.Blocks { if d := referenceDom[b.ID]; d != nil { doms[blockNames[b]] = blockNames[d] } } return doms } func TestDominatorsPostTrickyA(t *testing.T) { testDominatorsPostTricky(t, "b8", "b11", "b10", "b8", "b14", "b15") } func TestDominatorsPostTrickyB(t *testing.T) { testDominatorsPostTricky(t, "b11", "b8", "b10", "b8", "b14", "b15") } func TestDominatorsPostTrickyC(t *testing.T) { testDominatorsPostTricky(t, "b8", "b11", "b8", "b10", "b14", "b15") } func TestDominatorsPostTrickyD(t *testing.T) { testDominatorsPostTricky(t, "b11", "b8", "b8", "b10", "b14", "b15") } func TestDominatorsPostTrickyE(t *testing.T) { testDominatorsPostTricky(t, "b8", "b11", "b10", "b8", "b15", "b14") } func TestDominatorsPostTrickyF(t *testing.T) { testDominatorsPostTricky(t, "b11", "b8", "b10", "b8", "b15", "b14") } func TestDominatorsPostTrickyG(t *testing.T) { testDominatorsPostTricky(t, "b8", "b11", "b8", "b10", "b15", "b14") } func TestDominatorsPostTrickyH(t *testing.T) { testDominatorsPostTricky(t, "b11", "b8", "b8", "b10", "b15", "b14") } func testDominatorsPostTricky(t *testing.T, b7then, b7else, b12then, b12else, b13then, b13else string) { c := testConfig(t) fun := c.Fun("b1", Bloc("b1", Valu("mem", OpInitMem, types.TypeMem, 0, nil), Valu("p", OpConstBool, types.Types[types.TBOOL], 1, nil), If("p", "b3", "b2")), Bloc("b3", If("p", "b5", "b6")), Bloc("b5", Goto("b7")), Bloc("b7", If("p", b7then, b7else)), Bloc("b8", Goto("b13")), Bloc("b13", If("p", b13then, b13else)), Bloc("b14", Goto("b10")), Bloc("b15", Goto("b16")), Bloc("b16", Goto("b9")), Bloc("b9", Goto("b7")), Bloc("b11", Goto("b12")), Bloc("b12", If("p", b12then, b12else)), Bloc("b10", Goto("b6")), Bloc("b6", Goto("b17")), Bloc("b17", Goto("b18")), Bloc("b18", If("p", "b22", "b19")), Bloc("b22", Goto("b23")), Bloc("b23", If("p", "b21", "b19")), Bloc("b19", If("p", "b24", "b25")), Bloc("b24", Goto("b26")), Bloc("b26", Goto("b25")), Bloc("b25", If("p", "b27", "b29")), Bloc("b27", Goto("b30")), Bloc("b30", Goto("b28")), Bloc("b29", Goto("b31")), Bloc("b31", Goto("b28")), Bloc("b28", If("p", "b32", "b33")), Bloc("b32", Goto("b21")), Bloc("b21", Goto("b47")), Bloc("b47", If("p", "b45", "b46")), Bloc("b45", Goto("b48")), Bloc("b48", Goto("b49")), Bloc("b49", If("p", "b50", "b51")), Bloc("b50", Goto("b52")), Bloc("b52", Goto("b53")), Bloc("b53", Goto("b51")), Bloc("b51", Goto("b54")), Bloc("b54", Goto("b46")), Bloc("b46", Exit("mem")), Bloc("b33", Goto("b34")), Bloc("b34", Goto("b37")), Bloc("b37", If("p", "b35", "b36")), Bloc("b35", Goto("b38")), Bloc("b38", Goto("b39")), Bloc("b39", If("p", "b40", "b41")), Bloc("b40", Goto("b42")), Bloc("b42", Goto("b43")), Bloc("b43", Goto("b41")), Bloc("b41", Goto("b44")), Bloc("b44", Goto("b36")), Bloc("b36", Goto("b20")), Bloc("b20", Goto("b18")), Bloc("b2", Goto("b4")), Bloc("b4", Exit("mem"))) CheckFunc(fun.f) doms := generateDominatorMap(fun) verifyDominators(t, fun, dominators, doms) }
Upload File
Create Folder