Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: unnecessary array copying in for range loop #33838

Closed
mariecurried opened this issue Aug 26, 2019 · 3 comments
Closed

cmd/compile: unnecessary array copying in for range loop #33838

mariecurried opened this issue Aug 26, 2019 · 3 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance

Comments

@mariecurried
Copy link

What version of Go are you using (go version)?

$ go version
go version devel +739123c Sun Aug 25 00:27:25 2019 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What did you do?

I compiled the following program and analyzed the assembly code generated (https://godbolt.org/z/QXblVs):

package test

func f(x [][4]int) [][3]int {
    res := make([][3]int, len(x))

    for i, v := range x {
        res[i][0] = v[0]
        res[i][1] = v[1]
        res[i][2] = v[2]
    }

    return res
}

What did you expect to see?

I expected the looping part of this function to not contain unnecessary instructions, like in (https://godbolt.org/z/L3hIuW):

package test

func f(x [][4]int) [][3]int {
    res := make([][3]int, len(x))

    for i := range x {
        res[i][0] = x[i][0]
        res[i][1] = x[i][1]
        res[i][2] = x[i][2]
    }

    return res
}
        leaq    (BX)(BX*2), SI
        movq    BX, DI
        shlq    $5, BX
        movq    (DX)(BX*1), R8
        movq    R8, (AX)(SI*8)
        movq    8(DX)(BX*1), R8
        movq    R8, 8(AX)(SI*8)
        movq    16(DX)(BX*1), R8
        movq    R8, 16(AX)(SI*8)

What did you see instead?

Instead, it was compiled to all this instructions, most of which are unnecessary (https://godbolt.org/z/QXblVs):

        movups  (DX), X0
        movups  X0, ""..autotmp_10+64(SP)
        movups  16(DX), X0
        movups  X0, ""..autotmp_10+80(SP)
        movups  ""..autotmp_10+64(SP), X0
        movups  X0, "".v+32(SP)
        movups  ""..autotmp_10+80(SP), X0
        movups  X0, "".v+48(SP)
        leaq    (BX)(BX*2), SI
        movq    "".v+32(SP), DI
        movq    DI, (AX)(SI*8)
        movq    "".v+40(SP), DI
        movq    DI, 8(AX)(SI*8)
        movq    "".v+48(SP), DI
        movq    DI, 16(AX)(SI*8)

Note: There are probably open issues about this, but I couldn't find any.

@av86743
Copy link

av86743 commented Aug 26, 2019

Semantics of v being a copy in for i, v := range x presents a challenge. You need either to erase allocations (which is painful and backward), or to have a separate path where v is not copied but just referenced (which is not there.)

With the current overall state of the project, I think the most you will get out of your example is a promise of another future vet warning, as problem can be resolved at the source level.

@randall77
Copy link
Contributor

I would call this a dup of #24416, as the whole [4]int currently needs to be copied.

@bcmills bcmills added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance labels Aug 26, 2019
@bcmills
Copy link
Contributor

bcmills commented Aug 26, 2019

Duplicate of #24416

@bcmills bcmills marked this as a duplicate of #24416 Aug 26, 2019
@bcmills bcmills closed this as completed Aug 26, 2019
@golang golang locked and limited conversation to collaborators Aug 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Performance
Projects
None yet
Development

No branches or pull requests

5 participants