github.com/freddyisaac/sicortex-golang@v0.0.0-20231019035217-e03519e66f60/src/cmd/compile/internal/ssa/regalloc_test.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssa 6 7 import "testing" 8 9 func TestLiveControlOps(t *testing.T) { 10 c := testConfig(t) 11 f := Fun(c, "entry", 12 Bloc("entry", 13 Valu("mem", OpInitMem, TypeMem, 0, nil), 14 Valu("x", OpAMD64MOVLconst, TypeInt8, 1, nil), 15 Valu("y", OpAMD64MOVLconst, TypeInt8, 2, nil), 16 Valu("a", OpAMD64TESTB, TypeFlags, 0, nil, "x", "y"), 17 Valu("b", OpAMD64TESTB, TypeFlags, 0, nil, "y", "x"), 18 Eq("a", "if", "exit"), 19 ), 20 Bloc("if", 21 Eq("b", "plain", "exit"), 22 ), 23 Bloc("plain", 24 Goto("exit"), 25 ), 26 Bloc("exit", 27 Exit("mem"), 28 ), 29 ) 30 flagalloc(f.f) 31 regalloc(f.f) 32 checkFunc(f.f) 33 } 34 35 func TestSpillMove(t *testing.T) { 36 // Test for issue 20472. We shouldn't move a spill out to exit blocks 37 // if there is an exit block where the spill is dead but the pre-spill 38 // value is live. 39 c := testConfig(t) 40 ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing 41 arg1Aux := c.fe.Auto(TypeInt64) 42 arg2Aux := c.fe.Auto(ptrType) 43 f := Fun(c, "entry", 44 Bloc("entry", 45 Valu("mem", OpInitMem, TypeMem, 0, nil), 46 Valu("x", OpArg, TypeInt64, 0, arg1Aux), 47 Valu("p", OpArg, ptrType, 0, arg2Aux), 48 Valu("a", OpAMD64TESTQ, TypeFlags, 0, nil, "x", "x"), 49 Goto("loop1"), 50 ), 51 Bloc("loop1", 52 Valu("y", OpAMD64MULQ, TypeInt64, 0, nil, "x", "x"), 53 Eq("a", "loop2", "exit1"), 54 ), 55 Bloc("loop2", 56 Eq("a", "loop1", "exit2"), 57 ), 58 Bloc("exit1", 59 // store before call, y is available in a register 60 Valu("mem2", OpAMD64MOVQstore, TypeMem, 0, nil, "p", "y", "mem"), 61 Valu("mem3", OpAMD64CALLstatic, TypeMem, 0, nil, "mem2"), 62 Exit("mem3"), 63 ), 64 Bloc("exit2", 65 // store after call, y must be loaded from a spill location 66 Valu("mem4", OpAMD64CALLstatic, TypeMem, 0, nil, "mem"), 67 Valu("mem5", OpAMD64MOVQstore, TypeMem, 0, nil, "p", "y", "mem4"), 68 Exit("mem5"), 69 ), 70 ) 71 flagalloc(f.f) 72 regalloc(f.f) 73 checkFunc(f.f) 74 // There should still be a spill in Loop1, and nowhere else. 75 if numSpills(f.blocks["loop1"]) != 1 { 76 t.Errorf("spill missing from loop1") 77 } 78 if numSpills(f.blocks["loop2"]) != 0 { 79 t.Errorf("spill present in loop2") 80 } 81 if numSpills(f.blocks["exit1"]) != 0 { 82 t.Errorf("spill present in exit1") 83 } 84 if numSpills(f.blocks["exit2"]) != 0 { 85 t.Errorf("spill present in exit2") 86 } 87 88 } 89 90 func numSpills(b *Block) int { 91 n := 0 92 for _, v := range b.Values { 93 if v.Op == OpStoreReg { 94 n++ 95 } 96 } 97 return n 98 }