[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

Dale Johannesen dalej at apple.com
Tue Sep 23 16:13:44 PDT 2008


On Sep 23, 2008, at 4:11 PMPDT, Dan Gohman wrote:

> 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?

Sure.

>
> 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
>
> _______________________________________________
> 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