From 86b49f8e2de796cb46c7c8b6a4c4900533fd53f4 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Wed, 24 Sep 2008 01:07:17 +0000 Subject: [PATCH] Next round of earlyclobber handling. Approach the RA problem by expanding the live interval of an earlyclobber def back one slot. Remove overlap-earlyclobber throughout. Remove earlyclobber bits and their handling from live internals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56539 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveInterval.h | 10 +- include/llvm/CodeGen/MachineOperand.h | 21 +--- include/llvm/CodeGen/ScheduleDAG.h | 4 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 3 +- lib/CodeGen/LiveInterval.cpp | 4 - lib/CodeGen/LiveIntervalAnalysis.cpp | 28 +++--- lib/CodeGen/MachineInstr.cpp | 9 +- lib/CodeGen/RegAllocLinearScan.cpp | 99 +------------------ lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp | 23 +---- .../SelectionDAG/SelectionDAGBuild.cpp | 31 ++---- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 5 +- lib/CodeGen/SimpleRegisterCoalescing.cpp | 12 --- 12 files changed, 42 insertions(+), 207 deletions(-) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index b346787bd9d..0d5acb83926 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -104,19 +104,13 @@ namespace llvm { unsigned reg; // the register or stack slot of this interval // if the top bits is set, it represents a stack slot. float weight; // weight of this interval - // The next 3 fields pack into a single word (on most hosts). - // Logically the first two could be bitfields, but that's slower. - bool isEarlyClobber; // marked earlyclobber in some asm - bool overlapsEarlyClobber; // input to asm that has an earlyclobber unsigned short preference; // preferred register for this interval Ranges ranges; // the ranges in which this register is live VNInfoList valnos; // value#'s public: - LiveInterval(unsigned Reg, float Weight, bool IsSS = false, - bool IsEarlyClobber = false, bool OverlapsEarlyClobber = false) - : reg(Reg), weight(Weight), isEarlyClobber(IsEarlyClobber), - overlapsEarlyClobber(OverlapsEarlyClobber), preference(0) { + LiveInterval(unsigned Reg, float Weight, bool IsSS = false) + : reg(Reg), weight(Weight), preference(0) { if (IsSS) reg = reg | (1U << (sizeof(unsigned)*8-1)); } diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index c2399beaf6e..40876dbfcae 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -73,12 +73,6 @@ private: /// model the GCC inline asm '&' constraint modifier. bool IsEarlyClobber : 1; - /// OverlapsEarlyClobber - True if this MO_Register operand is used as an - /// input to an inline asm that has the earlyclobber bit set on some other - /// operand. Flag is not valid for any other case. See gcc doc - /// for description of earlyclobber. - bool OverlapsEarlyClobber : 1; - /// SubReg - Subregister number, only valid for MO_Register. A value of 0 /// indicates the MO_Register has no subReg. unsigned char SubReg; @@ -188,11 +182,6 @@ public: return IsEarlyClobber; } - bool overlapsEarlyClobber() const { - assert(isRegister() && "Wrong MachineOperand accessor"); - return OverlapsEarlyClobber; - } - /// getNextOperandForReg - Return the next MachineOperand in the function that /// uses or defines this register. MachineOperand *getNextOperandForReg() const { @@ -243,11 +232,6 @@ public: IsEarlyClobber = Val; } - void setOverlapsEarlyClobber(bool Val = true) { - assert(isRegister() && "Wrong MachineOperand accessor"); - OverlapsEarlyClobber = Val; - } - //===--------------------------------------------------------------------===// // Accessors for various operand types. //===--------------------------------------------------------------------===// @@ -353,15 +337,13 @@ public: static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp = false, bool isKill = false, bool isDead = false, unsigned SubReg = 0, - bool isEarlyClobber = false, - bool overlapsEarlyClobber = false) { + bool isEarlyClobber = false) { MachineOperand Op(MachineOperand::MO_Register); Op.IsDef = isDef; Op.IsImp = isImp; Op.IsKill = isKill; Op.IsDead = isDead; Op.IsEarlyClobber = isEarlyClobber; - Op.OverlapsEarlyClobber = overlapsEarlyClobber; Op.Contents.Reg.RegNo = Reg; Op.Contents.Reg.Prev = 0; Op.Contents.Reg.Next = 0; @@ -408,7 +390,6 @@ public: IsKill = MO.IsKill; IsDead = MO.IsDead; IsEarlyClobber = MO.IsEarlyClobber; - OverlapsEarlyClobber = MO.OverlapsEarlyClobber; SubReg = MO.SubReg; ParentMI = MO.ParentMI; Contents = MO.Contents; diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 950d32ba619..06bb0361159 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -361,9 +361,7 @@ namespace llvm { void AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, const TargetInstrDesc *II, - DenseMap &VRBaseMap, - bool overlapsEarlyClobber = false); - + DenseMap &VRBaseMap); void AddMemOperand(MachineInstr *MI, const MachineMemOperand &MO); void EmitCrossRCCopy(SUnit *SU, DenseMap &VRBaseMap); diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 42a61c624c6..de856c165af 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1325,8 +1325,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { false, false, false); else { AsmPrinter *AP = const_cast(this); - if ((OpFlags & 7) == 4 /*ADDR MODE*/ || - (OpFlags & 7) == 7) /*ADDR MODE OVERLAPS EARLYCLOBBER*/ { + if ((OpFlags & 7) == 4) { Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant, Modifier[0] ? Modifier : 0); } else { diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 06e9722b974..ff430d71c7d 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -686,10 +686,6 @@ void LiveInterval::print(std::ostream &OS, OS << "%reg" << reg; OS << ',' << weight; - if (isEarlyClobber) - OS << ",earlyclobber"; - if (overlapsEarlyClobber) - OS << ",overlapsearly"; if (empty()) OS << " EMPTY"; diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index e0ff198056f..bc66321b4af 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -348,6 +348,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, if (interval.empty()) { // Get the Idx of the defining instructions. unsigned defIndex = getDefIndex(MIIdx); + // Earlyclobbers move back one. + if (MO.isEarlyClobber()) + defIndex = getUseIndex(MIIdx); VNInfo *ValNo; MachineInstr *CopyMI = NULL; unsigned SrcReg, DstReg; @@ -431,6 +434,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, assert(interval.containsOneValue()); unsigned DefIndex = getDefIndex(interval.getValNumInfo(0)->def); unsigned RedefIndex = getDefIndex(MIIdx); + // Earlyclobbers move back one. + if (MO.isEarlyClobber()) + RedefIndex = getUseIndex(MIIdx); const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1); VNInfo *OldValNo = OldLR->valno; @@ -498,6 +504,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // live until the end of the block. We've already taken care of the // rest of the live range. unsigned defIndex = getDefIndex(MIIdx); + // Earlyclobbers move back one. + if (MO.isEarlyClobber()) + defIndex = getUseIndex(MIIdx); VNInfo *ValNo; MachineInstr *CopyMI = NULL; @@ -532,6 +541,9 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, unsigned baseIndex = MIIdx; unsigned start = getDefIndex(baseIndex); + // Earlyclobbers move back one. + if (MO.isEarlyClobber()) + start = getUseIndex(MIIdx); unsigned end = start; // If it is not used after definition, it is considered dead at @@ -539,7 +551,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, // [defSlot(def), defSlot(def)+1) if (MO.isDead()) { DOUT << " dead"; - end = getDefIndex(start) + 1; + end = start + 1; goto exit; } @@ -561,7 +573,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, // it. Hence its interval is: // [defSlot(def), defSlot(def)+1) DOUT << " dead"; - end = getDefIndex(start) + 1; + end = start + 1; goto exit; } @@ -572,7 +584,7 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB, // instruction where we know it's dead is if it is live-in to the function // and never used. assert(!CopyMI && "physreg was not killed in defining block!"); - end = getDefIndex(start) + 1; // It's dead. + end = start + 1; exit: assert(start < end && "did not find end of interval?"); @@ -713,16 +725,6 @@ void LiveIntervals::computeIntervals() { // handle register defs - build intervals if (MO.isRegister() && MO.getReg() && MO.isDef()) { handleRegisterDef(MBB, MI, MIIndex, MO, i); - if (MO.isEarlyClobber()) { - LiveInterval &interval = getOrCreateInterval(MO.getReg()); - interval.isEarlyClobber = true; - } - } - if (MO.isRegister() && !MO.isDef() && - MO.getReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg()) && - MO.overlapsEarlyClobber()) { - LiveInterval &interval = getOrCreateInterval(MO.getReg()); - interval.overlapsEarlyClobber = true; } } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 7d44d4ee79f..4db02f49819 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -109,7 +109,6 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, // register's use/def lists. if (isRegister()) { assert(!isEarlyClobber()); - assert(!isEarlyClobber() && !overlapsEarlyClobber()); setReg(Reg); } else { // Otherwise, change this to a register and set the reg#. @@ -129,7 +128,6 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, IsKill = isKill; IsDead = isDead; IsEarlyClobber = false; - OverlapsEarlyClobber = false; SubReg = 0; } @@ -185,14 +183,9 @@ void MachineOperand::print(std::ostream &OS, const TargetMachine *TM) const { OS << "%mreg" << getReg(); } - if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber() || - overlapsEarlyClobber()) { + if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) { OS << "<"; bool NeedComma = false; - if (overlapsEarlyClobber()) { - NeedComma = true; - OS << "overlapsearly"; - } if (isImplicit()) { if (NeedComma) OS << ","; OS << (isDef() ? "imp-def" : "imp-use"); diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 5a1944fd5f9..d834031ae6b 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -173,9 +173,6 @@ namespace { void ComputeRelatedRegClasses(); - bool noEarlyClobberConflict(LiveInterval *cur, unsigned RegNo); - unsigned findPhysReg(MachineOperand &MO); - template void printIntervals(const char* const str, ItTy i, ItTy e) const { if (str) DOUT << str << " intervals:\n"; @@ -1007,90 +1004,6 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) unhandled_.push(added[i]); } -/// findPhysReg - get the physical register, if any, assigned to this operand. -/// This may be an original physical register, or the physical register which -/// has been assigned to a virtual register. -unsigned RALinScan::findPhysReg(MachineOperand &MO) { - unsigned PhysReg = MO.getReg(); - if (PhysReg && TargetRegisterInfo::isVirtualRegister(PhysReg)) { - if (!vrm_->hasPhys(PhysReg)) - return 0; - PhysReg = vrm_->getPhys(PhysReg); - } - return PhysReg; -} - -/// 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.isEarlyClobber()) { - unsigned PhysReg = findPhysReg(MO); - if (HReg==PhysReg) { - 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()) { - if ((MO.overlapsEarlyClobber() || MO.isEarlyClobber())) { - unsigned PhysReg = findPhysReg(MO); - if (HReg==PhysReg) - 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) { @@ -1122,12 +1035,10 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) { unsigned FreeRegInactiveCount = 0; // If copy coalescer has assigned a "preferred" register, check if it's - // available first. Coalescer can create new earlyclobber interferences, - // so we need to check that. + // available first. if (cur->preference) { if (prt_->isRegAvail(cur->preference) && - RC->contains(cur->preference) && - noEarlyClobberConflict(cur, cur->preference)) { + RC->contains(cur->preference)) { DOUT << "\t\tassigned the preferred register: " << tri_->getName(cur->preference) << "\n"; return cur->preference; @@ -1141,8 +1052,7 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) { TargetRegisterClass::iterator E = RC->allocation_order_end(*mf_); assert(I != E && "No allocatable register in this register class!"); for (; I != E; ++I) - if (prt_->isRegAvail(*I) && - noEarlyClobberConflict(cur, *I)) { + if (prt_->isRegAvail(*I)) { FreeReg = *I; if (FreeReg < inactiveCounts.size()) FreeRegInactiveCount = inactiveCounts[FreeReg]; @@ -1162,8 +1072,7 @@ unsigned RALinScan::getFreePhysReg(LiveInterval *cur) { for (; I != E; ++I) { unsigned Reg = *I; if (prt_->isRegAvail(Reg) && Reg < inactiveCounts.size() && - FreeRegInactiveCount < inactiveCounts[Reg] && - noEarlyClobberConflict(cur, *I)) { + FreeRegInactiveCount < inactiveCounts[Reg]) { FreeReg = Reg; FreeRegInactiveCount = inactiveCounts[Reg]; if (FreeRegInactiveCount == MaxInactiveCount) diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp index d929aaff7b8..4ea29063ab5 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGEmit.cpp @@ -231,8 +231,7 @@ unsigned ScheduleDAG::getVR(SDValue Op, void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, const TargetInstrDesc *II, - DenseMap &VRBaseMap, - bool overlapsEarlyClobber) { + DenseMap &VRBaseMap) { if (Op.isMachineOpcode()) { // Note that this case is redundant with the final else block, but we // include it because it is the most common and it makes the logic @@ -245,9 +244,7 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, const TargetInstrDesc &TID = MI->getDesc(); bool isOptDef = IIOpNum < TID.getNumOperands() && TID.OpInfo[IIOpNum].isOptionalDef(); - MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef, false, false, - false, 0, false, - overlapsEarlyClobber)); + MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef)); // Verify that it is right. assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Not a vreg?"); @@ -281,9 +278,7 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, const ConstantFP *CFP = F->getConstantFPValue(); MI->addOperand(MachineOperand::CreateFPImm(CFP)); } else if (RegisterSDNode *R = dyn_cast(Op)) { - MI->addOperand(MachineOperand::CreateReg(R->getReg(), false, false, - false, false, 0, false, - overlapsEarlyClobber)); + MI->addOperand(MachineOperand::CreateReg(R->getReg(), false)); } else if (GlobalAddressSDNode *TGA = dyn_cast(Op)) { MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset())); } else if (BasicBlockSDNode *BB = dyn_cast(Op)) { @@ -319,9 +314,7 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDValue Op, Op.getValueType() != MVT::Flag && "Chain and flag operands should occur at end of operand list!"); unsigned VReg = getVR(Op, VRBaseMap); - MI->addOperand(MachineOperand::CreateReg(VReg, false, false, - false, false, 0, false, - overlapsEarlyClobber)); + MI->addOperand(MachineOperand::CreateReg(VReg, false)); // Verify that it is right. Note that the reg class of the physreg and the // vreg don't necessarily need to match, but the target copy insertion has @@ -603,7 +596,6 @@ void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, // Add all of the operand registers to the instruction. for (unsigned i = 2; i != NumOps;) { - bool overlapsEarlyClobber = false; unsigned Flags = cast(Node->getOperand(i))->getZExtValue(); unsigned NumVals = Flags >> 3; @@ -626,18 +618,13 @@ void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, false, 0, true)); } break; - case 7: // Addressing mode overlapping earlyclobber. - case 5: // Use of register overlapping earlyclobber. - overlapsEarlyClobber = true; - // fall through case 1: // Use of register. case 3: // Immediate. case 4: // Addressing mode. // The addressing mode has been selected, just add all of the // operands to the machine instruction. for (; NumVals; --NumVals, ++i) - AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap, - overlapsEarlyClobber); + AddOperand(MI, Node->getOperand(i), 0, 0, VRBaseMap); break; } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 9768021b196..43ca2364d59 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4554,7 +4554,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo, bool HasEarlyClobber, // If this is an early clobber or tied register, our regalloc doesn't know // how to maintain the constraint. If it isn't, go ahead and create vreg // and let the regalloc do the right thing. - if (!OpInfo.hasMatchingInput && !OpInfo.isEarlyClobber && + if (!OpInfo.hasMatchingInput && !OpInfo.isEarlyClobber && // If there is some other early clobber and this is an input register, // then we are forced to pre-allocate the input reg so it doesn't // conflict with the earlyclobber. @@ -4843,10 +4843,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { assert(OpInfo.isIndirect && "Memory output must be indirect operand"); // Add information to the INLINEASM node to know about this output. - unsigned ResOpType = SawEarlyClobber ? - 7 /* MEM OVERLAPS EARLYCLOBBER */ : - 4/*MEM*/; - AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType | (1<<3), + unsigned ResOpType = 4/*MEM*/ | (1<<3); + AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, TLI.getPointerTy())); AsmNodeOperands.push_back(OpInfo.CallOperand); break; @@ -4899,8 +4897,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { cast(AsmNodeOperands[CurOp])->getZExtValue(); assert(((NumOps & 7) == 2 /*REGDEF*/ || (NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ || - (NumOps & 7) == 4 /*MEM*/ || - (NumOps & 7) == 7 /*MEM OVERLAPS EARLYCLOBBER*/) && + (NumOps & 7) == 4 /*MEM*/) && "Skipped past definitions?"); CurOp += (NumOps>>3)+1; } @@ -4922,14 +4919,10 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // Use the produced MatchedRegs object to MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag); - MatchedRegs.AddInlineAsmOperands(SawEarlyClobber ? - 1 /*REGUSE*/ : - 5 /*REGUSE OVERLAPS EARLYCLOBBER*/, - DAG, AsmNodeOperands); + MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands); break; } else { - assert(((NumOps & 7) == 7/*MEM OVERLAPS EARLYCLOBBER */ || - (NumOps & 7) == 4) && "Unknown matching constraint!"); + assert(((NumOps & 7) == 4) && "Unknown matching constraint!"); assert((NumOps >> 3) == 1 && "Unexpected number of operands"); // Add information to the INLINEASM node to know about this input. AsmNodeOperands.push_back(DAG.getTargetConstant(NumOps, @@ -4964,10 +4957,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { "Memory operands expect pointer values"); // Add information to the INLINEASM node to know about this input. - unsigned ResOpType = SawEarlyClobber ? - 7 /* MEM OVERLAPS EARLYCLOBBER */ : - 4/*MEM*/; - AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType | (1<<3), + unsigned ResOpType = 4/*MEM*/ | (1<<3); + AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, TLI.getPointerTy())); AsmNodeOperands.push_back(InOperandVal); break; @@ -4985,10 +4976,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag); - OpInfo.AssignedRegs.AddInlineAsmOperands(SawEarlyClobber ? - 5 /*REGUSE OVERLAPS EARLYCLOBBER*/: - 1/*REGUSE*/, - DAG, AsmNodeOperands); + OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, + DAG, AsmNodeOperands); break; } case InlineAsm::isClobber: { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index a91cb1fe933..afb290d822c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1115,8 +1115,7 @@ SelectInlineAsmMemoryOperands(std::vector &Ops) { while (i != e) { unsigned Flags = cast(InOps[i])->getZExtValue(); - if ((Flags & 7) != 4 /*MEM*/ && - (Flags & 7) != 7 /*MEM OVERLAPS EARLYCLOBBER*/) { + if ((Flags & 7) != 4 /*MEM*/) { // Just skip over this operand, copying the operands verbatim. Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1); i += (Flags >> 3) + 1; @@ -1131,7 +1130,7 @@ SelectInlineAsmMemoryOperands(std::vector &Ops) { // Add this to the output node. MVT IntPtrTy = CurDAG->getTargetLoweringInfo().getPointerTy(); - Ops.push_back(CurDAG->getTargetConstant((Flags & 7) | (SelOps.size()<< 3), + Ops.push_back(CurDAG->getTargetConstant(4/*MEM*/ | (SelOps.size()<< 3), IntPtrTy)); Ops.insert(Ops.end(), SelOps.begin(), SelOps.end()); i += 2; diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 05e0505f0ba..bdc37b16b6a 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1206,14 +1206,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { DOUT << " and "; DstInt.print(DOUT, tri_); DOUT << ": "; - // If one interval is earlyclobber and the other is overlaps-earlyclobber, - // we cannot coalesce them. - if ((SrcInt.isEarlyClobber && DstInt.overlapsEarlyClobber) || - (DstInt.isEarlyClobber && SrcInt.overlapsEarlyClobber)) { - DOUT << "\t\tCannot join due to earlyclobber."; - return false; - } - // Check if it is necessary to propagate "isDead" property. if (!isExtSubReg && !isInsSubReg) { MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false); @@ -1374,10 +1366,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { if (TargetRegisterInfo::isVirtualRegister(DstReg)) RemoveUnnecessaryKills(DstReg, *ResDstInt); - // Merge the earlyclobber bits. - ResDstInt->isEarlyClobber |= ResSrcInt->isEarlyClobber; - ResDstInt->overlapsEarlyClobber |= ResSrcInt->overlapsEarlyClobber; - if (isInsSubReg) // Avoid: // r1024 = op