15 #define DEBUG_TYPE "early-cse"
32 STATISTIC(NumSimplify,
"Number of instructions simplified or DCE'd");
33 STATISTIC(NumCSE,
"Number of instructions CSE'd");
34 STATISTIC(NumCSELoad,
"Number of load instructions CSE'd");
35 STATISTIC(NumCSECall,
"Number of call instructions CSE'd");
36 STATISTIC(NumDSE,
"Number of trivial dead stores removed");
53 assert((isSentinel() || canHandle(I)) &&
"Inst can't be handled!");
56 bool isSentinel()
const {
63 if (
CallInst *CI = dyn_cast<CallInst>(Inst))
64 return CI->doesNotAccessMemory() && !CI->getType()->isVoidTy();
65 return isa<CastInst>(Inst) || isa<BinaryOperator>(Inst) ||
66 isa<GetElementPtrInst>(Inst) || isa<CmpInst>(Inst) ||
67 isa<SelectInst>(Inst) || isa<ExtractElementInst>(Inst) ||
68 isa<InsertElementInst>(Inst) || isa<ShuffleVectorInst>(Inst) ||
69 isa<ExtractValueInst>(Inst) || isa<InsertValueInst>(Inst);
82 static unsigned getHashValue(SimpleValue Val);
83 static bool isEqual(SimpleValue LHS, SimpleValue RHS);
91 Value *LHS = BinOp->getOperand(0);
92 Value *RHS = BinOp->getOperand(1);
93 if (BinOp->isCommutative() && BinOp->getOperand(0) > BinOp->getOperand(1))
96 if (isa<OverflowingBinaryOperator>(BinOp)) {
101 return hash_combine(BinOp->getOpcode(), Overflow, LHS, RHS);
107 if (
CmpInst *CI = dyn_cast<CmpInst>(Inst)) {
108 Value *LHS = CI->getOperand(0);
109 Value *RHS = CI->getOperand(1);
113 Pred = CI->getSwappedPredicate();
118 if (
CastInst *CI = dyn_cast<CastInst>(Inst))
119 return hash_combine(CI->getOpcode(), CI->getType(), CI->getOperand(0));
122 return hash_combine(EVI->getOpcode(), EVI->getOperand(0),
126 return hash_combine(IVI->getOpcode(), IVI->getOperand(0),
130 assert((isa<CallInst>(Inst) || isa<BinaryOperator>(Inst) ||
131 isa<GetElementPtrInst>(Inst) || isa<SelectInst>(Inst) ||
132 isa<ExtractElementInst>(Inst) || isa<InsertElementInst>(Inst) ||
133 isa<ShuffleVectorInst>(Inst)) &&
"Invalid/unknown instruction");
144 if (LHS.isSentinel() || RHS.isSentinel())
147 if (LHSI->
getOpcode() != RHSI->getOpcode())
return false;
152 if (!LHSBinOp->isCommutative())
155 assert(isa<BinaryOperator>(RHSI)
156 &&
"same opcode, but different instruction type?");
160 if (isa<OverflowingBinaryOperator>(LHSBinOp)) {
161 assert(isa<OverflowingBinaryOperator>(RHSBinOp)
162 &&
"same opcode, but different operator type?");
169 return LHSBinOp->getOperand(0) == RHSBinOp->
getOperand(1) &&
170 LHSBinOp->getOperand(1) == RHSBinOp->
getOperand(0);
172 if (
CmpInst *LHSCmp = dyn_cast<CmpInst>(LHSI)) {
173 assert(isa<CmpInst>(RHSI)
174 &&
"same opcode, but different instruction type?");
175 CmpInst *RHSCmp = cast<CmpInst>(RHSI);
178 LHSCmp->getOperand(1) == RHSCmp->
getOperand(0) &&
179 LHSCmp->getSwappedPredicate() == RHSCmp->
getPredicate();
196 assert((isSentinel() || canHandle(I)) &&
"Inst can't be handled!");
199 bool isSentinel()
const {
225 static unsigned getHashValue(CallValue Val);
226 static bool isEqual(CallValue LHS, CallValue RHS);
235 "Cannot value number calls with metadata operands");
245 if (LHS.isSentinel() || RHS.isSentinel())
271 AllocatorTy> ScopedHTType;
278 ScopedHTType *AvailableValues;
291 LoadHTType *AvailableLoads;
296 CallHTType *AvailableCalls;
299 unsigned CurrentGeneration;
315 NodeScope(ScopedHTType *availableValues,
316 LoadHTType *availableLoads,
317 CallHTType *availableCalls) :
318 Scope(*availableValues),
319 LoadScope(*availableLoads),
320 CallScope(*availableCalls) {}
324 void operator=(const NodeScope&) LLVM_DELETED_FUNCTION;
326 ScopedHTType::ScopeTy Scope;
327 LoadHTType::ScopeTy LoadScope;
328 CallHTType::ScopeTy CallScope;
337 StackNode(ScopedHTType *availableValues,
338 LoadHTType *availableLoads,
339 CallHTType *availableCalls,
342 CurrentGeneration(cg), ChildGeneration(cg), Node(n),
343 ChildIter(child), EndIter(end),
344 Scopes(availableValues, availableLoads, availableCalls),
348 unsigned currentGeneration() {
return CurrentGeneration; }
349 unsigned childGeneration() {
return ChildGeneration; }
359 bool isProcessed() {
return Processed; }
360 void process() { Processed =
true; }
363 StackNode(
const StackNode&) LLVM_DELETED_FUNCTION;
364 void operator=(const StackNode&) LLVM_DELETED_FUNCTION;
367 unsigned CurrentGeneration;
368 unsigned ChildGeneration;
382 AU.setPreservesCFG();
391 return new EarlyCSE();
417 bool Changed =
false;
426 DEBUG(
dbgs() <<
"EarlyCSE DCE: " << *Inst <<
'\n');
436 DEBUG(
dbgs() <<
"EarlyCSE Simplify: " << *Inst <<
" to: " << *V <<
'\n');
445 if (SimpleValue::canHandle(Inst)) {
447 if (
Value *V = AvailableValues->lookup(Inst)) {
448 DEBUG(
dbgs() <<
"EarlyCSE CSE: " << *Inst <<
" to: " << *V <<
'\n');
457 AvailableValues->insert(Inst, Inst);
462 if (
LoadInst *
LI = dyn_cast<LoadInst>(Inst)) {
464 if (!
LI->isSimple()) {
471 std::pair<Value*, unsigned> InVal =
473 if (InVal.first != 0 && InVal.second == CurrentGeneration) {
474 DEBUG(
dbgs() <<
"EarlyCSE CSE LOAD: " << *Inst <<
" to: "
475 << *InVal.first <<
'\n');
485 std::pair<Value*, unsigned>(Inst, CurrentGeneration));
495 if (CallValue::canHandle(Inst)) {
498 std::pair<Value*, unsigned> InVal = AvailableCalls->lookup(Inst);
499 if (InVal.first != 0 && InVal.second == CurrentGeneration) {
500 DEBUG(
dbgs() <<
"EarlyCSE CSE CALL: " << *Inst <<
" to: "
501 << *InVal.first <<
'\n');
510 AvailableCalls->insert(Inst,
511 std::pair<Value*, unsigned>(Inst, CurrentGeneration));
521 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
526 DEBUG(
dbgs() <<
"EarlyCSE DEAD STORE: " << *LastStore <<
" due to: "
540 AvailableLoads->insert(SI->getPointerOperand(),
541 std::pair<Value*, unsigned>(SI->getValueOperand(), CurrentGeneration));
554 bool EarlyCSE::runOnFunction(
Function &
F) {
555 std::deque<StackNode *> nodesToProcess;
557 TD = getAnalysisIfAvailable<DataLayout>();
558 TLI = &getAnalysis<TargetLibraryInfo>();
559 DT = &getAnalysis<DominatorTree>();
562 ScopedHTType AVTable;
563 AvailableValues = &AVTable;
564 LoadHTType LoadTable;
565 AvailableLoads = &LoadTable;
566 CallHTType CallTable;
567 AvailableCalls = &CallTable;
569 CurrentGeneration = 0;
570 bool Changed =
false;
573 nodesToProcess.push_front(
574 new StackNode(AvailableValues, AvailableLoads, AvailableCalls,
575 CurrentGeneration, DT->getRootNode(),
576 DT->getRootNode()->begin(),
577 DT->getRootNode()->end()));
580 unsigned LiveOutGeneration = CurrentGeneration;
583 while (!nodesToProcess.empty()) {
586 StackNode *NodeToProcess = nodesToProcess.front();
589 CurrentGeneration = NodeToProcess->currentGeneration();
592 if (!NodeToProcess->isProcessed()) {
594 Changed |= processNode(NodeToProcess->node());
595 NodeToProcess->childGeneration(CurrentGeneration);
596 NodeToProcess->process();
597 }
else if (NodeToProcess->childIter() != NodeToProcess->end()) {
600 nodesToProcess.push_front(
601 new StackNode(AvailableValues,
604 NodeToProcess->childGeneration(), child,
609 delete NodeToProcess;
610 nodesToProcess.pop_front();
615 CurrentGeneration = LiveOutGeneration;
const_iterator end(StringRef path)
Get end iterator over path.
static SimpleValue getTombstoneKey()
Abstract base class of comparison instructions.
static PassRegistry * getPassRegistry()
STATISTIC(NumSimplify,"Number of instructions simplified or DCE'd")
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getNumOperands() const
value_op_iterator value_op_begin()
static CallValue getTombstoneKey()
value_op_iterator value_op_end()
void initializeEarlyCSEPass(PassRegistry &)
LoopInfoBase< BlockT, LoopT > * LI
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isIdenticalTo(const Instruction *I) const
Base class of casting instructions.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
static CallValue getEmptyKey()
ID
LLVM Calling Convention Representation.
bool mayReadFromMemory() const
void replaceAllUsesWith(Value *V)
Optimize for code generation
LLVM Basic Block Representation.
Generic base class which exposes information about an operating system process.
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, const T6 &arg6)
static SimpleValue getEmptyKey()
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=0)
Value * getOperand(unsigned i) const
static unsigned getHash(const void *V)
FunctionPass * createEarlyCSEPass()
Predicate getPredicate() const
Return the predicate for this instruction.
Value * SimplifyInstruction(Instruction *I, const DataLayout *TD=0, const TargetLibraryInfo *TLI=0, const DominatorTree *DT=0)
bool hasNoSignedWrap() const
hasNoSignedWrap - Determine whether the no signed wrap flag is set.
bool mayWriteToMemory() const
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
#define LLVM_DELETED_FUNCTION
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
BasicBlock * getSinglePredecessor()
Return this block if it has a single predecessor block. Otherwise return a null pointer.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
std::vector< DomTreeNodeBase< NodeT > * >::iterator iterator
LLVM Value Representation.
bool hasNoUnsignedWrap() const
hasNoUnsignedWrap - Determine whether the no unsigned wrap flag is set.
unsigned getOpcode() const
getOpcode() returns a member of one of the enums like Instruction::Add.
Value * getPointerOperand()
INITIALIZE_PASS(GlobalMerge,"global-merge","Global Merge", false, false) bool GlobalMerge const DataLayout * TD
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
bool isMetadataTy() const
isMetadataTy - Return true if this is 'metadata'.