Files
go/test/mem2reg.go
Junyang Shao 59b9e2dc57 cmd/compile: add mem2reg pass
This CL adds the mem2reg pass for scalar variables. It's an attempt to
translate LLVM's mem2reg pass:
https://llvm.org/doxygen/PromoteMemoryToRegister_8cpp_source.html.

The pass promotes address-taken stack variables to SSA values when the
address is only used by Loads and Stores. For each qualifying variable,
stores become the variable's current value, loads are replaced by that
value, and the memory operations (and their VarDefs) are removed. For
example, in

	var x int
	p := &x
	*p = a
	b := *p + 1

the store *p = a and the load *p never leave a value in memory: b is
computed directly from a, and x's stack slot goes away entirely.

This CL only handles variables whose loads and stores are all in a
single basic block; a later CL extends the analysis across blocks with
phi insertion.

This CL has some edge cases not handled, they should be easily findable
in the code by looking at where statistics are printed.

This CL might help #73589.

Updates #73589.

Change-Id: Iedee627971ad00324cc04d580e351a37fe88a6de
Reviewed-on: https://go-review.googlesource.com/c/go/+/713300
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2026-09-26 08:30:33 -07:00

44 lines
860 B
Go

// errorcheck -0 -d=ssa/mem2reg/debug=4
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test for variables accessed through pointers that can
// be promoted to register by the mem2reg pass.
package main
// The following functions are ported from src/cmd/compile/internal/ssa/mem2reg_test.go.
// Single-block mem2reg test
func justReturn0() int {
var x, y, z int // ERROR "promoted x in single block case" "promoted y in single block case" "promoted z in single block case"
xp := &x
yp := &y
zp := &z
*xp = 0
*yp = 1
*zp = 2
*yp = 3
*zp = 4
*yp = 5
valX1 := *xp
*zp = valX1 - 1
*xp = 1
*yp = 2
*xp = 3
*yp = 4
*xp = 5
valZ1 := *zp
*yp = valZ1 + 1
*zp = 1
*xp = 2
*zp = 3
*xp = 4
*zp = 5
valY1 := *yp
return valY1
}