IntrinsicCleaner.cpp

Go to the documentation of this file.
00001 //===-- IntrinsicCleaner.cpp ----------------------------------------------===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "Passes.h"
00011 
00012 #include "llvm/Constants.h"
00013 #include "llvm/DerivedTypes.h"
00014 #include "llvm/Function.h"
00015 #include "llvm/InstrTypes.h"
00016 #include "llvm/Instruction.h"
00017 #include "llvm/Instructions.h"
00018 #include "llvm/IntrinsicInst.h"
00019 #include "llvm/Module.h"
00020 #include "llvm/Pass.h"
00021 #include "llvm/Type.h"
00022 #include "llvm/Transforms/Scalar.h"
00023 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
00024 #include "llvm/Target/TargetData.h"
00025 
00026 using namespace llvm;
00027 
00028 namespace klee {
00029 
00030 char IntrinsicCleanerPass::ID;
00031 
00032 bool IntrinsicCleanerPass::runOnModule(Module &M) {
00033   bool dirty = false;
00034   for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f)
00035     for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b)
00036         dirty |= runOnBasicBlock(*b);
00037   return dirty;
00038 }
00039 
00040 bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b) { 
00041   bool dirty = false;
00042 
00043   for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie;) {     
00044     IntrinsicInst *ii = dyn_cast<IntrinsicInst>(&*i);
00045     // increment now since LowerIntrinsic deletion makes iterator invalid.
00046     ++i;  
00047     if(ii) {
00048       switch (ii->getIntrinsicID()) {
00049       case Intrinsic::vastart:
00050       case Intrinsic::vaend:
00051         break;
00052         
00053         // Lower vacopy so that object resolution etc is handled by
00054         // normal instructions.  FIXME: This is broken for non-x86_32.
00055       case Intrinsic::vacopy: { // (dst, src) -> *((i8**) dst) = *((i8**) src)
00056         Value *dst = ii->getOperand(1);
00057         Value *src = ii->getOperand(2);
00058         Type *i8pp = PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty));
00059         Value *castedDst = CastInst::CreatePointerCast(dst, i8pp, "vacopy.cast.dst", ii);
00060         Value *castedSrc = CastInst::CreatePointerCast(src, i8pp, "vacopy.cast.src", ii);
00061         Value *load = new LoadInst(castedSrc, "vacopy.read", ii);
00062         new StoreInst(load, castedDst, false, ii);
00063         ii->removeFromParent();
00064         delete ii;
00065         break;
00066       }
00067 
00068       case Intrinsic::dbg_stoppoint: {
00069         // We can remove this stoppoint if the next instruction is
00070         // sure to be another stoppoint. This is nice for cleanliness
00071         // but also important for switch statements where it can allow
00072         // the targets to be joined.
00073         bool erase = false;
00074         if (isa<DbgStopPointInst>(i) ||
00075             isa<UnreachableInst>(i)) {
00076           erase = true;
00077         } else if (isa<BranchInst>(i) ||
00078                    isa<SwitchInst>(i)) {
00079           BasicBlock *bb = i->getParent();
00080           erase = true;
00081           for (succ_iterator it=succ_begin(bb), ie=succ_end(bb);
00082                it!=ie; ++it) {
00083             if (!isa<DbgStopPointInst>(it->getFirstNonPHI())) {
00084               erase = false;
00085               break;
00086             }
00087           }
00088         }
00089 
00090         if (erase) {
00091           ii->eraseFromParent();
00092           dirty = true;
00093         }
00094         break;
00095       }
00096 
00097       case Intrinsic::dbg_region_start:
00098       case Intrinsic::dbg_region_end:
00099       case Intrinsic::dbg_func_start:
00100       case Intrinsic::dbg_declare:
00101         // Remove these regardless of lower intrinsics flag. This can
00102         // be removed once IntrinsicLowering is fixed to not have bad
00103         // caches.
00104         ii->eraseFromParent();
00105         dirty = true;
00106         break;
00107                     
00108       default:
00109         if (LowerIntrinsics)
00110           IL->LowerIntrinsicCall(ii);
00111         dirty = true;
00112         break;
00113       }
00114     }
00115   }
00116 
00117   return dirty;
00118 }
00119 }

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8