PhiCleaner.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Passes.h"
00011
00012 #include <set>
00013
00014 using namespace llvm;
00015
00016 char klee::PhiCleanerPass::ID = 0;
00017
00018 bool klee::PhiCleanerPass::runOnFunction(Function &f) {
00019 bool changed = false;
00020
00021 for (Function::iterator b = f.begin(), be = f.end(); b != be; ++b) {
00022 BasicBlock::iterator it = b->begin();
00023
00024 if (it->getOpcode() == Instruction::PHI) {
00025 PHINode *reference = cast<PHINode>(it);
00026
00027 std::set<Value*> phis;
00028 phis.insert(reference);
00029
00030 unsigned numBlocks = reference->getNumIncomingValues();
00031 for (++it; isa<PHINode>(*it); ++it) {
00032 PHINode *pi = cast<PHINode>(it);
00033
00034 assert(numBlocks == pi->getNumIncomingValues());
00035
00036
00037 unsigned i;
00038 for (i=0; i<numBlocks; i++)
00039 if (pi->getIncomingBlock(i) != reference->getIncomingBlock(i))
00040 break;
00041
00042 if (i!=numBlocks) {
00043 std::vector<Value*> values;
00044 values.reserve(numBlocks);
00045 for (unsigned i=0; i<numBlocks; i++)
00046 values[i] = pi->getIncomingValueForBlock(reference->getIncomingBlock(i));
00047 for (unsigned i=0; i<numBlocks; i++) {
00048 pi->setIncomingBlock(i, reference->getIncomingBlock(i));
00049 pi->setIncomingValue(i, values[i]);
00050 }
00051 changed = true;
00052 }
00053
00054
00055 for (i=0; i<numBlocks; i++) {
00056 Value *value = pi->getIncomingValue(i);
00057
00058 if (phis.find(value) != phis.end()) {
00059
00060
00061
00062
00063
00064
00065
00066 Instruction *tmp =
00067 new BitCastInst(value,
00068 value->getType(),
00069 value->getName() + ".phiclean",
00070 pi->getIncomingBlock(i)->getTerminator());
00071 pi->setIncomingValue(i, tmp);
00072 }
00073
00074 changed = true;
00075 }
00076
00077 phis.insert(pi);
00078 }
00079 }
00080 }
00081
00082 return changed;
00083 }