blob: d495721de3d032d9857e532441d5d8df3f34c36d [file] [log] [blame]
//===-- SimplifyInsertValue.cpp - Remove extraneous insertvalue insts------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Simplify insertvalue
// Replace insertvalue by storess where possible
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "simplify-iv"
#include "assistDS/SimplifyInsertValue.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Debug.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/DataLayout.h"
#include <set>
#include <map>
#include <vector>
using namespace llvm;
// Pass statistic
STATISTIC(numErased, "Number of Instructions Deleted");
//
// Method: runOnModule()
//
// Description:
// Entry point for this LLVM pass. Search for insertvalue instructions
// that can be simplified.
//
// Inputs:
// M - A reference to the LLVM module to transform.
//
// Outputs:
// M - The transformed LLVM module.
//
// Return value:
// true - The module was modified.
// false - The module was not modified.
//
bool SimplifyIV::runOnModule(Module& M) {
// Repeat till no change
bool changed;
do {
changed = false;
std::vector<StoreInst*> worklist;
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
InsertValueInst *IV = dyn_cast<InsertValueInst>(I++);
if(!IV)
continue;
// Find all insert value instructions.
if(!IV->hasOneUse())
continue;
// Check that its only use is a StoreInst
StoreInst *SI = dyn_cast<StoreInst>(*(IV->user_begin()));
if(!SI)
continue;
// Check that it is the stored value
if(SI->getOperand(0) != IV)
continue;
changed = true;
numErased++;
do {
// replace by a series of gep/stores
SmallVector<Value*, 8> Indices;
Type *Int32Ty = Type::getInt32Ty(M.getContext());
Indices.push_back(Constant::getNullValue(Int32Ty));
for (InsertValueInst::idx_iterator I = IV->idx_begin(), E = IV->idx_end();
I != E; ++I) {
Indices.push_back(ConstantInt::get(Int32Ty, *I));
}
GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(SI->getOperand(1), Indices,
SI->getName(), SI) ;
new StoreInst(IV->getInsertedValueOperand(), GEP, SI);
IV = dyn_cast<InsertValueInst>(IV->getAggregateOperand());
} while(IV);
worklist.push_back(SI);
}
}
}
while(!worklist.empty()) {
StoreInst *SI = worklist.back();
worklist.pop_back();
SI->eraseFromParent();
}
} while(changed);
return (numErased > 0);
}
// Pass ID variable
char SimplifyIV::ID = 0;
// Register the pass
static RegisterPass<SimplifyIV>
X("simplify-iv", "Simplify insert value");