1// Copyright 2020 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//go:generate go run mknode.go 6 7package ir 8 9import ( 10 "cmd/compile/internal/types" 11 "cmd/internal/src" 12 "fmt" 13 "go/constant" 14) 15 16// A miniNode is a minimal node implementation, 17// meant to be embedded as the first field in a larger node implementation, 18// at a cost of 8 bytes. 19// 20// A miniNode is NOT a valid Node by itself: the embedding struct 21// must at the least provide: 22// 23// func (n *MyNode) String() string { return fmt.Sprint(n) } 24// func (n *MyNode) rawCopy() Node { c := *n; return &c } 25// func (n *MyNode) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) } 26// 27// The embedding struct should also fill in n.op in its constructor, 28// for more useful panic messages when invalid methods are called, 29// instead of implementing Op itself. 30type miniNode struct { 31 pos src.XPos // uint32 32 op Op // uint8 33 bits bitset8 34 esc uint16 35} 36 37// posOr returns pos if known, or else n.pos. 38// For use in DeepCopy. 39func (n *miniNode) posOr(pos src.XPos) src.XPos { 40 if pos.IsKnown() { 41 return pos 42 } 43 return n.pos 44} 45 46// op can be read, but not written. 47// An embedding implementation can provide a SetOp if desired. 48// (The panicking SetOp is with the other panics below.) 49func (n *miniNode) Op() Op { return n.op } 50func (n *miniNode) Pos() src.XPos { return n.pos } 51func (n *miniNode) SetPos(x src.XPos) { n.pos = x } 52func (n *miniNode) Esc() uint16 { return n.esc } 53func (n *miniNode) SetEsc(x uint16) { n.esc = x } 54 55const ( 56 miniTypecheckShift = 0 57 miniWalked = 1 << 2 // to prevent/catch re-walking 58) 59 60func (n *miniNode) Typecheck() uint8 { return n.bits.get2(miniTypecheckShift) } 61func (n *miniNode) SetTypecheck(x uint8) { 62 if x > 2 { 63 panic(fmt.Sprintf("cannot SetTypecheck %d", x)) 64 } 65 n.bits.set2(miniTypecheckShift, x) 66} 67 68func (n *miniNode) Walked() bool { return n.bits&miniWalked != 0 } 69func (n *miniNode) SetWalked(x bool) { n.bits.set(miniWalked, x) } 70 71// Empty, immutable graph structure. 72 73func (n *miniNode) Init() Nodes { return Nodes{} } 74 75// Additional functionality unavailable. 76 77func (n *miniNode) no(name string) string { return "cannot " + name + " on " + n.op.String() } 78 79func (n *miniNode) Type() *types.Type { return nil } 80func (n *miniNode) SetType(*types.Type) { panic(n.no("SetType")) } 81func (n *miniNode) Name() *Name { return nil } 82func (n *miniNode) Sym() *types.Sym { return nil } 83func (n *miniNode) Val() constant.Value { panic(n.no("Val")) } 84func (n *miniNode) SetVal(v constant.Value) { panic(n.no("SetVal")) } 85func (n *miniNode) NonNil() bool { return false } 86func (n *miniNode) MarkNonNil() { panic(n.no("MarkNonNil")) } 87