]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix score for Select{0,1} with type flags
authorLynn Boger <laboger@linux.vnet.ibm.com>
Tue, 16 Aug 2022 17:06:10 +0000 (12:06 -0500)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Fri, 26 Aug 2022 19:15:02 +0000 (19:15 +0000)
A recent change was made for ppc64x to treat ANDCCconst as
a tuple, allowing ANDconst to be removed from the list
of ops. Included in that change were some improvements to the
rules to avoid some extra code, mainly the elimination of a
cmp 0 following an andi. and in some cases the following
isel. While those changes worked for most cases, in a few
cases some extra unnecessary code was generated.

Currently the snippet appears in archive/zip.(*FileHeader).Mode:

        ANDCC R4,$1,R5                       // andi. r5,r4,1
        ANDCC R4,$16,R5                      // andi. r5,r4,16
        CMPW R5,R0                           // cmpw r5,r0
        ADDIS $0,$-32768,R5                  // lis r5,-32768
        OR R5,$511,R5                        // ori r5,r5,511
        MOVD $438,R6                         // li r6,438
        ISEL $2,R6,R5,R5                     // isel r5,r6,r5,eq
        MOVD $-147,R6                        // li r6,-147
        AND R6,R5,R6                         // and r6,r5,r6
        ANDCC R4,$1,R4                       // andi. r4,r4,1
        ISEL $2,R5,R6,R4                     // isel r4,r5,r6,eq

The first ANDCC is never used and should not be there.
From the ssa.html file, the scheduler is not putting the Select1
close to the ISEL, which results in the flag being clobbered
before it can be used. By changing the score for a Select0 or Select1
with type Flags, the extra ANDCC does not occur.

Change-Id: I82f4bc7c02afb1c2b1c048dc6995e0b3f9363fb3
Reviewed-on: https://go-review.googlesource.com/c/go/+/424294
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Paul Murphy <murp@ibm.com>
src/cmd/compile/internal/ssa/schedule.go

index 7ef04b2c32d3e8a23ca422b4217bfe5694b55562..ebf84d59b38ec6935444a7e5441a09e7de1f186c 100644 (file)
@@ -155,16 +155,10 @@ func schedule(f *Func) {
                                // VARDEF ops are scheduled before the corresponding LEA.
                                score[v.ID] = ScoreMemory
                        case v.Op == OpSelect0 || v.Op == OpSelect1 || v.Op == OpSelectN:
-                               // Schedule the pseudo-op of reading part of a tuple
-                               // immediately after the tuple-generating op, since
-                               // this value is already live. This also removes its
-                               // false dependency on the other part of the tuple.
-                               // Also ensures tuple is never spilled.
-                               if (v.Op == OpSelect1 || v.Op == OpSelect0) && v.Args[0].Op.isCarry() {
-                                       // Score tuple ops of carry ops later to ensure they do not
-                                       // delay scheduling the tuple-generating op. If such tuple ops
-                                       // are not placed more readily, unrelated carry clobbering ops
-                                       // may be placed inbetween two carry-dependent operations.
+                               if (v.Op == OpSelect1 || v.Op == OpSelect0) && (v.Args[0].Op.isCarry() || v.Type.IsFlags()) {
+                                       // When the Select pseudo op is being used for a carry or flag from
+                                       // a tuple then score it as ScoreFlags so it happens later. This
+                                       // prevents the bit from being clobbered before it is used.
                                        score[v.ID] = ScoreFlags
                                } else {
                                        score[v.ID] = ScoreReadTuple