diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7c15231b1ad..911be223b21 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -162,6 +162,10 @@ namespace llvm { /// FunctionPass *createGCInfoPrinter(raw_ostream &OS); + /// createMachineCSEPass - This pass performs global CSE on machine + /// instructions. + FunctionPass *createMachineCSEPass(); + /// createMachineLICMPass - This pass performs LICM on machine instructions. /// FunctionPass *createMachineLICMPass(); diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp new file mode 100644 index 00000000000..288fb473494 --- /dev/null +++ b/lib/CodeGen/MachineCSE.cpp @@ -0,0 +1,124 @@ +//===-- 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 schemem. IT +// 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 { + static inline MachineInstr *getEmptyKey() { + return 0; + } + + static inline MachineInstr *getTombstoneKey() { + return reinterpret_cast(-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::getHashValue(MO.getMBB()); + break; + case MachineOperand::MO_GlobalAddress: + Key |= DenseMapInfo::getHashValue(MO.getGlobal()); + break; + case MachineOperand::MO_BlockAddress: + Key |= DenseMapInfo::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 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(); + AU.addPreserved(); + } + + private: + bool ProcessBlock(MachineDomTreeNode *Node); + }; +} // end anonymous namespace + +char MachineCSE::ID = 0; +static RegisterPass +X("machine-cse", "Machine Common Subexpression Elimination"); + +FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); } + +bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) { + ScopedHashTableScope 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(); + return ProcessBlock(DT->getRootNode()); +}