Fix the aggressive anti-dep breaker's subregister definition handling
authorHal Finkel <hfinkel@anl.gov>
Wed, 26 Feb 2014 20:20:30 +0000 (20:20 +0000)
committerHal Finkel <hfinkel@anl.gov>
Wed, 26 Feb 2014 20:20:30 +0000 (20:20 +0000)
The aggressive anti-dependency breaker scans instructions, bottom-up, within the
scheduling region in order to find opportunities where register renaming can
be used to break anti-dependencies.

Unfortunately, the aggressive anti-dep breaker was treating a register definition
as defining all of that register's aliases (including super registers). This behavior
is incorrect when the super register is live and there are other definitions of
subregisters of the super register.

For example, given the following sequence:

%CR2EQ<def> = CROR %CR3UN, %CR3UN<kill>
%CR2GT<def> = IMPLICIT_DEF
%X4<def> = MFOCRF8 %CR2

the analysis of the first subregister definition would work as expected:
Anti:   %CR2GT<def> = IMPLICIT_DEF
        Def Groups: CR2GT=g194->g0(via CR2)
        Antidep reg: CR2GT (zero group)
        Use Groups:

but the analysis of the second one would not:
Anti:   %CR2EQ<def> = CROR %CR3UN, %CR3UN<kill>
        Def Groups: CR2EQ=g195
        Antidep reg: CR2EQ
        Rename Candidates for Group g195: ...

because, when processing the %CR2GT<def>, we'd mark all super registers of
%CR2GT (%CR2 in this case) as defined. As a result, when processing
%CR2EQ<def>, %CR2 no longer appears to be live, and %CR2EQ<def>'s group is not
%unioned with the %CR2 group.

I don't have an in-tree test case for this yet (and even if I did, I don't have
a small one).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202294 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AggressiveAntiDepBreaker.cpp

index 2ee7767115875b1fce6d9d9872340c8f6b8c783d..25c438c9615a43eec4e6ec9f91fcc62808196048 100644 (file)
@@ -403,8 +403,18 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI,
       continue;
 
     // Update def for Reg and aliases.
-    for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
+    for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
+      // We need to be careful here not to define already-live super registers.
+      // If the super register is already live, then this definition is not
+      // a definition of the whole super register (just a partial insertion
+      // into it). Earlier subregister definitions (which we've not yet visited
+      // because we're iterating bottom-up) need to be linked to the same group
+      // as this definition.
+      if (TRI->isSuperRegister(Reg, *AI) && State->IsLive(*AI))
+        continue;
+
       DefIndices[*AI] = Count;
+    }
   }
 }