static void removeLifetimeIntrinsicUsers(AllocaInst *AI) {
  // Knowing that this alloca is promotable, we know that it's safe to kill all
  // instructions except for load and store.
  // FIXME: This function isn't actually specific to lifetime instrinsics. It
  // also is redundant with the actual analysis of the loads and stores and
  // should be folded into that.

  SmallVector<Instruction *, 8> Worklist;
  SmallPtrSet<Instruction *, 8> Visited;
  SmallVector<Instruction *, 8> Dead;
  Worklist.push_back(AI);

  do {
    Instruction *I = Worklist.pop_back_val();

    if (I->use_empty()) {
      Dead.push_back(I);
      continue;
    }

    for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
         UI != UE; ++UI)
      if (!isa<LoadInst>(*UI) && !isa<StoreInst>(*UI) &&
          Visited.insert(cast<Instruction>(*UI)))
        Worklist.push_back(cast<Instruction>(*UI));
  } while (!Worklist.empty());

  while (!Dead.empty()) {
    Instruction *I = Dead.pop_back_val();

    // Don't delete the alloca itself.
    if (I == AI)
      continue;

    // Note that we open code the deletion algorithm here because we know
    // apriori that all of the instructions using an alloca that reaches here
    // are trivially dead when their use list becomes empty (The only risk are
    // lifetime markers which we specifically want to nuke). By coding it here
    // we can skip the triviality test and be more efficient.
    //
    // Null out all of the instruction's operands to see if any operand becomes
    // dead as we go.
    for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); OI != OE;
         ++OI) {
      Instruction *Op = dyn_cast<Instruction>(*OI);
      if (!Op)
        continue;

      OI->set(0);
      if (!Op->use_empty())
        continue;

      Dead.push_back(Op);
    }
    I->eraseFromParent();
  }
}
Exemple #2
0
void Preparer::replaceUndefsWithNull(User *I, ValueSet &Replaced) {
  if (Replaced.count(I))
    return;
  Replaced.insert(I);
  for (User::op_iterator OI = I->op_begin(); OI != I->op_end(); ++OI) {
    Value *V = OI->get();
    if (isa<UndefValue>(V) && V->getType()->isPointerTy()) {
      OI->set(ConstantPointerNull::get(cast<PointerType>(V->getType())));
    }
    if (User *I2 = dyn_cast<User>(V)) {
      replaceUndefsWithNull(I2, Replaced);
    }
  }
}