From a3c4ca9c7ba4bb98eb1c240726c8f4fb7e60f1c7 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 20 Jan 2012 22:27:12 +0000 Subject: Support register masks in MachineLICM. Only PostRA LICM is affected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148589 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineLICM.cpp | 59 +++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 23 deletions(-) (limited to 'lib/CodeGen/MachineLICM.cpp') diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 77ea4f37f8..30c93f8452 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -163,7 +163,9 @@ namespace { /// ProcessMI - Examine the instruction for potentai LICM candidate. Also /// gather register def and frame object update information. - void ProcessMI(MachineInstr *MI, unsigned *PhysRegDefs, + void ProcessMI(MachineInstr *MI, + BitVector &PhysRegDefs, + BitVector &PhysRegClobbers, SmallSet &StoredFIs, SmallVector &Candidates); @@ -392,7 +394,8 @@ static bool InstructionStoresToFI(const MachineInstr *MI, int FI) { /// ProcessMI - Examine the instruction for potentai LICM candidate. Also /// gather register def and frame object update information. void MachineLICM::ProcessMI(MachineInstr *MI, - unsigned *PhysRegDefs, + BitVector &PhysRegDefs, + BitVector &PhysRegClobbers, SmallSet &StoredFIs, SmallVector &Candidates) { bool RuledOut = false; @@ -411,6 +414,16 @@ void MachineLICM::ProcessMI(MachineInstr *MI, continue; } + // We can't hoist an instruction defining a physreg that is clobbered in + // the loop. + if (MO.isRegMask()) { + if (const uint32_t *Mask = MO.getRegMask()) + PhysRegClobbers.setBitsNotInMask(Mask); + else + PhysRegClobbers.set(); + continue; + } + if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); @@ -420,7 +433,7 @@ void MachineLICM::ProcessMI(MachineInstr *MI, "Not expecting virtual register!"); if (!MO.isDef()) { - if (Reg && PhysRegDefs[Reg]) + if (Reg && (PhysRegDefs.test(Reg) || PhysRegClobbers.test(Reg))) // If it's using a non-loop-invariant register, then it's obviously not // safe to hoist. HasNonInvariantUse = true; @@ -428,9 +441,8 @@ void MachineLICM::ProcessMI(MachineInstr *MI, } if (MO.isImplicit()) { - ++PhysRegDefs[Reg]; - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) - ++PhysRegDefs[*AS]; + for (const unsigned *AS = TRI->getOverlaps(Reg); *AS; ++AS) + PhysRegClobbers.set(*AS); if (!MO.isDead()) // Non-dead implicit def? This cannot be hoisted. RuledOut = true; @@ -447,14 +459,17 @@ void MachineLICM::ProcessMI(MachineInstr *MI, Def = Reg; // If we have already seen another instruction that defines the same - // register, then this is not safe. - if (++PhysRegDefs[Reg] > 1) - // MI defined register is seen defined by another instruction in - // the loop, it cannot be a LICM candidate. - RuledOut = true; - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) - if (++PhysRegDefs[*AS] > 1) + // register, then this is not safe. Two defs is indicated by setting a + // PhysRegClobbers bit. + for (const unsigned *AS = TRI->getOverlaps(Reg); *AS; ++AS) { + if (PhysRegDefs.test(Reg)) + PhysRegClobbers.set(Reg); + if (PhysRegClobbers.test(Reg)) + // MI defined register is seen defined by another instruction in + // the loop, it cannot be a LICM candidate. RuledOut = true; + PhysRegDefs.set(Reg); + } } // Only consider reloads for now and remats which do not have register @@ -471,8 +486,8 @@ void MachineLICM::ProcessMI(MachineInstr *MI, /// invariants out to the preheader. void MachineLICM::HoistRegionPostRA() { unsigned NumRegs = TRI->getNumRegs(); - unsigned *PhysRegDefs = new unsigned[NumRegs]; - std::fill(PhysRegDefs, PhysRegDefs + NumRegs, 0); + BitVector PhysRegDefs(NumRegs); // Regs defined once in the loop. + BitVector PhysRegClobbers(NumRegs); // Regs defined more than once. SmallVector Candidates; SmallSet StoredFIs; @@ -494,16 +509,15 @@ void MachineLICM::HoistRegionPostRA() { for (MachineBasicBlock::livein_iterator I = BB->livein_begin(), E = BB->livein_end(); I != E; ++I) { unsigned Reg = *I; - ++PhysRegDefs[Reg]; - for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS) - ++PhysRegDefs[*AS]; + for (const unsigned *AS = TRI->getOverlaps(Reg); *AS; ++AS) + PhysRegDefs.set(*AS); } SpeculationState = SpeculateUnknown; for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ++MII) { MachineInstr *MI = &*MII; - ProcessMI(MI, PhysRegDefs, StoredFIs, Candidates); + ProcessMI(MI, PhysRegDefs, PhysRegClobbers, StoredFIs, Candidates); } } @@ -517,14 +531,15 @@ void MachineLICM::HoistRegionPostRA() { StoredFIs.count(Candidates[i].FI)) continue; - if (PhysRegDefs[Candidates[i].Def] == 1) { + if (!PhysRegClobbers.test(Candidates[i].Def)) { bool Safe = true; MachineInstr *MI = Candidates[i].MI; for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) { const MachineOperand &MO = MI->getOperand(j); if (!MO.isReg() || MO.isDef() || !MO.getReg()) continue; - if (PhysRegDefs[MO.getReg()]) { + if (PhysRegDefs.test(MO.getReg()) || + PhysRegClobbers.test(MO.getReg())) { // If it's using a non-loop-invariant register, then it's obviously // not safe to hoist. Safe = false; @@ -535,8 +550,6 @@ void MachineLICM::HoistRegionPostRA() { HoistPostRA(MI, Candidates[i].Def); } } - - delete[] PhysRegDefs; } /// AddToLiveIns - Add register 'Reg' to the livein sets of BBs in the current -- cgit v1.2.3