Esempio n. 1
0
bool CallAnalyzer::visitBitCast(BitCastInst &I) {
  // Propagate constants through bitcasts.
  Constant *COp = dyn_cast<Constant>(I.getOperand(0));
  if (!COp)
    COp = SimplifiedValues.lookup(I.getOperand(0));
  if (COp)
    if (Constant *C = ConstantExpr::getBitCast(COp, I.getType())) {
      SimplifiedValues[&I] = C;
      return true;
    }

  // Track base/offsets through casts
  std::pair<Value *, APInt> BaseAndOffset
    = ConstantOffsetPtrs.lookup(I.getOperand(0));
  // Casts don't change the offset, just wrap it up.
  if (BaseAndOffset.first)
    ConstantOffsetPtrs[&I] = BaseAndOffset;

  // Also look for SROA candidates here.
  Value *SROAArg;
  DenseMap<Value *, int>::iterator CostIt;
  if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt))
    SROAArgValues[&I] = SROAArg;

  // Bitcasts are always zero cost.
  return true;
}
Esempio n. 2
0
void MemoryInstrumenter::instrumentVarArgFunction(Function *F) {
    IntrinsicInst *VAStart = findAnyVAStart(F);
    assert(VAStart && "cannot find any llvm.va_start");
    BitCastInst *ArrayDecay = cast<BitCastInst>(VAStart->getOperand(0));
    assert(ArrayDecay->getType() == CharStarType);

    // The source of the bitcast does not have to be an alloca. In unoptimized
    // bitcode, it's likely a GEP. In that case, we need track further.
    Instruction *Alloca = ArrayDecay;
    while (!isa<AllocaInst>(Alloca)) {
        Alloca = cast<Instruction>(Alloca->getOperand(0));
    }

    // Clone Alloca, ArrayDecay, and VAStart, and replace their operands.
    Instruction *ClonedAlloca = Alloca->clone();
    Instruction *ClonedArrayDecay = ArrayDecay->clone();
    Instruction *ClonedVAStart = VAStart->clone();
    ClonedArrayDecay->setOperand(0, ClonedAlloca);
    ClonedVAStart->setOperand(0, ClonedArrayDecay);

    // Insert the cloned instructions to the entry block.
    BasicBlock::iterator InsertPos = F->begin()->begin();
    BasicBlock::InstListType &InstList = F->begin()->getInstList();
    InstList.insert(InsertPos, ClonedAlloca);
    InstList.insert(InsertPos, ClonedArrayDecay);
    InstList.insert(InsertPos, ClonedVAStart);

    // Hook the llvm.va_start.
    CallInst::Create(VAStartHook, ClonedArrayDecay, "", InsertPos);
}
Esempio n. 3
0
void GraphBuilder::visitBitCastInst(BitCastInst &I) {
  if (!isa<PointerType>(I.getType())) return; // Only pointers
  DSNodeHandle Ptr = getValueDest(I.getOperand(0));
  if (Ptr.isNull()) return;
  setDestTo(I, Ptr);
}
Esempio n. 4
0
bool CombineNoopCasts::runOnBasicBlock(BasicBlock &BB) {
  bool Changed = false;

  for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE;) {
    Instruction* Inst = BBI++;
    if (IntToPtrInst *Cast1 = dyn_cast<IntToPtrInst>(Inst)) {
      if (isa<PtrToIntInst>(Cast1->getOperand(0)) ||
          (isa<ConstantExpr>(Cast1->getOperand(0)) &&
           cast<ConstantExpr>(Cast1->getOperand(0))->getOpcode() == Instruction::PtrToInt)) {
        User *Cast2 = cast<User>(Cast1->getOperand(0));
        Value *V = Cast2->getOperand(0);
        if(Cast2->getType() != IntPtrType) {
          continue;
        }
        if (V->getType() != Cast1->getType())
          V = CopyDebug(new BitCastInst(V, Cast1->getType(),
                                        V->getName() + ".bc", Cast1),
                        Cast2);
        Cast1->replaceAllUsesWith(V);
        if (Cast1->use_empty())
          Cast1->eraseFromParent();
        if (Cast2->use_empty() && isa<Instruction>(Cast2))
          cast<Instruction>(Cast2)->eraseFromParent();

        Changed = true;
      }
    } else if(PtrToIntInst *Cast1 = dyn_cast<PtrToIntInst>(Inst)) {
      if(Cast1->getType() != IntPtrType) {
        continue;
      }
      if (isa<IntToPtrInst>(Cast1->getOperand(0)) ||
          (isa<ConstantExpr>(Cast1->getOperand(0)) &&
           cast<ConstantExpr>(Cast1->getOperand(0))->getOpcode() == Instruction::IntToPtr)) {
        User *Cast2 = cast<User>(Cast1->getOperand(0));
        Value *V = Cast2->getOperand(0);
        Cast1->replaceAllUsesWith(V);
        if (Cast1->use_empty())
          Cast1->eraseFromParent();
        if (Cast2->use_empty() && isa<Instruction>(Cast2))
          cast<Instruction>(Cast2)->eraseFromParent();

        Changed = true;
      } else if(BitCastInst *Cast2 = dyn_cast<BitCastInst>(Cast1->getOperand(0))) {
        Cast1->setOperand(0, Cast2->getOperand(0));
        if (Cast2->use_empty())
          Cast2->eraseFromParent();
      }
    } else if(BitCastInst* Cast1 = dyn_cast<BitCastInst>(Inst)) {
      if(Cast1->getOperand(0)->getType() == Cast1->getType()) {
        Cast1->replaceAllUsesWith(Cast1->getOperand(0));
        Cast1->eraseFromParent();
      } else if(BitCastInst* Cast2 = dyn_cast<BitCastInst>(Cast1->getOperand(0))) {
        if(Cast1->getType() == Cast2->getOperand(0)->getType()) {
          Cast1->replaceAllUsesWith(Cast2->getOperand(0));
          Cast1->eraseFromParent();
          
          if (Cast2->use_empty()) {
            Cast2->eraseFromParent();
          }
        }
      }
    }
  }

  // de-duplicate bitcasts:
  DenseMap<std::pair<Value*, Type*>, BitCastInst*> BCs;
  for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI != BBE;) {
    Instruction* Inst = BBI++;

    if(PtrToIntInst *Cast1 = dyn_cast<PtrToIntInst>(Inst)) {
      if(Cast1->use_empty()) {
        Cast1->eraseFromParent();
        continue;
      }
    }

    if(!isa<BitCastInst>(Inst)) {
      continue;
    }

    BitCastInst* BC = cast<BitCastInst>(Inst);
    auto Val = std::make_pair(BC->getOperand(0), BC->getType());
    auto BI = BCs.find(Val);
    if(BI == BCs.end()) {
      BCs.insert(std::make_pair(Val, BC));
    } else {
      BC->replaceAllUsesWith(BI->second);
      BC->eraseFromParent();
    }
  }

  return Changed;
}