| Lang Hames | fae02a2 | 2009-07-21 23:47:33 +0000 | [diff] [blame] | 1 | //===-- lib/CodeGen/PHIElimination.h ----------------------------*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 |  | 
|  | 10 | #ifndef LLVM_CODEGEN_PHIELIMINATION_HPP | 
|  | 11 | #define LLVM_CODEGEN_PHIELIMINATION_HPP | 
|  | 12 |  | 
| Lang Hames | 287b8b0 | 2009-07-23 04:34:03 +0000 | [diff] [blame] | 13 | #include "llvm/ADT/DenseMap.h" | 
|  | 14 | #include "llvm/ADT/SmallSet.h" | 
| Lang Hames | fae02a2 | 2009-07-21 23:47:33 +0000 | [diff] [blame] | 15 | #include "llvm/ADT/SmallPtrSet.h" | 
|  | 16 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
|  | 17 | #include "llvm/Target/TargetInstrInfo.h" | 
|  | 18 |  | 
|  | 19 | #include <map> | 
|  | 20 |  | 
|  | 21 | namespace llvm { | 
|  | 22 |  | 
|  | 23 | /// Lower PHI instructions to copies. | 
|  | 24 | class PHIElimination : public MachineFunctionPass { | 
|  | 25 | MachineRegisterInfo  *MRI; // Machine register information | 
| Lang Hames | 287b8b0 | 2009-07-23 04:34:03 +0000 | [diff] [blame] | 26 | private: | 
|  | 27 |  | 
|  | 28 | typedef SmallSet<MachineBasicBlock*, 4> PHIKillList; | 
|  | 29 | typedef DenseMap<unsigned, PHIKillList> PHIKillMap; | 
|  | 30 | typedef DenseMap<unsigned, MachineBasicBlock*> PHIDefMap; | 
| Lang Hames | fae02a2 | 2009-07-21 23:47:33 +0000 | [diff] [blame] | 31 |  | 
|  | 32 | public: | 
| Lang Hames | 287b8b0 | 2009-07-23 04:34:03 +0000 | [diff] [blame] | 33 |  | 
|  | 34 | typedef PHIKillList::iterator phi_kill_iterator; | 
|  | 35 | typedef PHIKillList::const_iterator const_phi_kill_iterator; | 
|  | 36 |  | 
| Lang Hames | fae02a2 | 2009-07-21 23:47:33 +0000 | [diff] [blame] | 37 | static char ID; // Pass identification, replacement for typeid | 
|  | 38 | PHIElimination() : MachineFunctionPass(&ID) {} | 
|  | 39 |  | 
|  | 40 | virtual bool runOnMachineFunction(MachineFunction &Fn); | 
|  | 41 |  | 
|  | 42 | virtual void getAnalysisUsage(AnalysisUsage &AU) const; | 
|  | 43 |  | 
| Lang Hames | 287b8b0 | 2009-07-23 04:34:03 +0000 | [diff] [blame] | 44 | /// Return true if the given vreg was defined by a PHI intsr prior to | 
|  | 45 | /// lowering. | 
|  | 46 | bool hasPHIDef(unsigned vreg) const { | 
|  | 47 | return PHIDefs.count(vreg); | 
|  | 48 | } | 
|  | 49 |  | 
|  | 50 | /// Returns the block in which the PHI instruction which defined the | 
|  | 51 | /// given vreg used to reside. | 
|  | 52 | MachineBasicBlock* getPHIDefBlock(unsigned vreg) { | 
|  | 53 | PHIDefMap::iterator phiDefItr = PHIDefs.find(vreg); | 
|  | 54 | assert(phiDefItr != PHIDefs.end() && "vreg has no phi-def."); | 
|  | 55 | return phiDefItr->second; | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | /// Returns true if the given vreg was killed by a PHI instr. | 
|  | 59 | bool hasPHIKills(unsigned vreg) const { | 
|  | 60 | return PHIKills.count(vreg); | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | /// Returns an iterator over the BasicBlocks which contained PHI | 
|  | 64 | /// kills of this register prior to lowering. | 
|  | 65 | phi_kill_iterator phiKillsBegin(unsigned vreg) { | 
|  | 66 | PHIKillMap::iterator phiKillItr = PHIKills.find(vreg); | 
|  | 67 | assert(phiKillItr != PHIKills.end() && "vreg has no phi-kills."); | 
|  | 68 | return phiKillItr->second.begin(); | 
|  | 69 | } | 
|  | 70 | phi_kill_iterator phiKillsEnd(unsigned vreg) { | 
|  | 71 | PHIKillMap::iterator phiKillItr = PHIKills.find(vreg); | 
|  | 72 | assert(phiKillItr != PHIKills.end() && "vreg has no phi-kills."); | 
|  | 73 | return phiKillItr->second.end(); | 
|  | 74 | } | 
|  | 75 |  | 
| Lang Hames | fae02a2 | 2009-07-21 23:47:33 +0000 | [diff] [blame] | 76 | private: | 
|  | 77 | /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions | 
|  | 78 | /// in predecessor basic blocks. | 
|  | 79 | /// | 
|  | 80 | bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB); | 
|  | 81 | void LowerAtomicPHINode(MachineBasicBlock &MBB, | 
|  | 82 | MachineBasicBlock::iterator AfterPHIsIt); | 
|  | 83 |  | 
|  | 84 | /// analyzePHINodes - Gather information about the PHI nodes in | 
|  | 85 | /// here. In particular, we want to map the number of uses of a virtual | 
|  | 86 | /// register which is used in a PHI node. We map that to the BB the | 
|  | 87 | /// vreg is coming from. This is used later to determine when the vreg | 
|  | 88 | /// is killed in the BB. | 
|  | 89 | /// | 
|  | 90 | void analyzePHINodes(const MachineFunction& Fn); | 
|  | 91 |  | 
|  | 92 | // FindCopyInsertPoint - Find a safe place in MBB to insert a copy from | 
|  | 93 | // SrcReg.  This needs to be after any def or uses of SrcReg, but before | 
|  | 94 | // any subsequent point where control flow might jump out of the basic | 
|  | 95 | // block. | 
|  | 96 | MachineBasicBlock::iterator FindCopyInsertPoint(MachineBasicBlock &MBB, | 
|  | 97 | unsigned SrcReg); | 
|  | 98 |  | 
|  | 99 | // SkipPHIsAndLabels - Copies need to be inserted after phi nodes and | 
|  | 100 | // also after any exception handling labels: in landing pads execution | 
|  | 101 | // starts at the label, so any copies placed before it won't be executed! | 
|  | 102 | MachineBasicBlock::iterator SkipPHIsAndLabels(MachineBasicBlock &MBB, | 
|  | 103 | MachineBasicBlock::iterator I) { | 
|  | 104 | // Rather than assuming that EH labels come before other kinds of labels, | 
|  | 105 | // just skip all labels. | 
|  | 106 | while (I != MBB.end() && | 
|  | 107 | (I->getOpcode() == TargetInstrInfo::PHI || I->isLabel())) | 
|  | 108 | ++I; | 
|  | 109 | return I; | 
|  | 110 | } | 
|  | 111 |  | 
|  | 112 | typedef std::pair<const MachineBasicBlock*, unsigned> BBVRegPair; | 
|  | 113 | typedef std::map<BBVRegPair, unsigned> VRegPHIUse; | 
|  | 114 |  | 
|  | 115 | VRegPHIUse VRegPHIUseCount; | 
| Lang Hames | 287b8b0 | 2009-07-23 04:34:03 +0000 | [diff] [blame] | 116 | PHIDefMap PHIDefs; | 
|  | 117 | PHIKillMap PHIKills; | 
| Lang Hames | fae02a2 | 2009-07-21 23:47:33 +0000 | [diff] [blame] | 118 |  | 
|  | 119 | // Defs of PHI sources which are implicit_def. | 
|  | 120 | SmallPtrSet<MachineInstr*, 4> ImpDefs; | 
|  | 121 | }; | 
|  | 122 |  | 
|  | 123 | } | 
|  | 124 |  | 
| Evan Cheng | e939091 | 2009-09-04 07:46:30 +0000 | [diff] [blame^] | 125 | #endif /* LLVM_CODEGEN_PHIELIMINATION_HPP */ |