[llvm-commits] [llvm] r56326 - in /llvm/trunk: include/llvm/CodeGen/LiveInterval.h include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveInterval.cpp lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/RegAllocLinearScan.cpp

Dan Gohman gohman at apple.com
Tue Sep 23 16:11:45 PDT 2008


Hi Dale,

This commit caused a regression in
test/CodeGen/PowerPC/2007-09-11-RegCoalescerAssert.ll
in the "martini x86_64" nightly tester.

It's an llc abort, and it's reproducible by running
llc with the following explicit triple:
-march=ppc64 -mtriple=powerpc-unknown-linux-gnu

Can you investigate?

Thanks,

Dan

On Sep 18, 2008, at 6:02 PM, Dale Johannesen wrote:

> Author: johannes
> Date: Thu Sep 18 20:02:35 2008
> New Revision: 56326
>
> URL: http://llvm.org/viewvc/llvm-project?rev=56326&view=rev
> Log:
> Remove AsmThatEarlyClobber etc. from LiveIntervalAnalysis
> and redo as linked list walk.  Logic moved into RA.
> Per review feedback.
>
>
> Modified:
>    llvm/trunk/include/llvm/CodeGen/LiveInterval.h
>    llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
>    llvm/trunk/lib/CodeGen/LiveInterval.cpp
>    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
>    llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=56326&r1=56325&r2=56326&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Thu Sep 18  
> 20:02:35 2008
> @@ -105,12 +105,17 @@
>                          // if the top bits is set, it represents a  
> stack slot.
>     unsigned preference; // preferred register to allocate for this  
> interval
>     float weight;        // weight of this interval
> +    bool isEarlyClobber;
> +    bool overlapsEarlyClobber;
>     Ranges ranges;       // the ranges in which this register is live
>     VNInfoList valnos;   // value#'s
>
>   public:
> -    LiveInterval(unsigned Reg, float Weight, bool IsSS = false)
> -      : reg(Reg), preference(0), weight(Weight) {
> +    LiveInterval(unsigned Reg, float Weight, bool IsSS = false,
> +                 bool IsEarlyClobber = false, bool  
> OverlapsEarlyClobber = false)
> +      : reg(Reg), preference(0), weight(Weight),
> +        isEarlyClobber(IsEarlyClobber),
> +        overlapsEarlyClobber(OverlapsEarlyClobber) {
>       if (IsSS)
>         reg = reg | (1U << (sizeof(unsigned)*8-1));
>     }
>
> Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=56326&r1=56325&r2=56326&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Sep  
> 18 20:02:35 2008
> @@ -65,22 +65,6 @@
>     AliasAnalysis *aa_;
>     LiveVariables* lv_;
>
> -    /// AsmsWithEarlyClobber - maps a virtual register number to  
> all the
> -    /// inline asm's that have the register marked earlyclobber.
> -    ///
> -    std::multimap<unsigned, MachineInstr*> AsmsThatEarlyClobber;
> -
> -    /// AsmsWithEarlyClobberConflict - maps a virtual register number
> -    /// to all the inline asm's that have earlyclobber operands  
> elsewhere
> -    /// and use the register as a (non-earlyclobber) input.
> -    ///
> -    /// Note: earlyclobber operands may not be assigned the same  
> register as
> -    /// each other, or as earlyclobber-conflict operands.  However  
> two
> -    /// earlyclobber-conflict operands may be assigned the same  
> register if
> -    /// they happen to contain the same value.
> -    ///
> -    std::multimap<unsigned, MachineInstr*>  
> AsmsWithEarlyClobberConflict;
> -
>     /// Special pool allocator for VNInfo's (LiveInterval val#).
>     ///
>     BumpPtrAllocator VNInfoAllocator;
> @@ -353,11 +337,6 @@
>     unsigned getNumConflictsWithPhysReg(const LiveInterval &li,
>                                         unsigned PhysReg) const;
>
> -    /// noEarlyclobberConflict - see whether virtual reg VReg has a  
> conflict
> -    /// with hard reg HReg because HReg is used as an earlyclobber  
> register in
> -    /// asm that also has VReg live into or across it.
> -    bool noEarlyclobberConflict(unsigned VReg, VirtRegMap &vrm,  
> unsigned HReg);
> -
>     /// computeNumbering - Compute the index numbering.
>     void computeNumbering();
>
>
> Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=56326&r1=56325&r2=56326&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Thu Sep 18 20:02:35 2008
> @@ -686,6 +686,10 @@
>     OS << "%reg" << reg;
>
>   OS << ',' << weight;
> +  if (isEarlyClobber)
> +    OS << ",earlyclobber";
> +  if (overlapsEarlyClobber)
> +    OS << ",overlapsearly";
>
>   if (empty())
>     OS << " EMPTY";
>
> Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=56326&r1=56325&r2=56326&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Sep 18  
> 20:02:35 2008
> @@ -674,8 +674,6 @@
> /// live interval is an interval [i, j) where 1 <= i <= j < N for
> /// which a variable is live
> void LiveIntervals::computeIntervals() {
> -  AsmsThatEarlyClobber.clear();
> -  AsmsWithEarlyClobberConflict.clear();
>
>   DOUT << "********** COMPUTING LIVE INTERVALS **********\n"
>        << "********** Function: "
> @@ -716,13 +714,15 @@
>         if (MO.isRegister() && MO.getReg() && MO.isDef()) {
>           handleRegisterDef(MBB, MI, MIIndex, MO, i);
>           if (MO.isEarlyClobber()) {
> -            AsmsThatEarlyClobber.insert(std::make_pair(MO.getReg(),  
> MI));
> +            LiveInterval &interval =   
> getOrCreateInterval(MO.getReg());
> +            interval.isEarlyClobber = true;
>           }
>         }
>         if (MO.isRegister() && !MO.isDef() &&
>             MO.getReg() &&  
> TargetRegisterInfo::isVirtualRegister(MO.getReg()) &&
>             MO.overlapsEarlyClobber()) {
> -           
> AsmsWithEarlyClobberConflict.insert(std::make_pair(MO.getReg(), MI));
> +          LiveInterval &interval = getOrCreateInterval(MO.getReg());
> +          interval.overlapsEarlyClobber = true;
>         }
>       }
>
> @@ -752,73 +752,6 @@
>   return ResVal;
> }
>
> -/// noEarlyclobberConflict - see whether virtual reg VReg has a  
> conflict with
> -/// hard reg HReg because of earlyclobbers.
> -///
> -/// Earlyclobber operands may not be assigned the same register as
> -/// each other, or as earlyclobber-conflict operands (i.e. those that
> -/// are non-earlyclobbered inputs to an asm that also has  
> earlyclobbers).
> -///
> -/// Thus there are two cases to check for:
> -/// 1.  VReg is an earlyclobber-conflict register and HReg is an  
> earlyclobber
> -/// register in some asm that also has VReg as an input.
> -/// 2.  VReg is an earlyclobber register and HReg is an  
> earlyclobber-conflict
> -/// input elsewhere in some asm.
> -/// In both cases HReg can be assigned by the user, or assigned  
> early in
> -/// register allocation.
> -///
> -/// Dropping the distinction between earlyclobber and earlyclobber- 
> conflict,
> -/// keeping only one multimap, looks promising, but two  
> earlyclobber-conflict
> -/// operands may be assigned the same register if they happen to  
> contain the
> -/// same value, and that implementation would prevent this.
> -///
> -bool LiveIntervals::noEarlyclobberConflict(unsigned VReg,  
> VirtRegMap &vrm,
> -                                           unsigned HReg) {
> -  typedef std::multimap<unsigned, MachineInstr*>::iterator It;
> -
> -  // Short circuit the most common case.
> -  if (AsmsWithEarlyClobberConflict.size()!=0) {
> -    std::pair<It, It> x =  
> AsmsWithEarlyClobberConflict.equal_range(VReg);
> -    for (It I = x.first; I!=x.second; I++) {
> -      MachineInstr* MI = I->second;
> -      for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
> -        MachineOperand &MO = MI->getOperand(i);
> -        if (MO.isRegister() && MO.isEarlyClobber()) {
> -          unsigned PhysReg = MO.getReg();
> -          if (PhysReg &&  
> TargetRegisterInfo::isVirtualRegister(PhysReg)) {
> -            if (!vrm.hasPhys(PhysReg))
> -              continue;
> -            PhysReg = vrm.getPhys(PhysReg);
> -          }
> -          if (PhysReg==HReg)
> -            return false;
> -        }
> -      }
> -    }
> -  }
> -  // Short circuit the most common case.
> -  if (AsmsThatEarlyClobber.size()!=0) {
> -    std::pair<It, It> x = AsmsThatEarlyClobber.equal_range(VReg);
> -    for (It I = x.first; I!=x.second; I++) {
> -      MachineInstr* MI = I->second;
> -      for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
> -        MachineOperand &MO = MI->getOperand(i);
> -        if (MO.isRegister() && MO.overlapsEarlyClobber()) {
> -          unsigned PhysReg = MO.getReg();
> -          if (PhysReg &&  
> TargetRegisterInfo::isVirtualRegister(PhysReg)) {
> -            if (!vrm.hasPhys(PhysReg))
> -              continue;
> -            PhysReg = vrm.getPhys(PhysReg);
> -          }
> -          if (PhysReg==HReg)
> -            return false;
> -        }
> -      }
> -    }
> -  }
> -  return true;
> -}
> -
> LiveInterval* LiveIntervals::createInterval(unsigned reg) {
>   float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ?
>                        HUGE_VALF : 0.0F;
>
> Modified: llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp?rev=56326&r1=56325&r2=56326&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp (original)
> +++ llvm/trunk/lib/CodeGen/RegAllocLinearScan.cpp Thu Sep 18  
> 20:02:35 2008
> @@ -173,6 +173,8 @@
>
>     void ComputeRelatedRegClasses();
>
> +    bool noEarlyClobberConflict(LiveInterval *cur, unsigned RegNo);
> +
>     template <typename ItTy>
>     void printIntervals(const char* const str, ItTy i, ItTy e) const {
>       if (str) DOUT << str << " intervals:\n";
> @@ -1001,6 +1003,73 @@
>     unhandled_.push(added[i]);
> }
>
> +/// noEarlyClobberConflict - see whether LiveInternal cur has a  
> conflict with
> +/// hard reg HReg because of earlyclobbers.
> +///
> +/// Earlyclobber operands may not be assigned the same register as
> +/// each other, or as earlyclobber-conflict operands (i.e. those that
> +/// are non-earlyclobbered inputs to an asm that also has  
> earlyclobbers).
> +///
> +/// Thus there are two cases to check for:
> +/// 1.  cur->reg is an earlyclobber-conflict register and HReg is an
> +/// earlyclobber register in some asm that also has cur->reg as an  
> input.
> +/// 2.  cur->reg is an earlyclobber register and HReg is an
> +/// earlyclobber-conflict input, or a different earlyclobber  
> register,
> +/// elsewhere in some asm.
> +/// In both cases HReg can be assigned by the user, or assigned  
> early in
> +/// register allocation.
> +///
> +/// Dropping the distinction between earlyclobber and earlyclobber- 
> conflict,
> +/// keeping only one bit, looks promising, but two earlyclobber- 
> conflict
> +/// operands may be assigned the same register if they happen to  
> contain the
> +/// same value, and that implementation would prevent this.
> +///
> +bool RALinScan::noEarlyClobberConflict(LiveInterval *cur, unsigned  
> HReg) {
> +  if (cur->overlapsEarlyClobber) {
> +    for (MachineRegisterInfo::use_iterator I = mri_->use_begin(cur- 
> >reg),
> +          E = mri_->use_end(); I!=E; ++I) {
> +      MachineInstr *MI = I.getOperand().getParent();
> +      if (MI->getOpcode()==TargetInstrInfo::INLINEASM) {
> +        for (int i = MI->getNumOperands()-1; i>=0; --i) {
> +          MachineOperand &MO = MI->getOperand(i);
> +          if (MO.isRegister() && MO.getReg() && MO.isEarlyClobber()  
> &&
> +              HReg==MO.getReg()) {
> +            DOUT << "  earlyclobber conflict: " <<
> +                  "%reg" << cur->reg << ", " << tri_->getName(HReg)  
> << "\n\t";
> +            return false;
> +          }
> +        }
> +      }
> +    }
> +  }
> +  if (cur->isEarlyClobber) {
> +    for (MachineRegisterInfo::def_iterator I = mri_->def_begin(cur- 
> >reg),
> +          E = mri_->def_end(); I!=E; ++I) {
> +      MachineInstr *MI = I.getOperand().getParent();
> +      if (MI->getOpcode()==TargetInstrInfo::INLINEASM) {
> +        // make sure cur->reg is really clobbered in this  
> instruction.
> +        bool earlyClobberFound = false, overlapFound = false;
> +        for (int i = MI->getNumOperands()-1; i>=0; --i) {
> +          MachineOperand &MO = MI->getOperand(i);
> +          if (MO.isRegister() && MO.getReg()) {
> +            if ((MO.overlapsEarlyClobber() || MO.isEarlyClobber()) &&
> +                HReg==MO.getReg())
> +              overlapFound = true;
> +            if (MO.isEarlyClobber() && cur->reg==MO.getReg())
> +              earlyClobberFound = true;
> +          }
> +        }
> +        if (earlyClobberFound && overlapFound) {
> +          DOUT << "  earlyclobber conflict: " <<
> +                  "%reg" << cur->reg << ", " << tri_->getName(HReg)  
> << "\n\t";
> +          return false;
> +        }
> +      }
> +    }
> +  }
> +  return true;
> +}
> +
> /// getFreePhysReg - return a free physical register for this  
> virtual register
> /// interval if we have one, otherwise return 0.
> unsigned RALinScan::getFreePhysReg(LiveInterval *cur) {
> @@ -1049,7 +1118,7 @@
>   assert(I != E && "No allocatable register in this register class!");
>   for (; I != E; ++I)
>     if (prt_->isRegAvail(*I) &&
> -        li_->noEarlyclobberConflict(cur->reg, *vrm_, *I)) {
> +        noEarlyClobberConflict(cur, *I)) {
>       FreeReg = *I;
>       if (FreeReg < inactiveCounts.size())
>         FreeRegInactiveCount = inactiveCounts[FreeReg];
> @@ -1070,7 +1139,7 @@
>     unsigned Reg = *I;
>     if (prt_->isRegAvail(Reg) && Reg < inactiveCounts.size() &&
>         FreeRegInactiveCount < inactiveCounts[Reg] &&
> -        li_->noEarlyclobberConflict(cur->reg, *vrm_, Reg)) {
> +        noEarlyClobberConflict(cur, *I)) {
>       FreeReg = Reg;
>       FreeRegInactiveCount = inactiveCounts[Reg];
>       if (FreeRegInactiveCount == MaxInactiveCount)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list