github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/compile/internal/ssa/fuse_test.go (about) 1 package ssa 2 3 import ( 4 "testing" 5 ) 6 7 func TestFuseEliminatesOneBranch(t *testing.T) { 8 ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing 9 c := NewConfig("amd64", DummyFrontend{t}, nil, true) 10 fun := Fun(c, "entry", 11 Bloc("entry", 12 Valu("mem", OpInitMem, TypeMem, 0, nil), 13 Valu("sb", OpSB, TypeInvalid, 0, nil), 14 Goto("checkPtr")), 15 Bloc("checkPtr", 16 Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"), 17 Valu("nilptr", OpConstNil, ptrType, 0, nil), 18 Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"), 19 If("bool1", "then", "exit")), 20 Bloc("then", 21 Goto("exit")), 22 Bloc("exit", 23 Exit("mem"))) 24 25 CheckFunc(fun.f) 26 fuse(fun.f) 27 28 for _, b := range fun.f.Blocks { 29 if b == fun.blocks["then"] && b.Kind != BlockInvalid { 30 t.Errorf("then was not eliminated, but should have") 31 } 32 } 33 } 34 35 func TestFuseEliminatesBothBranches(t *testing.T) { 36 ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing 37 c := NewConfig("amd64", DummyFrontend{t}, nil, true) 38 fun := Fun(c, "entry", 39 Bloc("entry", 40 Valu("mem", OpInitMem, TypeMem, 0, nil), 41 Valu("sb", OpSB, TypeInvalid, 0, nil), 42 Goto("checkPtr")), 43 Bloc("checkPtr", 44 Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"), 45 Valu("nilptr", OpConstNil, ptrType, 0, nil), 46 Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"), 47 If("bool1", "then", "else")), 48 Bloc("then", 49 Goto("exit")), 50 Bloc("else", 51 Goto("exit")), 52 Bloc("exit", 53 Exit("mem"))) 54 55 CheckFunc(fun.f) 56 fuse(fun.f) 57 58 for _, b := range fun.f.Blocks { 59 if b == fun.blocks["then"] && b.Kind != BlockInvalid { 60 t.Errorf("then was not eliminated, but should have") 61 } 62 if b == fun.blocks["else"] && b.Kind != BlockInvalid { 63 t.Errorf("then was not eliminated, but should have") 64 } 65 } 66 } 67 68 func TestFuseHandlesPhis(t *testing.T) { 69 ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing 70 c := NewConfig("amd64", DummyFrontend{t}, nil, true) 71 fun := Fun(c, "entry", 72 Bloc("entry", 73 Valu("mem", OpInitMem, TypeMem, 0, nil), 74 Valu("sb", OpSB, TypeInvalid, 0, nil), 75 Goto("checkPtr")), 76 Bloc("checkPtr", 77 Valu("ptr1", OpLoad, ptrType, 0, nil, "sb", "mem"), 78 Valu("nilptr", OpConstNil, ptrType, 0, nil), 79 Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"), 80 If("bool1", "then", "else")), 81 Bloc("then", 82 Goto("exit")), 83 Bloc("else", 84 Goto("exit")), 85 Bloc("exit", 86 Valu("phi", OpPhi, ptrType, 0, nil, "ptr1", "ptr1"), 87 Exit("mem"))) 88 89 CheckFunc(fun.f) 90 fuse(fun.f) 91 92 for _, b := range fun.f.Blocks { 93 if b == fun.blocks["then"] && b.Kind != BlockInvalid { 94 t.Errorf("then was not eliminated, but should have") 95 } 96 if b == fun.blocks["else"] && b.Kind != BlockInvalid { 97 t.Errorf("then was not eliminated, but should have") 98 } 99 } 100 } 101 102 func TestFuseEliminatesEmptyBlocks(t *testing.T) { 103 c := NewConfig("amd64", DummyFrontend{t}, nil, true) 104 fun := Fun(c, "entry", 105 Bloc("entry", 106 Valu("mem", OpInitMem, TypeMem, 0, nil), 107 Valu("sb", OpSB, TypeInvalid, 0, nil), 108 Goto("z0")), 109 Bloc("z1", 110 Goto("z2")), 111 Bloc("z3", 112 Goto("exit")), 113 Bloc("z2", 114 Goto("z3")), 115 Bloc("z0", 116 Goto("z1")), 117 Bloc("exit", 118 Exit("mem"), 119 )) 120 121 CheckFunc(fun.f) 122 fuse(fun.f) 123 124 for k, b := range fun.blocks { 125 if k[:1] == "z" && b.Kind != BlockInvalid { 126 t.Errorf("%s was not eliminated, but should have", k) 127 } 128 } 129 }