void AliasSetTracker::add(const AliasSetTracker &AST) { assert(&AA == &AST.AA && "Merging AliasSetTracker objects with different Alias Analyses!"); // Loop over all of the alias sets in AST, adding the pointers contained // therein into the current alias sets. This can cause alias sets to be // merged together in the current AST. for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) { if (I->Forward) continue; // Ignore forwarding alias sets AliasSet &AS = const_cast<AliasSet&>(*I); // If there are any call sites in the alias set, add them to this AST. for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i) add(AS.UnknownInsts[i]); // Loop over all of the pointers in this alias set. bool X; for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) { AliasSet &NewAS = addPointer(ASI.getPointer(), ASI.getSize(), ASI.getTBAAInfo(), (AliasSet::AccessType)AS.AccessTy, X); if (AS.isVolatile()) NewAS.setVolatile(); } } }
void AliasSetTracker::add(const AliasSetTracker &AST) { assert(&AA == &AST.AA && "Merging AliasSetTracker objects with different Alias Analyses!"); // Loop over all of the alias sets in AST, adding the pointers contained // therein into the current alias sets. This can cause alias sets to be // merged together in the current AST. for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I) if (!I->Forward) { // Ignore forwarding alias sets AliasSet &AS = const_cast<AliasSet&>(*I); // If there are any call sites in the alias set, add them to this AST. for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i) add(AS.CallSites[i]); // Loop over all of the pointers in this alias set... AliasSet::iterator I = AS.begin(), E = AS.end(); bool X; for (; I != E; ++I) addPointer(I.getPointer(), I.getSize(), (AliasSet::AccessType)AS.AccessTy, X); } }
void AliasSetTracker::add(const AliasSetTracker &AST) { assert(&AA == &AST.AA && "Merging AliasSetTracker objects with different Alias Analyses!"); // Loop over all of the alias sets in AST, adding the pointers contained // therein into the current alias sets. This can cause alias sets to be // merged together in the current AST. for (const AliasSet &AS : AST) { if (AS.Forward) continue; // Ignore forwarding alias sets // If there are any call sites in the alias set, add them to this AST. for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i) if (auto *Inst = AS.getUnknownInst(i)) add(Inst); // Loop over all of the pointers in this alias set. for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) addPointer( MemoryLocation(ASI.getPointer(), ASI.getSize(), ASI.getAAInfo()), (AliasSet::AccessLattice)AS.Access); } }
InsInfo::InsInfo(const Instruction *i, AliasAnalysis &aa, AliasSetTracker &ast) : AA(&aa), AST(&ast), ins(i), sliced(true) { DEBUG( errs() << "new InsInfo for "); DEBUG( i->print(errs()) ); DEBUG( errs() << "\n"); //typedef ptr::PointsToSets::PointsToSet PTSet; if (const LoadInst *LI = dyn_cast<const LoadInst>(i)) { addDEF(Pointee(i, -1)); const Value *op = elimConstExpr(LI->getPointerOperand()); if (isa<ConstantPointerNull>(op)) { errs() << "ERROR in analysed code -- reading from address 0 at " << i->getParent()->getParent()->getName() << ":\n"; i->print(errs()); } else if (isa<ConstantInt>(op)) { } else { addREF(Pointee(op, -1)); /*if (!hasExtraReference(op)) { const PTSet &S = getPointsToSet(op,PS); for (PTSet::const_iterator I = S.begin(), E = S.end(); I != E; ++I) addREF(*I); }*/ if (!hasExtraReference(op)) { uint64_t Size = 0; if (op->getType()->isSized()) Size = AA->getTypeStoreSize(op->getType()); Value* temp = const_cast<Value*>(op); const AliasSet* S = AST->getAliasSetForPointerIfExists(temp, Size, LI->getMetadata(LLVMContext::MD_tbaa)); if( S != NULL ){ for (AliasSet::iterator I = S->begin(), E = S->end(); I != E; ++I) addREF(Pointee(I.getPointer(), -1)); } addREF(Pointee(op, -1)); } } } else if (const StoreInst *SI = dyn_cast<const StoreInst>(i)) { const Value *l = elimConstExpr(SI->getPointerOperand()); if (isa<ConstantPointerNull>(l)) { errs() << "ERROR in analysed code -- writing to address 0 at " << i->getParent()->getParent()->getName() << ":\n"; i->print(errs()); } else if (isa<ConstantInt>(l)) { } else { if (hasExtraReference(l)) { addDEF(Pointee(l, -1)); } else { uint64_t Size = 0; if (l->getType()->isSized()) Size = AA->getTypeStoreSize(l->getType()); Value* temp = const_cast<Value*>(l); const AliasSet* S = AST->getAliasSetForPointerIfExists(temp, Size, SI->getMetadata(LLVMContext::MD_tbaa)); if( S!= NULL ){ for (AliasSet::iterator I = S->begin(), E = S->end(); I != E; ++I) addDEF(Pointee(I.getPointer(), -1)); } addDEF(Pointee(l, -1)); /*const PTSet &S = getPointsToSet(l, PS); for (PTSet::const_iterator I = S.begin(), E = S.end(); I != E; ++I) addDEF(*I);*/ } if (!l->getType()->isIntegerTy()) addREF(Pointee(l, -1)); const Value *r = elimConstExpr(SI->getValueOperand()); if (!hasExtraReference(r) && !isConstantValue(r)) addREF(Pointee(r, -1)); } } else if (const GetElementPtrInst *gep = dyn_cast<const GetElementPtrInst>(i)) { addDEF(Pointee(i, -1)); addREF(Pointee(gep->getPointerOperand(), -1)); for (unsigned i = 1, e = gep->getNumOperands(); i != e; ++i) { Value *op = gep->getOperand(i); if (!isa<ConstantInt>(op)) addREF(Pointee(op, -1)); } } else if (CallInst const* const C = dyn_cast<const CallInst>(i)) { const Value *cv = C->getCalledValue(); if (isInlineAssembly(C)) { DEBUG( errs() << "ERROR: Inline assembler detected in " << i->getParent()->getParent()->getName() << ", ignoring\n"); } else if (isMemoryAllocation(cv)) { addDEF(Pointee(i, -1)); } else if (isMemoryDeallocation(cv)) { } else if (isMemoryCopy(cv) || isMemoryMove(cv)) { const Value *l = elimConstExpr(C->getOperand(0)); if (isPointerValue(l)) { uint64_t Size = 0; if (l->getType()->isSized()) Size = AA->getTypeStoreSize(l->getType()); Value* temp = const_cast<Value*>(l); const AliasSet* S = AST->getAliasSetForPointerIfExists(temp, Size, C->getMetadata(LLVMContext::MD_tbaa)); if( S!= NULL ){ for (AliasSet::iterator I = S->begin(), E = S->end(); I != E; ++I) addDEF(Pointee(I.getPointer(), -1)); } addDEF(Pointee(l, -1)); /*const PTSet &L = getPointsToSet(l, PS); for (PTSet::const_iterator p = L.begin(); p != L.end(); ++p) addDEF(*p);*/ } const Value *r = elimConstExpr(C->getOperand(1)); const Value *len = elimConstExpr(C->getOperand(2)); addREF(Pointee(l, -1)); addREF(Pointee(r, -1)); /* memcpy/memset wouldn't work with len being 'undef' */ addREF(Pointee(len, -1)); if (isPointerValue(r)) { uint64_t Size = 0; if (r->getType()->isSized()) Size = AA->getTypeStoreSize(r->getType()); Value* temp = const_cast<Value*>(r); const AliasSet* S = AST->getAliasSetForPointerIfExists(temp, Size, C->getMetadata(LLVMContext::MD_tbaa)); if( S!= NULL ){ for (AliasSet::iterator I = S->begin(), E = S->end(); I != E; ++I) addREF(Pointee(I.getPointer(), -1)); } addREF(Pointee(r, -1)); /*const PTSet &R = getPointsToSet(r, PS); for (PTSet::const_iterator p = R.begin(); p != R.end(); ++p) addREF(*p);*/ } } else if (!memoryManStuff(C)) { //typedef std::vector<const llvm::Function *> CalledVec; //CalledVec CV; //getCalledFunctions(C, PS, std::back_inserter(CV)); const Value *callie = C->getCalledValue(); if (!isa<Function>(callie)) addREF(Pointee(callie, -1)); /*for (CalledVec::const_iterator f = CV.begin(); f != CV.end(); ++f) { mods::Modifies::mapped_type const& M = getModSet(*f, MOD); for (mods::Modifies::mapped_type::const_iterator v = M.begin(); v != M.end(); ++v) addDEF(Pointee(*v, -1)); }*/ if (!callToVoidFunction(C)) addDEF(Pointee(C, -1)); // Add all the arguments to REF for( int i = 0; i< C->getNumArgOperands(); i++){ const Value *r = C->getArgOperand(i); if( const ConstantInt *I = dyn_cast<const ConstantInt>(r) ){ } else addREF(Pointee(r, -1)); } } } else if (isa<const ReturnInst>(i)) { } else if (const BinaryOperator *BO = dyn_cast<const BinaryOperator>(i)) { addDEF(Pointee(i, -1)); if (!isConstantValue(BO->getOperand(0))) addREF(Pointee(BO->getOperand(0), -1)); if (!isConstantValue(BO->getOperand(1))) addREF(Pointee(BO->getOperand(1), -1)); } else if (const CastInst *CI = dyn_cast<const CastInst>(i)) { addDEF(Pointee(i, -1)); //if (!hasExtraReference(CI->getOperand(0))) addREF(Pointee(CI->getOperand(0), -1)); } else if (const AllocaInst *AI = dyn_cast<const AllocaInst>(i)) { addDEF(Pointee(AI, -1)); } else if (const CmpInst *CI = dyn_cast<const CmpInst>(i)) { addDEF(Pointee(i, -1)); if (!isConstantValue(CI->getOperand(0))) addREF(Pointee(CI->getOperand(0), -1)); if (!isConstantValue(CI->getOperand(1))) addREF(Pointee(CI->getOperand(1), -1)); } else if (const BranchInst *BI = dyn_cast<const BranchInst>(i)) { if (BI->isConditional() && !isConstantValue(BI->getCondition())) addREF(Pointee(BI->getCondition(), -1)); } else if (const PHINode *phi = dyn_cast<const PHINode>(i)) { addDEF(Pointee(i, -1)); for (unsigned k = 0; k < phi->getNumIncomingValues(); ++k) if (!isConstantValue(phi->getIncomingValue(k))) addREF(Pointee(phi->getIncomingValue(k), -1)); } else if (const SwitchInst *SI = dyn_cast<SwitchInst>(i)) { if (!isConstantValue(SI->getCondition())) addREF(Pointee(SI->getCondition(), -1)); } else if (const SelectInst *SI = dyn_cast<const SelectInst>(i)) { addDEF(Pointee(i, -1)); if (!isConstantValue(SI->getCondition())) addREF(Pointee(SI->getCondition(), -1)); if (!isConstantValue(SI->getTrueValue())) addREF(Pointee(SI->getTrueValue(), -1)); if (!isConstantValue(SI->getFalseValue())) addREF(Pointee(SI->getFalseValue(), -1)); } else if (isa<const UnreachableInst>(i)) { } else if (const ExtractValueInst *EV = dyn_cast<const ExtractValueInst>(i)) { addDEF(Pointee(i, -1)); addREF(Pointee(EV->getAggregateOperand(), -1)); } else if (const InsertValueInst *IV = dyn_cast<const InsertValueInst>(i)) { const Value *r = IV->getInsertedValueOperand(); addDEF(Pointee(IV->getAggregateOperand(), -1)); if (!isConstantValue(r)) addREF(Pointee(r, -1)); } else { errs() << "ERROR: Unsupported instruction reached\n"; i->print(errs()); } }