Skip to content

Commit caa1b4a

Browse files
committed
cmd/compile/internal/ssa: note zero-width Ops
Add a bool to opInfo to indicate if an Op never results in any instructions. This is a conservative approximation: some operations, like Copy, may or may not generate code depending on their arguments. I built the list by reading each arch's ssaGenValue function. Hopefully I got them all. Change-Id: I130b251b65f18208294e129bb7ddc3f91d57d31d Reviewed-on: https://go-review.googlesource.com/97957 Reviewed-by: Keith Randall <[email protected]>
1 parent b77aad0 commit caa1b4a

File tree

12 files changed

+107
-74
lines changed

12 files changed

+107
-74
lines changed

src/cmd/compile/internal/ssa/gen/386Ops.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ func init() {
439439
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
440440
// and sorts it to the very beginning of the block to prevent other
441441
// use of DX (the closure pointer)
442-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
442+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}, zeroWidth: true},
443443
// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
444444
// I.e., if f calls g "calls" getcallerpc,
445445
// the result should be the PC within f that g will return to.
@@ -459,7 +459,7 @@ func init() {
459459
// (particularly stack maps). It takes a memory arg so it
460460
// gets correctly ordered with respect to GC safepoints.
461461
// arg0=ptr/int arg1=mem, output=int/ptr
462-
{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true},
462+
{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true, zeroWidth: true},
463463

464464
// Constant flag values. For any comparison, there are 5 possible
465465
// outcomes: the three from the signed total order (<,==,>) and the

src/cmd/compile/internal/ssa/gen/AMD64Ops.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ func init() {
568568
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
569569
// and sorts it to the very beginning of the block to prevent other
570570
// use of DX (the closure pointer)
571-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}},
571+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("DX")}}, zeroWidth: true},
572572
// LoweredGetCallerPC evaluates to the PC to which its "caller" will return.
573573
// I.e., if f calls g "calls" getcallerpc,
574574
// the result should be the PC within f that g will return to.
@@ -588,8 +588,8 @@ func init() {
588588
// (particularly stack maps). It takes a memory arg so it
589589
// gets correctly ordered with respect to GC safepoints.
590590
// arg0=ptr/int arg1=mem, output=int/ptr
591-
{name: "MOVQconvert", argLength: 2, reg: gp11, asm: "MOVQ", resultInArg0: true},
592-
{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true}, // amd64p32 equivalent
591+
{name: "MOVQconvert", argLength: 2, reg: gp11, asm: "MOVQ", resultInArg0: true, zeroWidth: true},
592+
{name: "MOVLconvert", argLength: 2, reg: gp11, asm: "MOVL", resultInArg0: true, zeroWidth: true}, // amd64p32 equivalent
593593

594594
// Constant flag values. For any comparison, there are 5 possible
595595
// outcomes: the three from the signed total order (<,==,>) and the

src/cmd/compile/internal/ssa/gen/ARM64Ops.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,8 @@ func init() {
217217
{name: "CLZW", argLength: 1, reg: gp11, asm: "CLZW"}, // count leading zero, 32-bit
218218
{name: "VCNT", argLength: 1, reg: fp11, asm: "VCNT"}, // count set bits for each 8-bit unit and store the result in each 8-bit unit
219219
{name: "VUADDLV", argLength: 1, reg: fp11, asm: "VUADDLV"}, // unsigned sum of eight bytes in a 64-bit value, zero extended to 64-bit.
220-
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true},
221-
{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true},
220+
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
221+
{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
222222

223223
// 3-operand, the addend comes first
224224
{name: "FMADDS", argLength: 3, reg: fp31, asm: "FMADDS"}, // +arg0 + (arg1 * arg2)
@@ -459,7 +459,7 @@ func init() {
459459
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
460460
// and sorts it to the very beginning of the block to prevent other
461461
// use of R26 (arm64.REGCTXT, the closure pointer)
462-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}},
462+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R26")}}, zeroWidth: true},
463463

464464
// LoweredGetCallerSP returns the SP of the caller of the current function.
465465
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},

src/cmd/compile/internal/ssa/gen/ARMOps.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ func init() {
514514
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
515515
// and sorts it to the very beginning of the block to prevent other
516516
// use of R7 (arm.REGCTXT, the closure pointer)
517-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}},
517+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R7")}}, zeroWidth: true},
518518

519519
// LoweredGetCallerSP returns the SP of the caller of the current function.
520520
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},

src/cmd/compile/internal/ssa/gen/MIPS64Ops.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ func init() {
404404
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
405405
// and sorts it to the very beginning of the block to prevent other
406406
// use of R22 (mips.REGCTXT, the closure pointer)
407-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}},
407+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}, zeroWidth: true},
408408

409409
// LoweredGetCallerSP returns the SP of the caller of the current function.
410410
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},

src/cmd/compile/internal/ssa/gen/MIPSOps.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ func init() {
374374
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
375375
// and sorts it to the very beginning of the block to prevent other
376376
// use of R22 (mips.REGCTXT, the closure pointer)
377-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}},
377+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R22")}}, zeroWidth: true},
378378

379379
// LoweredGetCallerSP returns the SP of the caller of the current function.
380380
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},

src/cmd/compile/internal/ssa/gen/PPC64Ops.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,16 +316,16 @@ func init() {
316316
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
317317
// and sorts it to the very beginning of the block to prevent other
318318
// use of the closure pointer.
319-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}},
319+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{ctxt}}, zeroWidth: true},
320320

321321
// LoweredGetCallerSP returns the SP of the caller of the current function.
322322
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
323323

324324
//arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
325325
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
326326
// Round ops to block fused-multiply-add extraction.
327-
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true},
328-
{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true},
327+
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
328+
{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
329329

330330
// Convert pointer to integer, takes a memory operand for ordering.
331331
{name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},

src/cmd/compile/internal/ssa/gen/S390XOps.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,14 +445,14 @@ func init() {
445445
// Scheduler ensures LoweredGetClosurePtr occurs only in entry block,
446446
// and sorts it to the very beginning of the block to prevent other
447447
// use of R12 (the closure pointer)
448-
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}},
448+
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{buildReg("R12")}}, zeroWidth: true},
449449
// arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
450450
// LoweredGetCallerSP returns the SP of the caller of the current function.
451451
{name: "LoweredGetCallerSP", reg: gp01, rematerializeable: true},
452452
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{ptrsp}}, clobberFlags: true, nilCheck: true, faultOnNilArg0: true},
453453
// Round ops to block fused-multiply-add extraction.
454-
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true},
455-
{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true},
454+
{name: "LoweredRound32F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
455+
{name: "LoweredRound64F", argLength: 1, reg: fp11, resultInArg0: true, zeroWidth: true},
456456

457457
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
458458
// It saves all GP registers if necessary,

src/cmd/compile/internal/ssa/gen/genericOps.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ var genericOps = []opData{
285285

286286
// Data movement, max argument length for Phi is indefinite so just pick
287287
// a really large number
288-
{name: "Phi", argLength: -1}, // select an argument based on which predecessor block we came from
289-
{name: "Copy", argLength: 1}, // output = arg0
288+
{name: "Phi", argLength: -1, zeroWidth: true}, // select an argument based on which predecessor block we came from
289+
{name: "Copy", argLength: 1}, // output = arg0
290290
// Convert converts between pointers and integers.
291291
// We have a special op for this so as to not confuse GC
292292
// (particularly stack maps). It takes a memory arg so it
@@ -311,8 +311,8 @@ var genericOps = []opData{
311311
{name: "ConstSlice"}, // nil slice
312312

313313
// Constant-like things
314-
{name: "InitMem"}, // memory input to the function.
315-
{name: "Arg", aux: "SymOff", symEffect: "Read"}, // argument to the function. aux=GCNode of arg, off = offset in that arg.
314+
{name: "InitMem", zeroWidth: true}, // memory input to the function.
315+
{name: "Arg", aux: "SymOff", symEffect: "Read", zeroWidth: true}, // argument to the function. aux=GCNode of arg, off = offset in that arg.
316316

317317
// The address of a variable. arg0 is the base pointer.
318318
// If the variable is a global, the base pointer will be SB and
@@ -321,9 +321,9 @@ var genericOps = []opData{
321321
// the Aux field will be a *gc.Node.
322322
{name: "Addr", argLength: 1, aux: "Sym", symEffect: "Addr"}, // Address of a variable. Arg0=SP or SB. Aux identifies the variable.
323323

324-
{name: "SP"}, // stack pointer
325-
{name: "SB", typ: "Uintptr"}, // static base pointer (a.k.a. globals pointer)
326-
{name: "Invalid"}, // unused value
324+
{name: "SP", zeroWidth: true}, // stack pointer
325+
{name: "SB", typ: "Uintptr", zeroWidth: true}, // static base pointer (a.k.a. globals pointer)
326+
{name: "Invalid"}, // unused value
327327

328328
// Memory operations
329329
{name: "Load", argLength: 2}, // Load from arg0. arg1=memory
@@ -395,10 +395,10 @@ var genericOps = []opData{
395395
{name: "NilCheck", argLength: 2, typ: "Void"}, // arg0=ptr, arg1=mem. Panics if arg0 is nil. Returns void.
396396

397397
// Pseudo-ops
398-
{name: "GetG", argLength: 1}, // runtime.getg() (read g pointer). arg0=mem
399-
{name: "GetClosurePtr"}, // get closure pointer from dedicated register
400-
{name: "GetCallerPC"}, // for getcallerpc intrinsic
401-
{name: "GetCallerSP"}, // for getcallersp intrinsic
398+
{name: "GetG", argLength: 1, zeroWidth: true}, // runtime.getg() (read g pointer). arg0=mem
399+
{name: "GetClosurePtr"}, // get closure pointer from dedicated register
400+
{name: "GetCallerPC"}, // for getcallerpc intrinsic
401+
{name: "GetCallerSP"}, // for getcallersp intrinsic
402402

403403
// Indexing operations
404404
{name: "PtrIndex", argLength: 2}, // arg0=ptr, arg1=index. Computes ptr+sizeof(*v.type)*index, where index is extended to ptrwidth type
@@ -451,10 +451,10 @@ var genericOps = []opData{
451451
// Unknown value. Used for Values whose values don't matter because they are dead code.
452452
{name: "Unknown"},
453453

454-
{name: "VarDef", argLength: 1, aux: "Sym", typ: "Mem", symEffect: "None"}, // aux is a *gc.Node of a variable that is about to be initialized. arg0=mem, returns mem
455-
{name: "VarKill", argLength: 1, aux: "Sym", symEffect: "None"}, // aux is a *gc.Node of a variable that is known to be dead. arg0=mem, returns mem
456-
{name: "VarLive", argLength: 1, aux: "Sym", symEffect: "Read"}, // aux is a *gc.Node of a variable that must be kept live. arg0=mem, returns mem
457-
{name: "KeepAlive", argLength: 2, typ: "Mem"}, // arg[0] is a value that must be kept alive until this mark. arg[1]=mem, returns mem
454+
{name: "VarDef", argLength: 1, aux: "Sym", typ: "Mem", symEffect: "None", zeroWidth: true}, // aux is a *gc.Node of a variable that is about to be initialized. arg0=mem, returns mem
455+
{name: "VarKill", argLength: 1, aux: "Sym", symEffect: "None"}, // aux is a *gc.Node of a variable that is known to be dead. arg0=mem, returns mem
456+
{name: "VarLive", argLength: 1, aux: "Sym", symEffect: "Read", zeroWidth: true}, // aux is a *gc.Node of a variable that must be kept live. arg0=mem, returns mem
457+
{name: "KeepAlive", argLength: 2, typ: "Mem", zeroWidth: true}, // arg[0] is a value that must be kept alive until this mark. arg[1]=mem, returns mem
458458

459459
// Ops for breaking 64-bit operations on 32-bit architectures
460460
{name: "Int64Make", argLength: 2, typ: "UInt64"}, // arg0=hi, arg1=lo
@@ -481,8 +481,8 @@ var genericOps = []opData{
481481
{name: "Cvt64Fto64U", argLength: 1}, // float64 -> uint64, only used on archs that has the instruction
482482

483483
// pseudo-ops for breaking Tuple
484-
{name: "Select0", argLength: 1}, // the first component of a tuple
485-
{name: "Select1", argLength: 1}, // the second component of a tuple
484+
{name: "Select0", argLength: 1, zeroWidth: true}, // the first component of a tuple
485+
{name: "Select1", argLength: 1, zeroWidth: true}, // the second component of a tuple
486486

487487
// Atomic operations used for semantically inlining runtime/internal/atomic.
488488
// Atomic loads return a new memory so that the loads are properly ordered

src/cmd/compile/internal/ssa/gen/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type opData struct {
5454
faultOnNilArg1 bool // this op will fault if arg1 is nil (and aux encodes a small offset)
5555
usesScratch bool // this op requires scratch memory space
5656
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
57+
zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
5758
symEffect string // effect this op has on symbol in aux
5859
}
5960

@@ -216,6 +217,9 @@ func genOp() {
216217
if v.hasSideEffects {
217218
fmt.Fprintln(w, "hasSideEffects: true,")
218219
}
220+
if v.zeroWidth {
221+
fmt.Fprintln(w, "zeroWidth: true,")
222+
}
219223
needEffect := strings.HasPrefix(v.aux, "Sym")
220224
if v.symEffect != "" {
221225
if !needEffect {

src/cmd/compile/internal/ssa/op.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type opInfo struct {
3535
faultOnNilArg1 bool // this op will fault if arg1 is nil (and aux encodes a small offset)
3636
usesScratch bool // this op requires scratch memory space
3737
hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182.
38+
zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width.
3839
symEffect SymEffect // effect this op has on symbol in aux
3940
}
4041

0 commit comments

Comments
 (0)