[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