diff options
author | ed <ed@FreeBSD.org> | 2009-07-04 13:58:26 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-07-04 13:58:26 +0000 |
commit | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (patch) | |
tree | 84360c8989c912127a383af37c4b1aa5767bd16e /lib/CodeGen/VirtRegRewriter.cpp | |
parent | cf5cd875b51255602afaed29deb636b66b295671 (diff) | |
download | FreeBSD-src-72621d11de5b873f1695f391eb95f0b336c3d2d4.zip FreeBSD-src-72621d11de5b873f1695f391eb95f0b336c3d2d4.tar.gz |
Import LLVM 74788.
Diffstat (limited to 'lib/CodeGen/VirtRegRewriter.cpp')
-rw-r--r-- | lib/CodeGen/VirtRegRewriter.cpp | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index bd6584a..be0b016 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -356,7 +356,7 @@ static void InvalidateKills(MachineInstr &MI, SmallVector<unsigned, 2> *KillRegs = NULL) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); - if (!MO.isReg() || !MO.isUse() || !MO.isKill()) + if (!MO.isReg() || !MO.isUse() || !MO.isKill() || MO.isUndef()) continue; unsigned Reg = MO.getReg(); if (TargetRegisterInfo::isVirtualRegister(Reg)) @@ -390,12 +390,12 @@ static bool InvalidateRegDef(MachineBasicBlock::iterator I, MachineOperand *DefOp = NULL; for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) { MachineOperand &MO = DefMI->getOperand(i); - if (MO.isReg() && MO.isDef()) { - if (MO.getReg() == Reg) - DefOp = &MO; - else if (!MO.isDead()) - HasLiveDef = true; - } + if (!MO.isReg() || !MO.isUse() || !MO.isKill() || MO.isUndef()) + continue; + if (MO.getReg() == Reg) + DefOp = &MO; + else if (!MO.isDead()) + HasLiveDef = true; } if (!DefOp) return false; @@ -430,7 +430,7 @@ static void UpdateKills(MachineInstr &MI, const TargetRegisterInfo* TRI, std::vector<MachineOperand*> &KillOps) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); - if (!MO.isReg() || !MO.isUse()) + if (!MO.isReg() || !MO.isUse() || MO.isUndef()) continue; unsigned Reg = MO.getReg(); if (Reg == 0) @@ -1289,8 +1289,7 @@ private: if (InvalidateRegDef(PrevMII, *MII, KillRegs[j], HasOtherDef)) { MachineInstr *DeadDef = PrevMII; if (ReMatDefs.count(DeadDef) && !HasOtherDef) { - // FIXME: This assumes a remat def does not have side - // effects. + // FIXME: This assumes a remat def does not have side effects. VRM.RemoveMachineInstrFromMaps(DeadDef); MBB.erase(DeadDef); ++NumDRM; @@ -1569,6 +1568,8 @@ private: if (MO.isImplicit()) // If the virtual register is implicitly defined, emit a implicit_def // before so scavenger knows it's "defined". + // FIXME: This is a horrible hack done the by register allocator to + // remat a definition with virtual register operand. VirtUseOps.insert(VirtUseOps.begin(), i); else VirtUseOps.push_back(i); @@ -1595,6 +1596,7 @@ private: MI.getOperand(i).setReg(RReg); MI.getOperand(i).setSubReg(0); if (VRM.isImplicitlyDefined(VirtReg)) + // FIXME: Is this needed? BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg); continue; @@ -1604,22 +1606,16 @@ private: if (!MO.isUse()) continue; // Handle defs in the loop below (handle use&def here though) - bool AvoidReload = false; - if (LIs->hasInterval(VirtReg)) { - LiveInterval &LI = LIs->getInterval(VirtReg); - if (!LI.liveAt(LIs->getUseIndex(LI.beginNumber()))) - // Must be defined by an implicit def. It should not be spilled. Note, - // this is for correctness reason. e.g. - // 8 %reg1024<def> = IMPLICIT_DEF - // 12 %reg1024<def> = INSERT_SUBREG %reg1024<kill>, %reg1025, 2 - // The live range [12, 14) are not part of the r1024 live interval since - // it's defined by an implicit def. It will not conflicts with live - // interval of r1025. Now suppose both registers are spilled, you can - // easily see a situation where both registers are reloaded before - // the INSERT_SUBREG and both target registers that would overlap. - AvoidReload = true; - } - + bool AvoidReload = MO.isUndef(); + // Check if it is defined by an implicit def. It should not be spilled. + // Note, this is for correctness reason. e.g. + // 8 %reg1024<def> = IMPLICIT_DEF + // 12 %reg1024<def> = INSERT_SUBREG %reg1024<kill>, %reg1025, 2 + // The live range [12, 14) are not part of the r1024 live interval since + // it's defined by an implicit def. It will not conflicts with live + // interval of r1025. Now suppose both registers are spilled, you can + // easily see a situation where both registers are reloaded before + // the INSERT_SUBREG and both target registers that would overlap. bool DoReMat = VRM.isReMaterialized(VirtReg); int SSorRMId = DoReMat ? VRM.getReMatId(VirtReg) : VRM.getStackSlot(VirtReg); @@ -2033,8 +2029,12 @@ private: if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) { // Check to see if this is a noop copy. If so, eliminate the // instruction before considering the dest reg to be changed. + // Also check if it's copying from an "undef", if so, we can't + // eliminate this or else the undef marker is lost and it will + // confuses the scavenger. This is extremely rare. unsigned Src, Dst, SrcSR, DstSR; - if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) { + if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst && + !MI.findRegisterUseOperand(Src)->isUndef()) { ++NumDCE; DOUT << "Removing now-noop copy: " << MI; SmallVector<unsigned, 2> KillRegs; @@ -2053,7 +2053,7 @@ private: Spills.disallowClobberPhysReg(VirtReg); goto ProcessNextInst; } - + // If it's not a no-op copy, it clobbers the value in the destreg. Spills.ClobberPhysReg(VirtReg); ReusedOperands.markClobbered(VirtReg); |