#include "llvm/Support/Debug.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
/// Constant Propagation.
///
class SCCPSolver : public InstVisitor<SCCPSolver> {
- SmallSet<BasicBlock*, 16> BBExecutable;// The basic blocks that are executable
+ DenseSet<BasicBlock*> BBExecutable;// The basic blocks that are executable
std::map<Value*, LatticeVal> ValueState; // The state each value is in.
/// GlobalValue - If we are tracking any values for the contents of a global
/// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions
/// that return multiple values.
- std::map<std::pair<Function*, unsigned>, LatticeVal> TrackedMultipleRetVals;
+ DenseMap<std::pair<Function*, unsigned>, LatticeVal> TrackedMultipleRetVals;
// The reason for two worklists is that overdefined is the lowest state
// on the lattice, and moving things to overdefined as fast as possible
// By having a separate worklist, we accomplish this because everything
// possibly overdefined will become overdefined at the soonest possible
// point.
- std::vector<Value*> OverdefinedInstWorkList;
- std::vector<Value*> InstWorkList;
+ SmallVector<Value*, 64> OverdefinedInstWorkList;
+ SmallVector<Value*, 64> InstWorkList;
- std::vector<BasicBlock*> BBWorkList; // The BasicBlock work list
+ SmallVector<BasicBlock*, 64> BBWorkList; // The BasicBlock work list
/// UsersOfOverdefinedPHIs - Keep track of any users of PHI nodes that are not
/// overdefined, despite the fact that the PHI node is overdefined.
/// KnownFeasibleEdges - Entries in this set are edges which have already had
/// PHI nodes retriggered.
- typedef std::pair<BasicBlock*,BasicBlock*> Edge;
- std::set<Edge> KnownFeasibleEdges;
+ typedef std::pair<BasicBlock*, BasicBlock*> Edge;
+ DenseSet<Edge> KnownFeasibleEdges;
public:
/// MarkBlockExecutable - This method can be used by clients to mark all of
/// getExecutableBlocks - Once we have solved for constants, return the set of
/// blocks that is known to be executable.
- SmallSet<BasicBlock*, 16> &getExecutableBlocks() {
+ DenseSet<BasicBlock*> &getExecutableBlocks() {
return BBExecutable;
}
if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) {
if (IV.isOverdefined()) { // PHI node becomes overdefined!
- markOverdefined(PNIV, &PN);
+ markOverdefined(&PN);
return;
}
// Yes there is. This means the PHI node is not constant.
// You must be overdefined poor PHI.
//
- markOverdefined(PNIV, &PN); // The PHI node now becomes overdefined
+ markOverdefined(&PN); // The PHI node now becomes overdefined
return; // I'm done analyzing you
}
}
// this is the case, the PHI remains undefined.
//
if (OperandVal)
- markConstant(PNIV, &PN, OperandVal); // Acquire operand value
+ markConstant(&PN, OperandVal); // Acquire operand value
}
void SCCPSolver::visitReturnInst(ReturnInst &I) {
// Handle functions that return multiple values.
if (!TrackedMultipleRetVals.empty() && I.getNumOperands() > 1) {
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
- std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
+ DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, i));
if (It == TrackedMultipleRetVals.end()) break;
mergeInValue(It->second, F, getValueState(I.getOperand(i)));
isa<StructType>(I.getOperand(0)->getType())) {
for (unsigned i = 0, e = I.getOperand(0)->getType()->getNumContainedTypes();
i != e; ++i) {
- std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
+ DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, i));
if (It == TrackedMultipleRetVals.end()) break;
Value *Val = FindInsertedValue(I.getOperand(0), i);
return;
}
- // See if we are tracking the result of the callee.
- std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
- It = TrackedMultipleRetVals.find(std::make_pair(F, *EVI.idx_begin()));
-
- // If not tracking this function (for example, it is a declaration) just move
- // to overdefined.
- if (It == TrackedMultipleRetVals.end()) {
+ // See if we are tracking the result of the callee. If not tracking this
+ // function (for example, it is a declaration) just move to overdefined.
+ if (!TrackedMultipleRetVals.count(std::make_pair(F, *EVI.idx_begin()))) {
markOverdefined(&EVI);
return;
}
// See if we are tracking the result of the callee.
Function *F = IVI.getParent()->getParent();
- std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
+ DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
It = TrackedMultipleRetVals.find(std::make_pair(F, *IVI.idx_begin()));
// Merge in the inserted member value.
} else if (isa<StructType>(I->getType())) {
// Check to see if we're tracking this callee, if not, handle it in the
// common path above.
- std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
- TMRVI = TrackedMultipleRetVals.find(std::make_pair(F, 0));
+ DenseMap<std::pair<Function*, unsigned>, LatticeVal>::iterator
+ TMRVI = TrackedMultipleRetVals.find(std::make_pair(F, 0));
if (TMRVI == TrackedMultipleRetVals.end())
goto CallOverdefined;
// delete their contents now. Note that we cannot actually delete the blocks,
// as we cannot modify the CFG of the function.
//
- SmallSet<BasicBlock*, 16> &ExecutableBBs = Solver.getExecutableBlocks();
- SmallVector<Instruction*, 32> Insts;
+ DenseSet<BasicBlock*> &ExecutableBBs = Solver.getExecutableBlocks();
+ SmallVector<Instruction*, 512> Insts;
std::map<Value*, LatticeVal> &Values = Solver.getValueMapping();
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
// Iterate over all of the instructions in the module, replacing them with
// constants if we have found them to be of constant values.
//
- SmallSet<BasicBlock*, 16> &ExecutableBBs = Solver.getExecutableBlocks();
- SmallVector<Instruction*, 32> Insts;
- SmallVector<BasicBlock*, 32> BlocksToErase;
+ DenseSet<BasicBlock*> &ExecutableBBs = Solver.getExecutableBlocks();
+ SmallVector<Instruction*, 512> Insts;
+ SmallVector<BasicBlock*, 512> BlocksToErase;
std::map<Value*, LatticeVal> &Values = Solver.getValueMapping();
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {