Enable inline static init for go 1.21

April 19, 2023
go golang compiler

Prologue

In previous post, I talked about an upgrading node for go1.20, which has many regression bugs due to in-complete implementation of inlining static init. The issue is now fixed, and will be enabled by default again for go1.21 version.

The problem

The old implementation of inline static init use typecheck.EvalConst, which will do constant-evaluation for an expression. However, this function only evaluates the expression in constant context, while inline static init requires the expression is evaluated in non-constant context.

For this given code:

package p

var x = f(-1)

func f(x int) int {
	return 1 << x
}

It should be compiled and raise a runtime error at running time. With inline static init, the code will be rewritten to:

package p

var x = 1 << -1

func f(x int) int {
	return 1 << x
}

which raise a compile-time error because of 1 << -1 expression.

Solution

CL 466277 implements a safer approach, making inline static init only handles cases that known to be safe at compile time. Those cases are:

That would prevents regressions, and still open room for supporting other arithmetic operations in the future.


NOTE

This approach also leads to a better code generation for constant-fold switch, and removing typecheck.EvalConst entirely.

See this CLs chain for more details.


Epilogue

It takes me a while for figuring out this approach for inline static init, which not only make user code better, but also improving the quality of the go compiler code base. Please help testing with gotip (or RC version when it’s out) and report any bugs that you seen.

Thank you all for reading so far!

Till next time!


GopherCon 2023

October 2, 2023
gophercon community go golang

Improving parallel calls from C to Go performance

June 29, 2023
go golang cgo runtime

A practical optimization for Go compiler

May 25, 2023
go golang compiler