Пример #1
0
//
// 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->use_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);
}