compiler: rename named unused global vars to "_"
So that (*codegen).Visit is able to omit code generation for these unused global vars. The most tricky part is to detect unused global variables, it is done in several steps: 1. Collect the set of named used/unused global vars. 2. Collect the set of globally declared expressions that contain function calls. 3. Pick up global vars from the set made at step 2. 4. Traverse used functions and puck up those global vars that are used from these functions. 5. Rename all globals that are presented in the set made at step 1 but are not presented in the set made on step 3 or step 4.
This commit is contained in:
parent
1e6b70d570
commit
800321db06
10 changed files with 903 additions and 22 deletions
2
pkg/compiler/testdata/foo/foo.go
vendored
2
pkg/compiler/testdata/foo/foo.go
vendored
|
@ -5,7 +5,7 @@ func NewBar() int {
|
|||
return 10
|
||||
}
|
||||
|
||||
// Dummy is dummy constant.
|
||||
// Dummy is dummy variable.
|
||||
var Dummy = 1
|
||||
|
||||
// Foo is a type.
|
||||
|
|
18
pkg/compiler/testdata/globalvar/funccall/main.go
vendored
Normal file
18
pkg/compiler/testdata/globalvar/funccall/main.go
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
package funccall
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler/testdata/globalvar/nested1"
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler/testdata/globalvar/nested2"
|
||||
alias "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/globalvar/nested3"
|
||||
)
|
||||
|
||||
// F should be called from the main package to check usage analyzer against
|
||||
// nested constructions handling.
|
||||
func F() int {
|
||||
return nested1.F(nested2.Argument + alias.Argument)
|
||||
}
|
||||
|
||||
// GetAge calls method on the global struct.
|
||||
func GetAge() int {
|
||||
return alias.Anna.GetAge()
|
||||
}
|
14
pkg/compiler/testdata/globalvar/main.go
vendored
Normal file
14
pkg/compiler/testdata/globalvar/main.go
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
package globalvar
|
||||
|
||||
// Unused shouldn't produce any initialization code if it's not used anywhere.
|
||||
var Unused = 3
|
||||
|
||||
// Default is initialized by default value.
|
||||
var Default int
|
||||
|
||||
// A initialized by function call, thus the initialization code should always be emitted.
|
||||
var A = f()
|
||||
|
||||
func f() int {
|
||||
return 5
|
||||
}
|
29
pkg/compiler/testdata/globalvar/nested1/main.go
vendored
Normal file
29
pkg/compiler/testdata/globalvar/nested1/main.go
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
package nested1
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler/testdata/globalvar/nested2"
|
||||
alias "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/globalvar/nested3"
|
||||
)
|
||||
|
||||
// Unused shouldn't produce any code if unused.
|
||||
var Unused = 11
|
||||
|
||||
// A should produce call to f and should not be DROPped if C is used. It uses
|
||||
// aliased package var as an argument to check analizator.
|
||||
var A = f(alias.Argument)
|
||||
|
||||
// B should produce call to f and be DROPped if unused. It uses foreign package var as an argument
|
||||
// to check analizator.
|
||||
var B = f(nested2.Argument)
|
||||
|
||||
// C shouldn't produce any code if unused. It uses
|
||||
var C = A + nested2.A + nested2.Unique
|
||||
|
||||
func f(i int) int {
|
||||
return i
|
||||
}
|
||||
|
||||
// F is used for nested calls check.
|
||||
func F(i int) int {
|
||||
return i
|
||||
}
|
20
pkg/compiler/testdata/globalvar/nested2/main.go
vendored
Normal file
20
pkg/compiler/testdata/globalvar/nested2/main.go
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
package nested2
|
||||
|
||||
// Unused shouldn't produce any code if unused.
|
||||
var Unused = 21
|
||||
|
||||
// Argument is an argument used from external package to call nested1.f.
|
||||
var Argument = 22
|
||||
|
||||
// A has the same name as nested1.A.
|
||||
var A = 23
|
||||
|
||||
// B should produce call to f and be DROPped if unused.
|
||||
var B = f()
|
||||
|
||||
// Unique has unique name.
|
||||
var Unique = 24
|
||||
|
||||
func f() int {
|
||||
return 25
|
||||
}
|
18
pkg/compiler/testdata/globalvar/nested3/main.go
vendored
Normal file
18
pkg/compiler/testdata/globalvar/nested3/main.go
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
package nested3
|
||||
|
||||
// Argument is used as a function argument.
|
||||
var Argument = 34
|
||||
|
||||
// Anna is used to check struct-related usage analyzer logic (calls to methods
|
||||
// and fields).
|
||||
var Anna = Person{Age: 24}
|
||||
|
||||
// Person is an auxiliary structure containing simple field.
|
||||
type Person struct {
|
||||
Age int
|
||||
}
|
||||
|
||||
// GetAge is used to check method calls inside usage analyzer.
|
||||
func (p Person) GetAge() int {
|
||||
return p.Age
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue