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; }
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); }
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); }
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; }