Newer
Older
//===-- MachineCSE.cpp - Machine Common Subexpression Elimination Pass ----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass performs global common subexpression elimination on machine
// instructions using a scoped hash table based value numbering scheme. It
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// must be run while the machine function is still in SSA form.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "machine-cse"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
using namespace llvm;
namespace llvm {
template<> struct DenseMapInfo<MachineInstr*> {
static inline MachineInstr *getEmptyKey() {
return 0;
}
static inline MachineInstr *getTombstoneKey() {
return reinterpret_cast<MachineInstr*>(-1);
}
static unsigned getHashValue(const MachineInstr* const &MI) {
unsigned Hash = MI->getOpcode() * 37;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
uint64_t Key = (uint64_t)MO.getType() << 32;
switch (MO.getType()) {
default: break;
case MachineOperand::MO_Register:
Key |= MO.getReg();
break;
case MachineOperand::MO_Immediate:
Key |= MO.getImm();
break;
case MachineOperand::MO_FrameIndex:
case MachineOperand::MO_ConstantPoolIndex:
case MachineOperand::MO_JumpTableIndex:
Key |= MO.getIndex();
break;
case MachineOperand::MO_MachineBasicBlock:
Key |= DenseMapInfo<void*>::getHashValue(MO.getMBB());
break;
case MachineOperand::MO_GlobalAddress:
Key |= DenseMapInfo<void*>::getHashValue(MO.getGlobal());
break;
case MachineOperand::MO_BlockAddress:
Key |= DenseMapInfo<void*>::getHashValue(MO.getBlockAddress());
break;
}
Key += ~(Key << 32);
Key ^= (Key >> 22);
Key += ~(Key << 13);
Key ^= (Key >> 8);
Key += (Key << 3);
Key ^= (Key >> 15);
Key += ~(Key << 27);
Key ^= (Key >> 31);
Hash = (unsigned)Key + Hash * 37;
}
return Hash;
}
static bool isEqual(const MachineInstr* const &LHS,
const MachineInstr* const &RHS) {
return LHS->isIdenticalTo(RHS);
}
};
} // end llvm namespace
namespace {
class MachineCSE : public MachineFunctionPass {
ScopedHashTable<MachineInstr*, unsigned> VNT;
MachineDominatorTree *DT;
public:
static char ID; // Pass identification
MachineCSE() : MachineFunctionPass(&ID) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
}
private:
bool ProcessBlock(MachineDomTreeNode *Node);
};
} // end anonymous namespace
char MachineCSE::ID = 0;
static RegisterPass<MachineCSE>
X("machine-cse", "Machine Common Subexpression Elimination");
FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
ScopedHashTableScope<MachineInstr*, unsigned> VNTS(VNT);
MachineBasicBlock *MBB = Node->getBlock();
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
++I) {
}
return false;
}
bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
DT = &getAnalysis<MachineDominatorTree>();
return ProcessBlock(DT->getRootNode());
}