From 7948290532c1b54cbad5a189d0728c0ed9d5095c Mon Sep 17 00:00:00 2001 From: Patrik Hagglund Date: Mon, 1 Sep 2014 11:04:07 +0000 Subject: [PATCH] Fix in InlineSpiller to make the rematerilization loop also consider implicit uses of the whole register when a sub register is defined. Now the same iterator is used in the rematerilization loop as in the spill loop later. Patch provided by Mikael Holmen. This fix was proposed and reviewed by Quentin Colombet, http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-August/076135.html. Unfortunately, this error in the rematerilization code has only been seen in a large test case for an out-of-tree target, and is probably hard to reproduce on an in-tree target. Therefore, no testcase is provided. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216873 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/InlineSpiller.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 28235b0f973..c868cab6c15 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -848,6 +848,15 @@ void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) { /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading. bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineBasicBlock::iterator MI) { + + // Analyze instruction + SmallVector, 8> Ops; + MIBundleOperands::VirtRegInfo RI = + MIBundleOperands(MI).analyzeVirtReg(VirtReg.reg, &Ops); + + if (!RI.Reads) + return false; + SlotIndex UseIdx = LIS.getInstructionIndex(MI).getRegSlot(true); VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx.getBaseIndex()); @@ -878,9 +887,6 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, // If the instruction also writes VirtReg.reg, it had better not require the // same register for uses and defs. - SmallVector, 8> Ops; - MIBundleOperands::VirtRegInfo RI = - MIBundleOperands(MI).analyzeVirtReg(VirtReg.reg, &Ops); if (RI.Tied) { markValueUsed(&VirtReg, ParentVNI); DEBUG(dbgs() << "\tcannot remat tied reg: " << UseIdx << '\t' << *MI); @@ -934,10 +940,15 @@ void InlineSpiller::reMaterializeAll() { for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) { unsigned Reg = RegsToSpill[i]; LiveInterval &LI = LIS.getInterval(Reg); - for (MachineRegisterInfo::use_bundle_nodbg_iterator - RI = MRI.use_bundle_nodbg_begin(Reg), E = MRI.use_bundle_nodbg_end(); - RI != E; ) { - MachineInstr *MI = &*(RI++); + for (MachineRegisterInfo::reg_bundle_iterator + RegI = MRI.reg_bundle_begin(Reg), E = MRI.reg_bundle_end(); + RegI != E; ) { + MachineInstr *MI = &*(RegI++); + + // Debug values are not allowed to affect codegen. + if (MI->isDebugValue()) + continue; + anyRemat |= reMaterializeFor(LI, MI); } }