[llvm] r278370 - Make TwoAddressInstructionPass::rescheduleMIBelowKill subreg-aware

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 11 14:47:54 PDT 2016


Merged to 3.9 in r278422.

Thanks,
Hans

On Thu, Aug 11, 2016 at 10:38 AM, Michael Kuperstein via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: mkuper
> Date: Thu Aug 11 12:38:33 2016
> New Revision: 278370
>
> URL: http://llvm.org/viewvc/llvm-project?rev=278370&view=rev
> Log:
> Make TwoAddressInstructionPass::rescheduleMIBelowKill subreg-aware
>
> This fixes PR28824.
>
> Differential Revision: https://reviews.llvm.org/D23220
>
>
> Added:
>     llvm/trunk/test/CodeGen/X86/pr28824.ll
> Modified:
>     llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp
>
> Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=278370&r1=278369&r2=278370&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original)
> +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Thu Aug 11 12:38:33 2016
> @@ -29,7 +29,7 @@
>
>  #include "llvm/ADT/DenseMap.h"
>  #include "llvm/ADT/STLExtras.h"
> -#include "llvm/ADT/SmallSet.h"
> +#include "llvm/ADT/SmallVector.h"
>  #include "llvm/ADT/Statistic.h"
>  #include "llvm/Analysis/AliasAnalysis.h"
>  #include "llvm/CodeGen/LiveIntervalAnalysis.h"
> @@ -539,6 +539,16 @@ regsAreCompatible(unsigned RegA, unsigne
>    return TRI->regsOverlap(RegA, RegB);
>  }
>
> +// Returns true if Reg is equal or aliased to at least one register in Set.
> +static bool regOverlapsSet(const SmallVectorImpl<unsigned> &Set, unsigned Reg,
> +                           const TargetRegisterInfo *TRI) {
> +  for (unsigned R : Set)
> +    if (TRI->regsOverlap(R, Reg))
> +      return true;
> +
> +  return false;
> +}
> +
>  /// Return true if it's potentially profitable to commute the two-address
>  /// instruction that's being processed.
>  bool
> @@ -864,9 +874,9 @@ rescheduleMIBelowKill(MachineBasicBlock:
>      // FIXME: Needs more sophisticated heuristics.
>      return false;
>
> -  SmallSet<unsigned, 2> Uses;
> -  SmallSet<unsigned, 2> Kills;
> -  SmallSet<unsigned, 2> Defs;
> +  SmallVector<unsigned, 2> Uses;
> +  SmallVector<unsigned, 2> Kills;
> +  SmallVector<unsigned, 2> Defs;
>    for (const MachineOperand &MO : MI->operands()) {
>      if (!MO.isReg())
>        continue;
> @@ -874,12 +884,12 @@ rescheduleMIBelowKill(MachineBasicBlock:
>      if (!MOReg)
>        continue;
>      if (MO.isDef())
> -      Defs.insert(MOReg);
> +      Defs.push_back(MOReg);
>      else {
> -      Uses.insert(MOReg);
> +      Uses.push_back(MOReg);
>        if (MOReg != Reg && (MO.isKill() ||
>                             (LIS && isPlainlyKilled(MI, MOReg, LIS))))
> -        Kills.insert(MOReg);
> +        Kills.push_back(MOReg);
>      }
>    }
>
> @@ -888,8 +898,9 @@ rescheduleMIBelowKill(MachineBasicBlock:
>    MachineBasicBlock::iterator AfterMI = std::next(Begin);
>
>    MachineBasicBlock::iterator End = AfterMI;
> -  while (End->isCopy() && Defs.count(End->getOperand(1).getReg())) {
> -    Defs.insert(End->getOperand(0).getReg());
> +  while (End->isCopy() &&
> +         regOverlapsSet(Defs, End->getOperand(1).getReg(), TRI)) {
> +    Defs.push_back(End->getOperand(0).getReg());
>      ++End;
>    }
>
> @@ -915,21 +926,21 @@ rescheduleMIBelowKill(MachineBasicBlock:
>        if (!MOReg)
>          continue;
>        if (MO.isDef()) {
> -        if (Uses.count(MOReg))
> +        if (regOverlapsSet(Uses, MOReg, TRI))
>            // Physical register use would be clobbered.
>            return false;
> -        if (!MO.isDead() && Defs.count(MOReg))
> +        if (!MO.isDead() && regOverlapsSet(Defs, MOReg, TRI))
>            // May clobber a physical register def.
>            // FIXME: This may be too conservative. It's ok if the instruction
>            // is sunken completely below the use.
>            return false;
>        } else {
> -        if (Defs.count(MOReg))
> +        if (regOverlapsSet(Defs, MOReg, TRI))
>            return false;
>          bool isKill =
>              MO.isKill() || (LIS && isPlainlyKilled(&OtherMI, MOReg, LIS));
> -        if (MOReg != Reg &&
> -            ((isKill && Uses.count(MOReg)) || Kills.count(MOReg)))
> +        if (MOReg != Reg && ((isKill && regOverlapsSet(Uses, MOReg, TRI)) ||
> +                             regOverlapsSet(Kills, MOReg, TRI)))
>            // Don't want to extend other live ranges and update kills.
>            return false;
>          if (MOReg == Reg && !isKill)
>
> Added: llvm/trunk/test/CodeGen/X86/pr28824.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr28824.ll?rev=278370&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/pr28824.ll (added)
> +++ llvm/trunk/test/CodeGen/X86/pr28824.ll Thu Aug 11 12:38:33 2016
> @@ -0,0 +1,23 @@
> +; RUN: llc < %s -mtriple=i386-unknown-linux-gnu | FileCheck %s
> +
> + at d = global i32 0, align 4
> +
> +; Verify the sar happens before ecx is clobbered with the parameter being
> +; passed to fn3
> +; CHECK-LABEL: fn4
> +; CHECK: movb d, %cl
> +; CHECK: sarl %cl
> +; CHECK: movl $2, %ecx
> +define i32 @fn4(i32 %i) #0 {
> +entry:
> +  %0 = load i32, i32* @d, align 4
> +  %shr = ashr i32 %i, %0
> +  tail call fastcc void @fn3(i32 2, i32 5, i32 %shr, i32 %i)
> +  %cmp = icmp slt i32 %shr, 1
> +  %. = zext i1 %cmp to i32
> +  ret i32 %.
> +}
> +
> +declare void @fn3(i32 %p1, i32 %p2, i32 %p3, i32 %p4) #0
> +
> +attributes #0 = { nounwind }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list