//===- InstructionCombining.cpp - Combine multiple instructions -----------===//
//
// InstructionCombining - Combine instructions to form fewer, simple
// instructions. This pass does not modify the CFG This pass is where algebraic
// simplification happens.
//
// This pass combines things like:
// %Y = add int 1, %X
// %Z = add int 1, %Y
// into:
// %Z = add int 2, %X
//
// This is a simple worklist driven algorithm.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ConstantHandling.h"
#include "llvm/iMemory.h"
#include "llvm/iOther.h"
#include "llvm/iPHINode.h"
#include "llvm/iOperators.h"
#include "llvm/Pass.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/Support/InstVisitor.h"
#include "Support/Statistic.h"
#include <algorithm>
namespace {
Statistic<> NumCombined ("instcombine", "Number of insts combined");
Statistic<> NumConstProp("instcombine", "Number of constant folds");
Statistic<> NumDeadInst ("instcombine", "Number of dead inst eliminated");
class InstCombiner : public FunctionPass,
public InstVisitor<InstCombiner, Instruction*> {
// Worklist of all of the instructions that need to be simplified.
std::vector<Instruction*> WorkList;
void AddUsesToWorkList(Instruction &I) {
// The instruction was simplified, add all users of the instruction to
// the work lists because they might get more simplified now...
//
for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
UI != UE; ++UI)
WorkList.push_back(cast<Instruction>(*UI));
}
// removeFromWorkList - remove all instances of I from the worklist.
void removeFromWorkList(Instruction *I);
public:
virtual bool runOnFunction(Function &F);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}
// Visitation implementation - Implement instruction combining for different
// instruction types. The semantics are as follows:
// Return Value:
// null - No change was made
// I - Change was made, I is still valid, I may be dead though
// otherwise - Change was made, replace I with returned instruction
//
Instruction *visitAdd(BinaryOperator &I);
Instruction *visitSub(BinaryOperator &I);
Instruction *visitMul(BinaryOperator &I);
Instruction *visitDiv(BinaryOperator &I);
Instruction *visitRem(BinaryOperator &I);
Instruction *visitAnd(BinaryOperator &I);
Instruction *visitOr (BinaryOperator &I);
Instruction *visitXor(BinaryOperator &I);
Instruction *visitSetCondInst(BinaryOperator &I);
Instruction *visitShiftInst(ShiftInst &I);
Instruction *visitCastInst(CastInst &CI);
Instruction *visitPHINode(PHINode &PN);
Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
Instruction *visitAllocationInst(AllocationInst &AI);
// visitInstruction - Specify what to return for unhandled instructions...
Instruction *visitInstruction(Instruction &I) { return 0; }
// InsertNewInstBefore - insert an instruction New before instruction Old
// in the program. Add the new instruction to the worklist.
//
void InsertNewInstBefore(Instruction *New, Instruction &Old) {
assert(New && New->getParent() == 0 &&
"New instruction already inserted into a basic block!");
BasicBlock *BB = Old.getParent();
BB->getInstList().insert(&Old, New); // Insert inst
WorkList.push_back(New); // Add to worklist
}
// ReplaceInstUsesWith - This method is to be used when an instruction is
// found to be dead, replacable with another preexisting expression. Here
// we add all uses of I to the worklist, replace all uses of I with the new
// value, then return I, so that the inst combiner will know that I was
// modified.
//
Instruction *ReplaceInstUsesWith(Instruction &I, Value *V) {
AddUsesToWorkList(I); // Add all modified instrs to worklist
I.replaceAllUsesWith(V);
return &I;
}
};