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  }