blob: 023ace2d219cc6e23dfb9f9cff32f1555e5e636a [file] [log] [blame]
Evan Chengc6fe3332010-03-02 02:38:24 +00001//===-- MachineCSE.cpp - Machine Common Subexpression Elimination Pass ----===//
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// This pass performs global common subexpression elimination on machine
Evan Chengc5bbba12010-03-02 19:02:27 +000011// instructions using a scoped hash table based value numbering scheme. It
Evan Chengc6fe3332010-03-02 02:38:24 +000012// must be run while the machine function is still in SSA form.
13//
14//===----------------------------------------------------------------------===//
15
16#define DEBUG_TYPE "machine-cse"
17#include "llvm/CodeGen/Passes.h"
18#include "llvm/CodeGen/MachineDominators.h"
19#include "llvm/CodeGen/MachineInstr.h"
Evan Cheng6ba95542010-03-03 02:48:20 +000020#include "llvm/CodeGen/MachineRegisterInfo.h"
21#include "llvm/Target/TargetInstrInfo.h"
Evan Chengc6fe3332010-03-02 02:38:24 +000022#include "llvm/ADT/ScopedHashTable.h"
23#include "llvm/ADT/Statistic.h"
24#include "llvm/Support/Debug.h"
25
26using namespace llvm;
27
28namespace llvm {
29 template<> struct DenseMapInfo<MachineInstr*> {
30 static inline MachineInstr *getEmptyKey() {
31 return 0;
32 }
33
34 static inline MachineInstr *getTombstoneKey() {
35 return reinterpret_cast<MachineInstr*>(-1);
36 }
37
38 static unsigned getHashValue(const MachineInstr* const &MI) {
39 unsigned Hash = MI->getOpcode() * 37;
40 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
41 const MachineOperand &MO = MI->getOperand(i);
42 uint64_t Key = (uint64_t)MO.getType() << 32;
43 switch (MO.getType()) {
44 default: break;
45 case MachineOperand::MO_Register:
Evan Cheng6ba95542010-03-03 02:48:20 +000046 if (MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))
47 continue; // Skip virtual register defs.
Evan Chengc6fe3332010-03-02 02:38:24 +000048 Key |= MO.getReg();
49 break;
50 case MachineOperand::MO_Immediate:
51 Key |= MO.getImm();
52 break;
53 case MachineOperand::MO_FrameIndex:
54 case MachineOperand::MO_ConstantPoolIndex:
55 case MachineOperand::MO_JumpTableIndex:
56 Key |= MO.getIndex();
57 break;
58 case MachineOperand::MO_MachineBasicBlock:
59 Key |= DenseMapInfo<void*>::getHashValue(MO.getMBB());
60 break;
61 case MachineOperand::MO_GlobalAddress:
62 Key |= DenseMapInfo<void*>::getHashValue(MO.getGlobal());
63 break;
64 case MachineOperand::MO_BlockAddress:
65 Key |= DenseMapInfo<void*>::getHashValue(MO.getBlockAddress());
66 break;
67 }
68 Key += ~(Key << 32);
69 Key ^= (Key >> 22);
70 Key += ~(Key << 13);
71 Key ^= (Key >> 8);
72 Key += (Key << 3);
73 Key ^= (Key >> 15);
74 Key += ~(Key << 27);
75 Key ^= (Key >> 31);
76 Hash = (unsigned)Key + Hash * 37;
77 }
78 return Hash;
79 }
80
81 static bool isEqual(const MachineInstr* const &LHS,
82 const MachineInstr* const &RHS) {
Evan Cheng6ba95542010-03-03 02:48:20 +000083 if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
84 LHS == getEmptyKey() || LHS == getTombstoneKey())
85 return LHS == RHS;
86 return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs);
Evan Chengc6fe3332010-03-02 02:38:24 +000087 }
88 };
89} // end llvm namespace
90
91namespace {
92 class MachineCSE : public MachineFunctionPass {
Evan Cheng6ba95542010-03-03 02:48:20 +000093 const TargetInstrInfo *TII;
94 MachineRegisterInfo *MRI;
Evan Chengc6fe3332010-03-02 02:38:24 +000095 MachineDominatorTree *DT;
Evan Cheng6ba95542010-03-03 02:48:20 +000096 ScopedHashTable<MachineInstr*, unsigned> VNT;
97 unsigned CurrVN;
Evan Chengc6fe3332010-03-02 02:38:24 +000098 public:
99 static char ID; // Pass identification
Evan Cheng6ba95542010-03-03 02:48:20 +0000100 MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
Evan Chengc6fe3332010-03-02 02:38:24 +0000101
102 virtual bool runOnMachineFunction(MachineFunction &MF);
103
104 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
105 AU.setPreservesCFG();
106 MachineFunctionPass::getAnalysisUsage(AU);
107 AU.addRequired<MachineDominatorTree>();
108 AU.addPreserved<MachineDominatorTree>();
109 }
110
111 private:
Evan Cheng6ba95542010-03-03 02:48:20 +0000112 bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
Evan Chengc6fe3332010-03-02 02:38:24 +0000113 bool ProcessBlock(MachineDomTreeNode *Node);
114 };
115} // end anonymous namespace
116
117char MachineCSE::ID = 0;
118static RegisterPass<MachineCSE>
119X("machine-cse", "Machine Common Subexpression Elimination");
120
121FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
122
Evan Cheng6ba95542010-03-03 02:48:20 +0000123bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
124 MachineBasicBlock *MBB) {
125 bool Changed = false;
126 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
127 MachineOperand &MO = MI->getOperand(i);
128 if (MO.isReg() && MO.isUse()) {
129 unsigned Reg = MO.getReg();
130 if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg))
131 continue;
132 MachineInstr *DefMI = MRI->getVRegDef(Reg);
133 if (DefMI->getParent() == MBB) {
134 unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
135 if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
136 TargetRegisterInfo::isVirtualRegister(SrcReg) &&
137 !SrcSubIdx && !DstSubIdx) {
138 MO.setReg(SrcReg);
139 Changed = true;
140 }
141 }
142 }
143 }
144
145 return Changed;
146}
147
148static bool hasLivePhysRegDefUse(MachineInstr *MI) {
149 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
150 MachineOperand &MO = MI->getOperand(i);
151 if (!MO.isReg())
152 continue;
153 unsigned Reg = MO.getReg();
154 if (!Reg)
155 continue;
156 if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
157 !(MO.isDef() && MO.isDead()))
158 return true;
Evan Chengc6fe3332010-03-02 02:38:24 +0000159 }
160 return false;
161}
162
Evan Cheng6ba95542010-03-03 02:48:20 +0000163bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
164 bool Changed = false;
165
166 ScopedHashTableScope<MachineInstr*, unsigned> VNTS(VNT);
167 MachineBasicBlock *MBB = Node->getBlock();
168 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
169 ++I) {
170 MachineInstr *MI = &*I;
171 bool SawStore = false;
172 if (!MI->isSafeToMove(TII, 0, SawStore))
173 continue;
174 // Ignore copies or instructions that read / write physical registers
175 // (except for dead defs of physical registers).
176 unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
177 if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
178 continue;
179 if (hasLivePhysRegDefUse(MI))
180 continue;
181
182 bool FoundCSE = VNT.count(MI);
183 if (!FoundCSE) {
184 // Look for trivial copy coalescing opportunities.
185 if (PerformTrivialCoalescing(MI, MBB))
186 FoundCSE = VNT.count(MI);
187 }
188
189 if (FoundCSE)
190 DEBUG(dbgs() << "Found a common subexpression: " << *MI);
191 else
192 VNT.insert(MI, ++CurrVN);
193 }
194
195 // Recursively call ProcessBlock with childred.
196 const std::vector<MachineDomTreeNode*> &Children = Node->getChildren();
197 for (unsigned i = 0, e = Children.size(); i != e; ++i)
198 Changed |= ProcessBlock(Children[i]);
199
200 return Changed;
201}
202
Evan Chengc6fe3332010-03-02 02:38:24 +0000203bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
Evan Cheng6ba95542010-03-03 02:48:20 +0000204 TII = MF.getTarget().getInstrInfo();
205 MRI = &MF.getRegInfo();
Evan Chengc6fe3332010-03-02 02:38:24 +0000206 DT = &getAnalysis<MachineDominatorTree>();
207 return ProcessBlock(DT->getRootNode());
208}