| //===-- lib/CodeGen/PHIElimination.h ----------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CODEGEN_PHIELIMINATION_HPP |
| #define LLVM_CODEGEN_PHIELIMINATION_HPP |
| |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/ADT/SmallSet.h" |
| #include "llvm/ADT/SmallPtrSet.h" |
| #include "llvm/CodeGen/MachineFunctionPass.h" |
| #include "llvm/CodeGen/MachineRegisterInfo.h" |
| |
| namespace llvm { |
| class LiveVariables; |
| |
| /// Lower PHI instructions to copies. |
| class PHIElimination : public MachineFunctionPass { |
| MachineRegisterInfo *MRI; // Machine register information |
| |
| public: |
| static char ID; // Pass identification, replacement for typeid |
| PHIElimination() : MachineFunctionPass(&ID) {} |
| |
| virtual bool runOnMachineFunction(MachineFunction &Fn); |
| |
| virtual void getAnalysisUsage(AnalysisUsage &AU) const; |
| |
| private: |
| /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions |
| /// in predecessor basic blocks. |
| /// |
| bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB); |
| void LowerAtomicPHINode(MachineBasicBlock &MBB, |
| MachineBasicBlock::iterator AfterPHIsIt); |
| |
| /// analyzePHINodes - Gather information about the PHI nodes in |
| /// here. In particular, we want to map the number of uses of a virtual |
| /// register which is used in a PHI node. We map that to the BB the |
| /// vreg is coming from. This is used later to determine when the vreg |
| /// is killed in the BB. |
| /// |
| void analyzePHINodes(const MachineFunction& Fn); |
| |
| /// Split critical edges where necessary for good coalescer performance. |
| bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB, |
| LiveVariables &LV); |
| |
| /// SplitCriticalEdge - Split a critical edge from A to B by |
| /// inserting a new MBB. Update branches in A and PHI instructions |
| /// in B. Return the new block. |
| MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *A, |
| MachineBasicBlock *B); |
| |
| /// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from |
| /// SrcReg when following the CFG edge to SuccMBB. This needs to be after |
| /// any def of SrcReg, but before any subsequent point where control flow |
| /// might jump out of the basic block. |
| MachineBasicBlock::iterator FindCopyInsertPoint(MachineBasicBlock &MBB, |
| MachineBasicBlock &SuccMBB, |
| unsigned SrcReg); |
| |
| // SkipPHIsAndLabels - Copies need to be inserted after phi nodes and |
| // also after any exception handling labels: in landing pads execution |
| // starts at the label, so any copies placed before it won't be executed! |
| // We also deal with DBG_VALUEs, which are a bit tricky: |
| // PHI |
| // DBG_VALUE |
| // LABEL |
| // Here the DBG_VALUE needs to be skipped, and if it refers to a PHI it |
| // needs to be annulled or, better, moved to follow the label, as well. |
| // PHI |
| // DBG_VALUE |
| // no label |
| // Here it is not a good idea to skip the DBG_VALUE. |
| // FIXME: For now we skip and annul all DBG_VALUEs, maximally simple and |
| // maximally stupid. |
| MachineBasicBlock::iterator SkipPHIsAndLabels(MachineBasicBlock &MBB, |
| MachineBasicBlock::iterator I) { |
| // Rather than assuming that EH labels come before other kinds of labels, |
| // just skip all labels. |
| while (I != MBB.end() && |
| (I->isPHI() || I->isLabel() || I->isDebugValue())) { |
| if (I->isDebugValue() && I->getNumOperands()==3 && |
| I->getOperand(0).isReg()) |
| I->getOperand(0).setReg(0U); |
| ++I; |
| } |
| return I; |
| } |
| |
| typedef std::pair<unsigned, unsigned> BBVRegPair; |
| typedef DenseMap<BBVRegPair, unsigned> VRegPHIUse; |
| |
| VRegPHIUse VRegPHIUseCount; |
| |
| // Defs of PHI sources which are implicit_def. |
| SmallPtrSet<MachineInstr*, 4> ImpDefs; |
| |
| // Map reusable lowered PHI node -> incoming join register. |
| typedef DenseMap<MachineInstr*, unsigned, |
| MachineInstrExpressionTrait> LoweredPHIMap; |
| LoweredPHIMap LoweredPHIs; |
| }; |
| |
| } |
| |
| #endif /* LLVM_CODEGEN_PHIELIMINATION_HPP */ |