zcov: / lib/Module/PhiCleaner.cpp


Files: 1 Branches Taken: 90.9% 20 / 22
Generated: 2009-05-17 22:47 Branches Executed: 100.0% 22 / 22
Line Coverage: 92.9% 26 / 28


Programs: 1 Runs 371


       1                 : #include "Passes.h"
       2                 : 
       3                 : #include <set>
       4                 : 
       5                 : using namespace llvm;
       6                 : 
       7                 : char klee::PhiCleanerPass::ID = 0;
       8                 : 
       9              806: bool klee::PhiCleanerPass::runOnFunction(Function &f) {
      10              806:   bool changed = false;
      11                 :   
                    10227: branch 1 taken
                      806: branch 2 taken
      12            21260:   for (Function::iterator b = f.begin(), be = f.end(); b != be; ++b) {
      13                 :     BasicBlock::iterator it = b->begin();
      14                 : 
                      470: branch 0 taken
                     9757: branch 1 taken
      15            10227:     if (it->getOpcode() == Instruction::PHI) {
      16              470:       PHINode *reference = cast<PHINode>(it);
      17                 :       
      18                 :       std::set<Value*> phis;
      19              470:       phis.insert(reference);
      20                 : 
      21              470:       unsigned numBlocks = reference->getNumIncomingValues();
                       50: branch 3 taken
                      470: branch 4 taken
      22             1040:       for (++it; isa<PHINode>(*it); ++it) {
      23               50:         PHINode *pi = cast<PHINode>(it);
      24                 : 
                        0: branch 0 not taken
                       50: branch 1 taken
      25               50:         assert(numBlocks == pi->getNumIncomingValues());
      26                 : 
      27                 :         // see if it is out of order
      28                 :         unsigned i;
                      115: branch 0 taken
                       49: branch 1 taken
      29              164:         for (i=0; i<numBlocks; i++)
                        1: branch 0 taken
                      114: branch 1 taken
      30              115:           if (pi->getIncomingBlock(i) != reference->getIncomingBlock(i))
      31                1:             break;
      32                 : 
                        1: branch 0 taken
                       49: branch 1 taken
      33               50:         if (i!=numBlocks) {
      34                 :           std::vector<Value*> values;
      35                1:           values.reserve(numBlocks);
                        2: branch 0 taken
                        1: branch 1 taken
      36                3:           for (unsigned i=0; i<numBlocks; i++)
      37                2:             values[i] = pi->getIncomingValueForBlock(reference->getIncomingBlock(i));
                        2: branch 0 taken
                        1: branch 1 taken
      38                3:           for (unsigned i=0; i<numBlocks; i++) {
      39                 :             pi->setIncomingBlock(i, reference->getIncomingBlock(i));
      40                2:             pi->setIncomingValue(i, values[i]);
      41                 :           }
      42                1:           changed = true;
      43                 :         }
      44                 : 
      45                 :         // see if it uses any previously defined phi nodes
                      116: branch 0 taken
                       50: branch 1 taken
      46              166:         for (i=0; i<numBlocks; i++) {
      47              116:           Value *value = pi->getIncomingValue(i);
      48                 : 
                        0: branch 0 not taken
                      116: branch 1 taken
      49              116:           if (phis.find(value) != phis.end()) {
      50                 :             // fix by making a "move" at the end of the incoming block
      51                 :             // to a new temporary, which is thus known not to be a phi
      52                 :             // result. we could be somewhat more efficient about this
      53                 :             // by sharing temps and by reordering phi instructions so
      54                 :             // this isn't completely necessary, but in the end this is
      55                 :             // just a pathological case which does not occur very
      56                 :             // often.
      57                 :             Instruction *tmp = 
      58                 :               new BitCastInst(value, 
      59                 :                               value->getType(),
      60                 :                               value->getName() + ".phiclean",
      61                0:                               pi->getIncomingBlock(i)->getTerminator());
      62                0:             pi->setIncomingValue(i, tmp);
      63                 :           }
      64                 : 
      65              116:           changed = true;
      66                 :         }
      67                 :         
      68               50:         phis.insert(pi);
      69                 :       }
      70                 :     }
      71                 :   }
      72                 : 
      73              806:   return changed;
      74                 : }

Generated: 2009-05-17 22:47 by zcov