[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