From f7da4e939f02678cbe56cae666506da3b1a5e100 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Oct 2006 07:20:20 +0000 Subject: [PATCH] Fix for PR929. The PHI nodes were being gone through for each instruction in a successor block for every block...resulting in some O(N^k) algorithm which wasn't very good for performance. Calculating this information up front and keeping it in a map made it much faster. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30697 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveVariables.h | 12 +++++++- lib/CodeGen/LiveVariables.cpp | 45 +++++++++++++++------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index a61eca89c15..95114c0b705 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -39,7 +39,7 @@ class MRegisterInfo; class LiveVariables : public MachineFunctionPass { public: /// VarInfo - This represents the regions where a virtual register is live in - /// the program. We represent this with three difference pieces of + /// the program. We represent this with three different pieces of /// information: the instruction that uniquely defines the value, the set of /// blocks the instruction is live into and live out of, and the set of /// non-phi instructions that are the last users of the value. @@ -136,9 +136,19 @@ private: // Intermediate data structures MachineInstr **PhysRegInfo; bool *PhysRegUsed; + typedef std::map > PHIVarInfoMap; + + PHIVarInfoMap PHIVarInfo; + void HandlePhysRegUse(unsigned Reg, MachineInstr *MI); void HandlePhysRegDef(unsigned Reg, MachineInstr *MI); + /// analyzePHINodes - Gather information about the PHI nodes in here. In + /// particular, we want to map the variable information of a virtual + /// register which is used in a PHI node. We map that to the BB the vreg + /// is coming from. + void analyzePHINodes(const MachineFunction& Fn); public: virtual bool runOnMachineFunction(MachineFunction &MF); diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index ddb6ded372d..5a73131b3e4 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/lib/CodeGen/LiveVariables.cpp @@ -92,7 +92,6 @@ bool LiveVariables::RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const { return std::binary_search(I->second.begin(), I->second.end(), Reg); } - void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *MBB) { unsigned BBNum = MBB->getNumber(); @@ -212,6 +211,8 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) { HandlePhysRegDef(I->first, 0); } + analyzePHINodes(MF); + // Calculate live variable information in depth first order on the CFG of the // function. This guarantees that we will see the definition of a virtual // register before its uses due to dominance properties of SSA (except for PHI @@ -288,26 +289,16 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) { // bottom of this basic block. We check all of our successor blocks to see // if they have PHI nodes, and if so, we simulate an assignment at the end // of the current block. - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - E = MBB->succ_end(); SI != E; ++SI) { - MachineBasicBlock *Succ = *SI; + if (!PHIVarInfo[MBB].empty()) { + std::vector& VarInfoVec = PHIVarInfo[MBB]; - // PHI nodes are guaranteed to be at the top of the block... - for (MachineBasicBlock::iterator MI = Succ->begin(), ME = Succ->end(); - MI != ME && MI->getOpcode() == TargetInstrInfo::PHI; ++MI) { - for (unsigned i = 1; ; i += 2) { - assert(MI->getNumOperands() > i+1 && - "Didn't find an entry for our predecessor??"); - if (MI->getOperand(i+1).getMachineBasicBlock() == MBB) { - MachineOperand &MO = MI->getOperand(i); - VarInfo &VRInfo = getVarInfo(MO.getReg()); - assert(VRInfo.DefInst && "Register use before def (or no def)!"); + for (std::vector::iterator I = VarInfoVec.begin(), + E = VarInfoVec.end(); I != E; ++I) { + VarInfo& VRInfo = getVarInfo(*I); + assert(VRInfo.DefInst && "Register use before def (or no def)!"); - // Only mark it alive only in the block we are representing. - MarkVirtRegAliveInBlock(VRInfo, MBB); - break; // Found the PHI entry for this block. - } - } + // Only mark it alive only in the block we are representing. + MarkVirtRegAliveInBlock(VRInfo, MBB); } } @@ -362,6 +353,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &MF) { assert(Visited.count(&*i) != 0 && "unreachable basic block found"); #endif + PHIVarInfo.clear(); return false; } @@ -450,4 +442,17 @@ void LiveVariables::removeVirtualRegistersDead(MachineInstr *MI) { RegistersDead.erase(I); } - +/// analyzePHINodes - Gather information about the PHI nodes in here. In +/// particular, we want to map the variable information of a virtual +/// register which is used in a PHI node. We map that to the BB the vreg is +/// coming from. +/// +void LiveVariables::analyzePHINodes(const MachineFunction& Fn) { + for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end(); + I != E; ++I) + for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end(); + BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) + for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) + PHIVarInfo[BBI->getOperand(i + 1).getMachineBasicBlock()]. + push_back(BBI->getOperand(i).getReg()); +}