From: Evan Cheng Date: Wed, 2 Apr 2008 18:04:08 +0000 (+0000) Subject: Now that I am told MachineRegisterInfo also tracks physical register uses / defs... X-Git-Tag: android-x86-6.0-r1~1003^2~29148 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ea1d9cdc4e4f4e4570acddb7c4a63f703b110dad;p=android-x86%2Fexternal-llvm.git Now that I am told MachineRegisterInfo also tracks physical register uses / defs, I can do away with the horribleness I introduced a while back. It's impossible to detect if there is any use of a physical register below an instruction (and before any def of the register) with some cheap book keeping. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49105 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index 1e49babe697..49fc90f00e5 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -31,11 +31,13 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" namespace llvm { +class MachineRegisterInfo; class TargetRegisterInfo; class LiveVariables : public MachineFunctionPass { @@ -128,6 +130,8 @@ private: private: // Intermediate data structures MachineFunction *MF; + MachineRegisterInfo* MRI; + const TargetRegisterInfo *TRI; // PhysRegInfo - Keep track of which instruction was the last def/use of a @@ -152,6 +156,10 @@ private: // Intermediate data structures SmallVector *PHIVarInfo; + // DistanceMap - Keep track the distance of a MI from the start of the + // current basic block. + DenseMap DistanceMap; + void addRegisterKills(unsigned Reg, MachineInstr *MI, SmallSet &SubKills); diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index 35461ef7db4..101d1e866d6 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/lib/CodeGen/LiveVariables.cpp @@ -118,8 +118,7 @@ void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo, void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB, MachineInstr *MI) { - const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); - assert(MRI.getVRegDef(reg) && "Register use before def!"); + assert(MRI->getVRegDef(reg) && "Register use before def!"); unsigned BBNum = MBB->getNumber(); @@ -140,7 +139,7 @@ void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB, assert(VRInfo.Kills[i]->getParent() != MBB && "entry should be at end!"); #endif - assert(MBB != MRI.getVRegDef(reg)->getParent() && + assert(MBB != MRI->getVRegDef(reg)->getParent() && "Should have kill for defblock!"); // Add a new kill entry for this basic block. If this virtual register is @@ -152,7 +151,7 @@ void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB, // Update all dominating blocks to mark them as "known live". for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), E = MBB->pred_end(); PI != E; ++PI) - MarkVirtRegAliveInBlock(VRInfo, MRI.getVRegDef(reg)->getParent(), *PI); + MarkVirtRegAliveInBlock(VRInfo, MRI->getVRegDef(reg)->getParent(), *PI); } /// HandlePhysRegUse - Turn previous partial def's into read/mod/writes. Add @@ -305,25 +304,63 @@ bool LiveVariables::hasRegisterUseBelow(unsigned Reg, MachineBasicBlock *MBB) { if (I == MBB->end()) return false; - ++I; - // FIXME: This is slow. We probably need a smarter solution. Possibilities: - // 1. Scan all instructions once and build def / use information of physical - // registers. We also need a fast way to compare relative ordering of - // instructions. - // 2. Cache information so this function only has to scan instructions that - // read / def physical instructions. - for (MachineBasicBlock::iterator E = MBB->end(); I != E; ++I) { - MachineInstr *MI = I; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (!MO.isRegister() || MO.getReg() != Reg) - continue; - if (MO.isDef()) - return false; - return true; + + // First find out if there are any uses / defs below. + bool hasDistInfo = true; + unsigned CurDist = DistanceMap[I]; + SmallVector Uses; + SmallVector Defs; + for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(Reg), + RE = MRI->reg_end(); RI != RE; ++RI) { + MachineOperand &UDO = RI.getOperand(); + MachineInstr *UDMI = &*RI; + if (UDMI->getParent() != MBB) + continue; + DenseMap::iterator DI = DistanceMap.find(UDMI); + bool isBelow = false; + if (DI == DistanceMap.end()) { + // Must be below if it hasn't been assigned a distance yet. + isBelow = true; + hasDistInfo = false; + } else if (DI->second > CurDist) + isBelow = true; + if (isBelow) { + if (UDO.isUse()) + Uses.push_back(UDMI); + if (UDO.isDef()) + Defs.push_back(UDMI); } } - return false; + + if (Uses.empty()) + // No uses below. + return false; + else if (!Uses.empty() && Defs.empty()) + // There are uses below but no defs below. + return true; + // There are both uses and defs below. We need to know which comes first. + if (!hasDistInfo) { + // Complete DistanceMap for this MBB. This information is computed only + // once per MBB. + ++I; + ++CurDist; + for (MachineBasicBlock::iterator E = MBB->end(); I != E; ++I, ++CurDist) + DistanceMap.insert(std::make_pair(I, CurDist)); + } + + unsigned EarliestUse = CurDist; + for (unsigned i = 0, e = Uses.size(); i != e; ++i) { + unsigned Dist = DistanceMap[Uses[i]]; + if (Dist < EarliestUse) + EarliestUse = Dist; + } + for (unsigned i = 0, e = Defs.size(); i != e; ++i) { + unsigned Dist = DistanceMap[Defs[i]]; + if (Dist < EarliestUse) + // The register is defined before its first use below. + return false; + } + return true; } void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) { @@ -408,8 +445,8 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) { bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { MF = &mf; + MRI = &mf.getRegInfo(); TRI = MF->getTarget().getRegisterInfo(); - MachineRegisterInfo& MRI = mf.getRegInfo(); ReservedRegisters = TRI->getReservedRegs(mf); @@ -449,9 +486,12 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { } // Loop over all of the instructions, processing them. + DistanceMap.clear(); + unsigned Dist = 0; for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; ++I) { MachineInstr *MI = I; + DistanceMap.insert(std::make_pair(MI, Dist++)); // Process all of the operands of the instruction... unsigned NumOperandsToProcess = MI->getNumOperands(); @@ -507,7 +547,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { for (SmallVector::iterator I = VarInfoVec.begin(), E = VarInfoVec.end(); I != E; ++I) // Mark it alive only in the block we are representing. - MarkVirtRegAliveInBlock(getVarInfo(*I), MRI.getVRegDef(*I)->getParent(), + MarkVirtRegAliveInBlock(getVarInfo(*I),MRI->getVRegDef(*I)->getParent(), MBB); } @@ -549,7 +589,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) { for (unsigned i = 0, e1 = VirtRegInfo.size(); i != e1; ++i) for (unsigned j = 0, e2 = VirtRegInfo[i].Kills.size(); j != e2; ++j) if (VirtRegInfo[i].Kills[j] == - MRI.getVRegDef(i + TargetRegisterInfo::FirstVirtualRegister)) + MRI->getVRegDef(i + TargetRegisterInfo::FirstVirtualRegister)) VirtRegInfo[i] .Kills[j]->addRegisterDead(i + TargetRegisterInfo::FirstVirtualRegister,