DeadTypeElimination.cpp [plain text]
#define DEBUG_TYPE "deadtypeelim"
#include "llvm/Transforms/IPO.h"
#include "llvm/Analysis/FindUsedTypes.h"
#include "llvm/Module.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(NumKilled, "Number of unused typenames removed from symtab");
namespace {
struct DTE : public ModulePass {
static char ID; DTE() : ModulePass(ID) {
initializeDTEPass(*PassRegistry::getPassRegistry());
}
bool runOnModule(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<FindUsedTypes>();
}
};
}
char DTE::ID = 0;
INITIALIZE_PASS_BEGIN(DTE, "deadtypeelim", "Dead Type Elimination",
false, false)
INITIALIZE_PASS_DEPENDENCY(FindUsedTypes)
INITIALIZE_PASS_END(DTE, "deadtypeelim", "Dead Type Elimination", false, false)
ModulePass *llvm::createDeadTypeEliminationPass() {
return new DTE();
}
static inline bool ShouldNukeSymtabEntry(const Type *Ty){
if (Ty->isPrimitiveType() || Ty->isIntegerTy())
return true;
if (const PointerType *PT = dyn_cast<PointerType>(Ty))
if (PT->getElementType()->isPrimitiveType() ||
PT->getElementType()->isIntegerTy())
return true;
return false;
}
bool DTE::runOnModule(Module &M) {
bool Changed = false;
TypeSymbolTable &ST = M.getTypeSymbolTable();
const SetVector<const Type*> &T = getAnalysis<FindUsedTypes>().getTypes();
std::set<const Type*> UsedTypes(T.begin(), T.end());
TypeSymbolTable::iterator TI = ST.begin();
TypeSymbolTable::iterator TE = ST.end();
while ( TI != TE ) {
const Type *RHS = TI->second;
if (ShouldNukeSymtabEntry(RHS) || !UsedTypes.count(RHS)) {
ST.remove(TI++);
++NumKilled;
Changed = true;
} else {
++TI;
UsedTypes.erase(RHS);
}
}
return Changed;
}