return CoerceAvailableValueToLoadType(SrcVal, LoadTy, InsertPt, *TD);
}
+struct AvailableValueInBlock {
+ /// BB - The basic block in question.
+ BasicBlock *BB;
+ /// V - The value that is live out of the block.
+ Value *V;
+
+ static AvailableValueInBlock get(BasicBlock *BB, Value *V) {
+ AvailableValueInBlock Res;
+ Res.BB = BB;
+ Res.V = V;
+ return Res;
+ }
+};
+
/// GetAvailableBlockValues - Given the ValuesPerBlock list, convert all of the
/// available values to values of the expected LoadTy in their blocks and insert
/// the new values into BlockReplValues.
static void
GetAvailableBlockValues(DenseMap<BasicBlock*, Value*> &BlockReplValues,
- const SmallVector<std::pair<BasicBlock*,
- Value*>, 16> &ValuesPerBlock,
+ const SmallVector<AvailableValueInBlock, 16> &ValuesPerBlock,
const Type *LoadTy,
const TargetData *TD) {
for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) {
- BasicBlock *BB = ValuesPerBlock[i].first;
- Value *AvailableVal = ValuesPerBlock[i].second;
+ BasicBlock *BB = ValuesPerBlock[i].BB;
+ Value *AvailableVal = ValuesPerBlock[i].V;
Value *&BlockEntry = BlockReplValues[BB];
if (BlockEntry) continue;
AvailableVal = CoerceAvailableValueToLoadType(AvailableVal, LoadTy,
BB->getTerminator(), *TD);
DEBUG(errs() << "GVN COERCED NONLOCAL VAL:\n"
- << *ValuesPerBlock[i].second << '\n'
+ << *ValuesPerBlock[i].V << '\n'
<< *AvailableVal << '\n' << "\n\n\n");
}
BlockEntry = AvailableVal;
// where we have a value available in repl, also keep track of whether we see
// dependencies that produce an unknown value for the load (such as a call
// that could potentially clobber the load).
- SmallVector<std::pair<BasicBlock*, Value*>, 16> ValuesPerBlock;
+ SmallVector<AvailableValueInBlock, 16> ValuesPerBlock;
SmallVector<BasicBlock*, 16> UnavailableBlocks;
const TargetData *TD = 0;
// Loading the allocation -> undef.
if (isa<AllocationInst>(DepInst) || isMalloc(DepInst)) {
- ValuesPerBlock.push_back(std::make_pair(DepBB,
- UndefValue::get(LI->getType())));
+ ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB,
+ UndefValue::get(LI->getType())));
continue;
}
- if (StoreInst* S = dyn_cast<StoreInst>(DepInst)) {
+ if (StoreInst *S = dyn_cast<StoreInst>(DepInst)) {
// Reject loads and stores that are to the same address but are of
// different types if we have to.
if (S->getOperand(0)->getType() != LI->getType()) {
}
}
- ValuesPerBlock.push_back(std::make_pair(DepBB, S->getOperand(0)));
+ ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB,
+ S->getOperand(0)));
- } else if (LoadInst* LD = dyn_cast<LoadInst>(DepInst)) {
+ } else if (LoadInst *LD = dyn_cast<LoadInst>(DepInst)) {
// If the types mismatch and we can't handle it, reject reuse of the load.
if (LD->getType() != LI->getType()) {
if (TD == 0)
continue;
}
}
- ValuesPerBlock.push_back(std::make_pair(DepBB, LD));
+ ValuesPerBlock.push_back(AvailableValueInBlock::get(DepBB, LD));
} else {
// FIXME: Handle memset/memcpy.
UnavailableBlocks.push_back(DepBB);
return true;
}
- ValuesPerBlock.push_back(std::make_pair((*I)->getParent(), *I));
+ ValuesPerBlock.push_back(AvailableValueInBlock::get((*I)->getParent(),
+ *I));
}
DEBUG(errs() << "GVN REMOVING NONLOCAL LOAD: " << *LI << '\n');
// to eliminate LI even if we insert uses in the other predecessors, we will
// end up increasing code size. Reject this by scanning for LI.
for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
- if (ValuesPerBlock[i].second == LI)
+ if (ValuesPerBlock[i].V == LI)
return false;
if (isSinglePred) {
bool isHot = false;
for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
- if (Instruction *I = dyn_cast<Instruction>(ValuesPerBlock[i].second))
+ if (Instruction *I = dyn_cast<Instruction>(ValuesPerBlock[i].V))
// "Hot" Instruction is in some loop (because it dominates its dep.
// instruction).
if (DT->dominates(LI, I)) {
DenseMap<BasicBlock*, char> FullyAvailableBlocks;
for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i)
- FullyAvailableBlocks[ValuesPerBlock[i].first] = true;
+ FullyAvailableBlocks[ValuesPerBlock[i].BB] = true;
for (unsigned i = 0, e = UnavailableBlocks.size(); i != e; ++i)
FullyAvailableBlocks[UnavailableBlocks[i]] = false;
SmallPtrSet<Instruction*, 4> &p = phiMap[LI->getPointerOperand()];
for (SmallPtrSet<Instruction*, 4>::iterator I = p.begin(), E = p.end();
I != E; ++I)
- ValuesPerBlock.push_back(std::make_pair((*I)->getParent(), *I));
+ ValuesPerBlock.push_back(AvailableValueInBlock::get((*I)->getParent(), *I));
DenseMap<BasicBlock*, Value*> BlockReplValues;
GetAvailableBlockValues(BlockReplValues, ValuesPerBlock, LI->getType(), TD);