/// isPossibleSelfRead - If 'Inst' might be a self read (i.e. a noop copy of a /// memory region into an identical pointer) then it doesn't actually make its /// input dead in the traditional sense. Consider this case: /// /// memcpy(A <- B) /// memcpy(A <- A) /// /// In this case, the second store to A does not make the first store to A dead. /// The usual situation isn't an explicit A<-A store like this (which can be /// trivially removed) but a case where two pointers may alias. /// /// This function detects when it is unsafe to remove a dependent instruction /// because the DSE inducing instruction may be a self-read. static bool isPossibleSelfRead(Instruction *Inst, const AliasAnalysis::Location &InstStoreLoc, Instruction *DepWrite, AliasAnalysis &AA) { // Self reads can only happen for instructions that read memory. Get the // location read. AliasAnalysis::Location InstReadLoc = getLocForRead(Inst, AA); if (InstReadLoc.Ptr == 0) return false; // Not a reading instruction. // If the read and written loc obviously don't alias, it isn't a read. if (AA.isNoAlias(InstReadLoc, InstStoreLoc)) return false; // Okay, 'Inst' may copy over itself. However, we can still remove a the // DepWrite instruction if we can prove that it reads from the same location // as Inst. This handles useful cases like: // memcpy(A <- B) // memcpy(A <- B) // Here we don't know if A/B may alias, but we do know that B/B are must // aliases, so removing the first memcpy is safe (assuming it writes <= # // bytes as the second one. AliasAnalysis::Location DepReadLoc = getLocForRead(DepWrite, AA); if (DepReadLoc.Ptr && AA.isMustAlias(InstReadLoc.Ptr, DepReadLoc.Ptr)) return false; // If DepWrite doesn't read memory or if we can't prove it is a must alias, // then it can't be considered dead. return true; }
static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA, SmallPtrSetImpl<Instruction *> &Stores) { if (Inst->mayWriteToMemory()) { Stores.insert(Inst); return false; } if (LoadInst *L = dyn_cast<LoadInst>(Inst)) { MemoryLocation Loc = MemoryLocation::get(L); for (Instruction *S : Stores) if (isModSet(AA.getModRefInfo(S, Loc))) return false; } if (Inst->isTerminator() || isa<PHINode>(Inst) || Inst->isEHPad() || Inst->mayThrow()) return false; if (auto *Call = dyn_cast<CallBase>(Inst)) { // Convergent operations cannot be made control-dependent on additional // values. if (Call->hasFnAttr(Attribute::Convergent)) return false; for (Instruction *S : Stores) if (isModSet(AA.getModRefInfo(S, Call))) return false; } return true; }
/// aliasesPointer - Return true if the specified pointer "may" (or must) /// alias one of the members in the set. /// bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const { if (AliasTy == MustAlias) { assert(CallSites.empty() && "Illegal must alias set!"); // If this is a set of MustAliases, only check to see if the pointer aliases // SOME value in the set... HashNodePair *SomePtr = getSomePointer(); assert(SomePtr && "Empty must-alias set??"); return AA.alias(SomePtr->first, SomePtr->second.getSize(), Ptr, Size); } // If this is a may-alias set, we have to check all of the pointers in the set // to be sure it doesn't alias the set... for (iterator I = begin(), E = end(); I != E; ++I) if (AA.alias(Ptr, Size, I.getPointer(), I.getSize())) return true; // Check the call sites list and invoke list... if (!CallSites.empty()) { if (AA.hasNoModRefInfoForCalls()) return true; for (unsigned i = 0, e = CallSites.size(); i != e; ++i) if (AA.getModRefInfo(CallSites[i], const_cast<Value*>(Ptr), Size) != AliasAnalysis::NoModRef) return true; } return false; }
/// aliasesPointer - Return true if the specified pointer "may" (or must) /// alias one of the members in the set. /// bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo, AliasAnalysis &AA) const { if (AliasTy == MustAlias) { assert(UnknownInsts.empty() && "Illegal must alias set!"); // If this is a set of MustAliases, only check to see if the pointer aliases // SOME value in the set. PointerRec *SomePtr = getSomePointer(); assert(SomePtr && "Empty must-alias set??"); return AA.alias(AliasAnalysis::Location(SomePtr->getValue(), SomePtr->getSize(), SomePtr->getTBAAInfo()), AliasAnalysis::Location(Ptr, Size, TBAAInfo)); } // If this is a may-alias set, we have to check all of the pointers in the set // to be sure it doesn't alias the set... for (iterator I = begin(), E = end(); I != E; ++I) if (AA.alias(AliasAnalysis::Location(Ptr, Size, TBAAInfo), AliasAnalysis::Location(I.getPointer(), I.getSize(), I.getTBAAInfo()))) return true; // Check the unknown instructions... if (!UnknownInsts.empty()) { for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) if (AA.getModRefInfo(UnknownInsts[i], AliasAnalysis::Location(Ptr, Size, TBAAInfo)) != AliasAnalysis::NoModRef) return true; } return false; }
bool AliasSet::aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const { if (AliasAny) return true; assert(Inst->mayReadOrWriteMemory() && "Instruction must either read or write memory."); for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { if (auto *UnknownInst = getUnknownInst(i)) { const auto *C1 = dyn_cast<CallBase>(UnknownInst); const auto *C2 = dyn_cast<CallBase>(Inst); if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) || isModOrRefSet(AA.getModRefInfo(C2, C1))) return true; } } for (iterator I = begin(), E = end(); I != E; ++I) if (isModOrRefSet(AA.getModRefInfo( Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())))) return true; return false; }
static uint64_t getPointerSize(const Value *V, AliasAnalysis &AA) { uint64_t Size; if (getObjectSize(V, Size, AA.getDataLayout(), AA.getTargetLibraryInfo())) return Size; else { return AA.getTypeStoreSize(V->getType()); } }
/// getLocForRead - Return the location read by the specified "hasMemoryWrite" /// instruction if any. static AliasAnalysis::Location getLocForRead(Instruction *Inst, AliasAnalysis &AA) { assert(hasMemoryWrite(Inst, AA.getTargetLibraryInfo()) && "Unknown instruction case"); // The only instructions that both read and write are the mem transfer // instructions (memcpy/memmove). if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(Inst)) return AA.getLocationForSource(MTI); return AliasAnalysis::Location(); }
/// UpdatePHINodes - Update the PHI nodes in OrigBB to include the values coming /// from NewBB. This also updates AliasAnalysis, if available. static void UpdatePHINodes(BasicBlock *OrigBB, BasicBlock *NewBB, ArrayRef<BasicBlock*> Preds, BranchInst *BI, Pass *P, bool HasLoopExit) { // Otherwise, create a new PHI node in NewBB for each PHI node in OrigBB. AliasAnalysis *AA = P ? P->getAnalysisIfAvailable<AliasAnalysis>() : 0; for (BasicBlock::iterator I = OrigBB->begin(); isa<PHINode>(I); ) { PHINode *PN = cast<PHINode>(I++); // Check to see if all of the values coming in are the same. If so, we // don't need to create a new PHI node, unless it's needed for LCSSA. Value *InVal = 0; if (!HasLoopExit) { InVal = PN->getIncomingValueForBlock(Preds[0]); for (unsigned i = 1, e = Preds.size(); i != e; ++i) if (InVal != PN->getIncomingValueForBlock(Preds[i])) { InVal = 0; break; } } if (InVal) { // If all incoming values for the new PHI would be the same, just don't // make a new PHI. Instead, just remove the incoming values from the old // PHI. for (unsigned i = 0, e = Preds.size(); i != e; ++i) { // Explicitly check the BB index here to handle duplicates in Preds. int Idx = PN->getBasicBlockIndex(Preds[i]); if (Idx >= 0) PN->removeIncomingValue(Idx, false); } } else { // If the values coming into the block are not the same, we need a PHI. // Create the new PHI node, insert it into NewBB at the end of the block PHINode *NewPHI = PHINode::Create(PN->getType(), Preds.size(), PN->getName() + ".ph", BI); if (AA) AA->copyValue(PN, NewPHI); // Move all of the PHI values for 'Preds' to the new PHI. for (unsigned i = 0, e = Preds.size(); i != e; ++i) { Value *V = PN->removeIncomingValue(Preds[i], false); NewPHI->addIncoming(V, Preds[i]); } InVal = NewPHI; } // Add an incoming value to the PHI node in the loop for the preheader // edge. PN->addIncoming(InVal, NewBB); } }
int Transformer4Trace::getValueIndex(Module* module, Value* v, AliasAnalysis & AA) { v = v->stripPointerCastsNoFollowAliases(); while(isa<GlobalAlias>(v)){ // aliase can be either global or bitcast of global v = ((GlobalAlias*)v)->getAliasee()->stripPointerCastsNoFollowAliases(); } if(isa<GlobalVariable>(v) && ((GlobalVariable*)v)->isConstant()){ return -1; } set<Value*>::iterator it = sharedVariables.begin(); while (it != sharedVariables.end()) { Value * rep = *it; if (AA.alias(v, rep) != AliasAnalysis::NoAlias) { if(sv_idx_map.count(rep)){ return sv_idx_map[rep]; } else { int idx = sv_idx_map.size(); sv_idx_map.insert(pair<Value*, int>(rep, idx)); return idx; } } it++; } return -1; }
bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { if (AA.doesNotAccessMemory(CS)) return false; for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { if (AA.getModRefInfo(getCallSite(i), CS) != AliasAnalysis::NoModRef || AA.getModRefInfo(CS, getCallSite(i)) != AliasAnalysis::NoModRef) return true; } for (iterator I = begin(), E = end(); I != E; ++I) if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) != AliasAnalysis::NoModRef) return true; return false; }
bool AliasSet::aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const { if (!Inst->mayReadOrWriteMemory()) return false; for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { ImmutableCallSite C1(getUnknownInst(i)), C2(Inst); if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != MRI_NoModRef || AA.getModRefInfo(C2, C1) != MRI_NoModRef) return true; } for (iterator I = begin(), E = end(); I != E; ++I) if (AA.getModRefInfo(Inst, MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo())) != MRI_NoModRef) return true; return false; }
bool AliasSet::aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const { if (!Inst->mayReadOrWriteMemory()) return false; for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { CallSite C1 = getUnknownInst(i), C2 = Inst; if (!C1 || !C2 || AA.getModRefInfo(C1, C2) != AliasAnalysis::NoModRef || AA.getModRefInfo(C2, C1) != AliasAnalysis::NoModRef) return true; } for (iterator I = begin(), E = end(); I != E; ++I) if (AA.getModRefInfo(Inst, I.getPointer(), I.getSize()) != AliasAnalysis::NoModRef) return true; return false; }
bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { if (Function *F = CS.getCalledFunction()) if (AA.doesNotAccessMemory(F)) return false; if (AA.hasNoModRefInfoForCalls()) return true; for (unsigned i = 0, e = CallSites.size(); i != e; ++i) if (AA.getModRefInfo(CallSites[i], CS) != AliasAnalysis::NoModRef || AA.getModRefInfo(CS, CallSites[i]) != AliasAnalysis::NoModRef) return true; for (iterator I = begin(), E = end(); I != E; ++I) if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) != AliasAnalysis::NoModRef) return true; return false; }
ALocBits may_alias_part(const AliasAnalysis& aa, AliasClass acls, folly::Optional<T> proj, AliasClass any, ALocBits pessimistic) { if (proj) { if (auto meta = aa.find(*proj)) { return ALocBits{meta->conflicts}.set(meta->index); } assertx(acls.maybe(any)); return pessimistic; } return acls.maybe(any) ? pessimistic : ALocBits{}; }
/// aliasesPointer - If the specified pointer "may" (or must) alias one of the /// members in the set return the appropriate AliasResult. Otherwise return /// NoAlias. /// AliasResult AliasSet::aliasesPointer(const Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo, AliasAnalysis &AA) const { if (AliasAny) return MayAlias; if (Alias == SetMustAlias) { assert(UnknownInsts.empty() && "Illegal must alias set!"); // If this is a set of MustAliases, only check to see if the pointer aliases // SOME value in the set. PointerRec *SomePtr = getSomePointer(); assert(SomePtr && "Empty must-alias set??"); return AA.alias(MemoryLocation(SomePtr->getValue(), SomePtr->getSize(), SomePtr->getAAInfo()), MemoryLocation(Ptr, Size, AAInfo)); } // If this is a may-alias set, we have to check all of the pointers in the set // to be sure it doesn't alias the set... for (iterator I = begin(), E = end(); I != E; ++I) if (AliasResult AR = AA.alias( MemoryLocation(Ptr, Size, AAInfo), MemoryLocation(I.getPointer(), I.getSize(), I.getAAInfo()))) return AR; // Check the unknown instructions... if (!UnknownInsts.empty()) { for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) if (auto *Inst = getUnknownInst(i)) if (isModOrRefSet( AA.getModRefInfo(Inst, MemoryLocation(Ptr, Size, AAInfo)))) return MayAlias; } return NoAlias; }
/// getLocForWrite - Return a Location stored to by the specified instruction. /// If isRemovable returns true, this function and getLocForRead completely /// describe the memory operations for this instruction. static AliasAnalysis::Location getLocForWrite(Instruction *Inst, AliasAnalysis &AA) { const DataLayout *DL = AA.getDataLayout(); if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) return AA.getLocation(SI); if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(Inst)) { // memcpy/memmove/memset. AliasAnalysis::Location Loc = AA.getLocationForDest(MI); // If we don't have target data around, an unknown size in Location means // that we should use the size of the pointee type. This isn't valid for // memset/memcpy, which writes more than an i8. if (Loc.Size == AliasAnalysis::UnknownSize && DL == nullptr) return AliasAnalysis::Location(); return Loc; } IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst); if (!II) return AliasAnalysis::Location(); switch (II->getIntrinsicID()) { default: return AliasAnalysis::Location(); // Unhandled intrinsic. case Intrinsic::init_trampoline: // If we don't have target data around, an unknown size in Location means // that we should use the size of the pointee type. This isn't valid for // init.trampoline, which writes more than an i8. if (!DL) return AliasAnalysis::Location(); // FIXME: We don't know the size of the trampoline, so we can't really // handle it here. return AliasAnalysis::Location(II->getArgOperand(0)); case Intrinsic::lifetime_end: { uint64_t Len = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(); return AliasAnalysis::Location(II->getArgOperand(1), Len); } } }
/// FoldSingleEntryPHINodes - We know that BB has one predecessor. If there are /// any single-entry PHI nodes in it, fold them away. This handles the case /// when all entries to the PHI nodes in a block are guaranteed equal, such as /// when the block has exactly one predecessor. void llvm::FoldSingleEntryPHINodes(BasicBlock *BB, Pass *P) { if (!isa<PHINode>(BB->begin())) return; AliasAnalysis *AA = 0; MemoryDependenceAnalysis *MemDep = 0; if (P) { AA = P->getAnalysisIfAvailable<AliasAnalysis>(); MemDep = P->getAnalysisIfAvailable<MemoryDependenceAnalysis>(); } while (PHINode *PN = dyn_cast<PHINode>(BB->begin())) { if (PN->getIncomingValue(0) != PN) PN->replaceAllUsesWith(PN->getIncomingValue(0)); else PN->replaceAllUsesWith(UndefValue::get(PN->getType())); if (MemDep) MemDep->removeInstruction(PN); // Memdep updates AA itself. else if (AA && isa<PointerType>(PN->getType())) AA->deleteValue(PN); PN->eraseFromParent(); } }
ALocBits expand_part(const AliasAnalysis& aa, AliasClass acls, folly::Optional<T> proj, AliasClass any, ALocBits all) { auto ret = ALocBits{}; if (proj) { if (auto const meta = aa.find(*proj)) { return ret.set(meta->index); // A single tracked location. } assertx(acls.maybe(any)); return ret; } return any <= acls ? all : ret; }
void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) { CallSites.push_back(CS.getInstruction()); AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS); if (Behavior == AliasAnalysis::DoesNotAccessMemory) return; if (AliasAnalysis::onlyReadsMemory(Behavior)) { AliasTy = MayAlias; AccessTy |= Refs; return; } // FIXME: This should use mod/ref information to make this not suck so bad AliasTy = MayAlias; AccessTy = ModRef; }
static uint64_t getPointerSize(Value *V, AliasAnalysis &AA) { const TargetData *TD = AA.getTargetData(); if (TD == 0) return AliasAnalysis::UnknownSize; if (AllocaInst *A = dyn_cast<AllocaInst>(V)) { // Get size information for the alloca if (ConstantInt *C = dyn_cast<ConstantInt>(A->getArraySize())) return C->getZExtValue() * TD->getTypeAllocSize(A->getAllocatedType()); return AliasAnalysis::UnknownSize; } assert(isa<Argument>(V) && "Expected AllocaInst or Argument!"); const PointerType *PT = cast<PointerType>(V->getType()); return TD->getTypeAllocSize(PT->getElementType()); }
static uint64_t getPointerSize(const Value *V, AliasAnalysis &AA) { const TargetData *TD = AA.getTargetData(); if (const CallInst *CI = extractMallocCall(V)) { if (const ConstantInt *C = dyn_cast<ConstantInt>(CI->getArgOperand(0))) return C->getZExtValue(); } if (const CallInst *CI = extractCallocCall(V)) { if (const ConstantInt *C1 = dyn_cast<ConstantInt>(CI->getArgOperand(0))) if (const ConstantInt *C2 = dyn_cast<ConstantInt>(CI->getArgOperand(1))) return (C1->getValue() * C2->getValue()).getZExtValue(); } if (TD == 0) return AliasAnalysis::UnknownSize; if (const AllocaInst *A = dyn_cast<AllocaInst>(V)) { // Get size information for the alloca if (const ConstantInt *C = dyn_cast<ConstantInt>(A->getArraySize())) return C->getZExtValue() * TD->getTypeAllocSize(A->getAllocatedType()); } if (const Argument *A = dyn_cast<Argument>(V)) { if (A->hasByValAttr()) if (PointerType *PT = dyn_cast<PointerType>(A->getType())) return TD->getTypeAllocSize(PT->getElementType()); } if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { if (!GV->mayBeOverridden()) return TD->getTypeAllocSize(GV->getType()->getElementType()); } return AliasAnalysis::UnknownSize; }
bool runOnFunction(Function &F) override { AliasAnalysis AA = getAnalysis<AliasAnalysis>(); DependenceAnalysis *DA = &(getAnalysis<DependenceAnalysis>()); // iterate over basic blocks Function *func = &F; unsigned bb_num = 0; for (Function::iterator BB = func->begin(), BE = func->end(); BB != BE; ++BB) { errs() << "BB-" << bb_num << "\n"; bb_num++; // iterator over instructions unsigned inst_num = 0; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;++I) { Instruction *Ins = dyn_cast<Instruction>(I); if (!Ins) return false; LoadInst *Ld = dyn_cast<LoadInst>(I); StoreInst *St = dyn_cast<StoreInst>(I); if (!St && !Ld) continue; if (Ld && !Ld->isSimple()) return false; if (St && !St->isSimple()) return false; inst_num++; MemInstr.push_back(&*I); errs() << "MemInst-" << inst_num << ":" << *I << "\n"; } ValueVector::iterator I, IE, J, JE; for (I = MemInstr.begin(), IE = MemInstr.end(); I != IE; ++I) { for (J = I, JE = MemInstr.end(); J != JE; ++J) { std::vector<char> Dep; Instruction *Src = dyn_cast<Instruction>(*I); Instruction *Des = dyn_cast<Instruction>(*J); if (Src == Des) continue; if (isa<LoadInst>(Src) && isa<LoadInst>(Des)) continue; if (auto D = DA->depends(Src, Des, true)) { errs() << "Found Dependency between:\nSrc:" << *Src << "\nDes:" << *Des << "\n"; if (D->isFlow()) { errs () << "Flow dependence not handled"; return false; } if (D->isAnti()) { errs() << "Found Anti dependence \n"; AliasAnalysis::AliasResult AA_dep = AA.alias(Src, Des); AliasAnalysis::AliasResult AA_dep_1 = AA.alias(Des, Src); errs() << "The Ld->St alias result is " << AA_dep << "\n"; errs() << "The St->Ld alias result is " << AA_dep_1 << "\n"; unsigned Levels = D->getLevels(); errs() << "levels = " << Levels << "\n"; char Direction; for (unsigned II = 1; II <= Levels; ++II) { const SCEV *Distance = D->getDistance(II); const SCEVConstant *SCEVConst = dyn_cast_or_null<SCEVConstant>(Distance); if (SCEVConst) { const ConstantInt *CI = SCEVConst->getValue(); //int64_t it_dist = CI->getUniqueInteger().getSExtValue(); //int it_dist = CI->getUniqueInteger().getSExtValue(); unsigned it_dist = abs(CI->getUniqueInteger().getSExtValue()); errs() << "distance is not null\n"; //errs() << "distance = "<< *CI << "\n"; errs() << "distance = "<< it_dist << "\n"; if (CI->isNegative()) Direction = '<'; else if (CI->isZero()) Direction = '='; else Direction = '>'; Dep.push_back(Direction); } else if (D->isScalar(II)) { Direction = 'S'; Dep.push_back(Direction); } else { unsigned Dir = D->getDirection(II); if (Dir == Dependence::DVEntry::LT || Dir == Dependence::DVEntry::LE) Direction = '<'; else if (Dir == Dependence::DVEntry::GT || Dir == Dependence::DVEntry::GE) Direction = '>'; else if (Dir == Dependence::DVEntry::EQ) Direction = '='; else Direction = '*'; Dep.push_back(Direction); } } } } } } } errs() << "------Hello World!--------\n"; return false; }
/// SplitBlockPredecessors - This method transforms BB by introducing a new /// basic block into the function, and moving some of the predecessors of BB to /// be predecessors of the new block. The new predecessors are indicated by the /// Preds array, which has NumPreds elements in it. The new block is given a /// suffix of 'Suffix'. /// /// This currently updates the LLVM IR, AliasAnalysis, DominatorTree and /// DominanceFrontier, but no other analyses. BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds, unsigned NumPreds, const char *Suffix, Pass *P) { // Create new basic block, insert right before the original block. BasicBlock *NewBB = BasicBlock::Create(BB->getName()+Suffix, BB->getParent(), BB); // The new block unconditionally branches to the old block. BranchInst *BI = BranchInst::Create(BB, NewBB); // Move the edges from Preds to point to NewBB instead of BB. for (unsigned i = 0; i != NumPreds; ++i) Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB); // Update dominator tree and dominator frontier if available. DominatorTree *DT = P ? P->getAnalysisIfAvailable<DominatorTree>() : 0; if (DT) DT->splitBlock(NewBB); if (DominanceFrontier *DF = P ? P->getAnalysisIfAvailable<DominanceFrontier>():0) DF->splitBlock(NewBB); AliasAnalysis *AA = P ? P->getAnalysisIfAvailable<AliasAnalysis>() : 0; // Insert a new PHI node into NewBB for every PHI node in BB and that new PHI // node becomes an incoming value for BB's phi node. However, if the Preds // list is empty, we need to insert dummy entries into the PHI nodes in BB to // account for the newly created predecessor. if (NumPreds == 0) { // Insert dummy values as the incoming value. for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ++I) cast<PHINode>(I)->addIncoming(UndefValue::get(I->getType()), NewBB); return NewBB; } // Otherwise, create a new PHI node in NewBB for each PHI node in BB. for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ) { PHINode *PN = cast<PHINode>(I++); // Check to see if all of the values coming in are the same. If so, we // don't need to create a new PHI node. Value *InVal = PN->getIncomingValueForBlock(Preds[0]); for (unsigned i = 1; i != NumPreds; ++i) if (InVal != PN->getIncomingValueForBlock(Preds[i])) { InVal = 0; break; } if (InVal) { // If all incoming values for the new PHI would be the same, just don't // make a new PHI. Instead, just remove the incoming values from the old // PHI. for (unsigned i = 0; i != NumPreds; ++i) PN->removeIncomingValue(Preds[i], false); } else { // If the values coming into the block are not the same, we need a PHI. // Create the new PHI node, insert it into NewBB at the end of the block PHINode *NewPHI = PHINode::Create(PN->getType(), PN->getName()+".ph", BI); if (AA) AA->copyValue(PN, NewPHI); // Move all of the PHI values for 'Preds' to the new PHI. for (unsigned i = 0; i != NumPreds; ++i) { Value *V = PN->removeIncomingValue(Preds[i], false); NewPHI->addIncoming(V, Preds[i]); } InVal = NewPHI; } // Add an incoming value to the PHI node in the loop for the preheader // edge. PN->addIncoming(InVal, NewBB); // Check to see if we can eliminate this phi node. if (Value *V = PN->hasConstantValue(DT != 0)) { Instruction *I = dyn_cast<Instruction>(V); if (!I || DT == 0 || DT->dominates(I, PN)) { PN->replaceAllUsesWith(V); if (AA) AA->deleteValue(PN); PN->eraseFromParent(); } } } return NewBB; }
/// isCompleteOverwrite - Return true if a store to the 'Later' location /// completely overwrites a store to the 'Earlier' location. static bool isCompleteOverwrite(const AliasAnalysis::Location &Later, const AliasAnalysis::Location &Earlier, AliasAnalysis &AA) { const Value *P1 = Earlier.Ptr->stripPointerCasts(); const Value *P2 = Later.Ptr->stripPointerCasts(); // If the start pointers are the same, we just have to compare sizes to see if // the later store was larger than the earlier store. if (P1 == P2) { // If we don't know the sizes of either access, then we can't do a // comparison. if (Later.Size == AliasAnalysis::UnknownSize || Earlier.Size == AliasAnalysis::UnknownSize) { // If we have no TargetData information around, then the size of the store // is inferrable from the pointee type. If they are the same type, then // we know that the store is safe. if (AA.getTargetData() == 0) return Later.Ptr->getType() == Earlier.Ptr->getType(); return false; } // Make sure that the Later size is >= the Earlier size. if (Later.Size < Earlier.Size) return false; return true; } // Otherwise, we have to have size information, and the later store has to be // larger than the earlier one. if (Later.Size == AliasAnalysis::UnknownSize || Earlier.Size == AliasAnalysis::UnknownSize || Later.Size <= Earlier.Size || AA.getTargetData() == 0) return false; // Check to see if the later store is to the entire object (either a global, // an alloca, or a byval argument). If so, then it clearly overwrites any // other store to the same object. const TargetData &TD = *AA.getTargetData(); const Value *UO1 = P1->getUnderlyingObject(), *UO2 = P2->getUnderlyingObject(); // If we can't resolve the same pointers to the same object, then we can't // analyze them at all. if (UO1 != UO2) return false; // If the "Later" store is to a recognizable object, get its size. if (isObjectPointerWithTrustworthySize(UO2)) { uint64_t ObjectSize = TD.getTypeAllocSize(cast<PointerType>(UO2->getType())->getElementType()); if (ObjectSize == Later.Size) return true; } // Okay, we have stores to two completely different pointers. Try to // decompose the pointer into a "base + constant_offset" form. If the base // pointers are equal, then we can reason about the two stores. int64_t Off1 = 0, Off2 = 0; const Value *BP1 = GetPointerBaseWithConstantOffset(P1, Off1, TD); const Value *BP2 = GetPointerBaseWithConstantOffset(P2, Off2, TD); // If the base pointers still differ, we have two completely different stores. if (BP1 != BP2) return false; // Otherwise, we might have a situation like: // store i16 -> P + 1 Byte // store i32 -> P // In this case, we see if the later store completely overlaps all bytes // stored by the previous store. if (Off1 < Off2 || // Earlier starts before Later. Off1+Earlier.Size > Off2+Later.Size) // Earlier goes beyond Later. return false; // Otherwise, we have complete overlap. return true; }
/// SplitBlockPredecessors - This method transforms BB by introducing a new /// basic block into the function, and moving some of the predecessors of BB to /// be predecessors of the new block. The new predecessors are indicated by the /// Preds array, which has NumPreds elements in it. The new block is given a /// suffix of 'Suffix'. /// /// This currently updates the LLVM IR, AliasAnalysis, DominatorTree, /// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. /// In particular, it does not preserve LoopSimplify (because it's /// complicated to handle the case where one of the edges being split /// is an exit of a loop with other exits). /// BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds, unsigned NumPreds, const char *Suffix, Pass *P) { // Create new basic block, insert right before the original block. BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), BB->getName()+Suffix, BB->getParent(), BB); // The new block unconditionally branches to the old block. BranchInst *BI = BranchInst::Create(BB, NewBB); LoopInfo *LI = P ? P->getAnalysisIfAvailable<LoopInfo>() : 0; Loop *L = LI ? LI->getLoopFor(BB) : 0; bool PreserveLCSSA = P->mustPreserveAnalysisID(LCSSAID); // Move the edges from Preds to point to NewBB instead of BB. // While here, if we need to preserve loop analyses, collect // some information about how this split will affect loops. bool HasLoopExit = false; bool IsLoopEntry = !!L; bool SplitMakesNewLoopHeader = false; for (unsigned i = 0; i != NumPreds; ++i) { // This is slightly more strict than necessary; the minimum requirement // is that there be no more than one indirectbr branching to BB. And // all BlockAddress uses would need to be updated. assert(!isa<IndirectBrInst>(Preds[i]->getTerminator()) && "Cannot split an edge from an IndirectBrInst"); Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB); if (LI) { // If we need to preserve LCSSA, determine if any of // the preds is a loop exit. if (PreserveLCSSA) if (Loop *PL = LI->getLoopFor(Preds[i])) if (!PL->contains(BB)) HasLoopExit = true; // If we need to preserve LoopInfo, note whether any of the // preds crosses an interesting loop boundary. if (L) { if (L->contains(Preds[i])) IsLoopEntry = false; else SplitMakesNewLoopHeader = true; } } } // Update dominator tree and dominator frontier if available. DominatorTree *DT = P ? P->getAnalysisIfAvailable<DominatorTree>() : 0; if (DT) DT->splitBlock(NewBB); if (DominanceFrontier *DF = P ? P->getAnalysisIfAvailable<DominanceFrontier>():0) DF->splitBlock(NewBB); // Insert a new PHI node into NewBB for every PHI node in BB and that new PHI // node becomes an incoming value for BB's phi node. However, if the Preds // list is empty, we need to insert dummy entries into the PHI nodes in BB to // account for the newly created predecessor. if (NumPreds == 0) { // Insert dummy values as the incoming value. for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ++I) cast<PHINode>(I)->addIncoming(UndefValue::get(I->getType()), NewBB); return NewBB; } AliasAnalysis *AA = P ? P->getAnalysisIfAvailable<AliasAnalysis>() : 0; if (L) { if (IsLoopEntry) { // Add the new block to the nearest enclosing loop (and not an // adjacent loop). To find this, examine each of the predecessors and // determine which loops enclose them, and select the most-nested loop // which contains the loop containing the block being split. Loop *InnermostPredLoop = 0; for (unsigned i = 0; i != NumPreds; ++i) if (Loop *PredLoop = LI->getLoopFor(Preds[i])) { // Seek a loop which actually contains the block being split (to // avoid adjacent loops). while (PredLoop && !PredLoop->contains(BB)) PredLoop = PredLoop->getParentLoop(); // Select the most-nested of these loops which contains the block. if (PredLoop && PredLoop->contains(BB) && (!InnermostPredLoop || InnermostPredLoop->getLoopDepth() < PredLoop->getLoopDepth())) InnermostPredLoop = PredLoop; } if (InnermostPredLoop) InnermostPredLoop->addBasicBlockToLoop(NewBB, LI->getBase()); } else { L->addBasicBlockToLoop(NewBB, LI->getBase()); if (SplitMakesNewLoopHeader) L->moveToHeader(NewBB); } } // Otherwise, create a new PHI node in NewBB for each PHI node in BB. for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ) { PHINode *PN = cast<PHINode>(I++); // Check to see if all of the values coming in are the same. If so, we // don't need to create a new PHI node, unless it's needed for LCSSA. Value *InVal = 0; if (!HasLoopExit) { InVal = PN->getIncomingValueForBlock(Preds[0]); for (unsigned i = 1; i != NumPreds; ++i) if (InVal != PN->getIncomingValueForBlock(Preds[i])) { InVal = 0; break; } } if (InVal) { // If all incoming values for the new PHI would be the same, just don't // make a new PHI. Instead, just remove the incoming values from the old // PHI. for (unsigned i = 0; i != NumPreds; ++i) PN->removeIncomingValue(Preds[i], false); } else { // If the values coming into the block are not the same, we need a PHI. // Create the new PHI node, insert it into NewBB at the end of the block PHINode *NewPHI = PHINode::Create(PN->getType(), PN->getName()+".ph", BI); if (AA) AA->copyValue(PN, NewPHI); // Move all of the PHI values for 'Preds' to the new PHI. for (unsigned i = 0; i != NumPreds; ++i) { Value *V = PN->removeIncomingValue(Preds[i], false); NewPHI->addIncoming(V, Preds[i]); } InVal = NewPHI; } // Add an incoming value to the PHI node in the loop for the preheader // edge. PN->addIncoming(InVal, NewBB); } return NewBB; }
/// isOverwrite - Return 'OverwriteComplete' if a store to the 'Later' location /// completely overwrites a store to the 'Earlier' location. /// 'OverwriteEnd' if the end of the 'Earlier' location is completely /// overwritten by 'Later', or 'OverwriteUnknown' if nothing can be determined static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, const AliasAnalysis::Location &Earlier, AliasAnalysis &AA, int64_t &EarlierOff, int64_t &LaterOff) { const DataLayout *DL = AA.getDataLayout(); const Value *P1 = Earlier.Ptr->stripPointerCasts(); const Value *P2 = Later.Ptr->stripPointerCasts(); // If the start pointers are the same, we just have to compare sizes to see if // the later store was larger than the earlier store. if (P1 == P2) { // If we don't know the sizes of either access, then we can't do a // comparison. if (Later.Size == AliasAnalysis::UnknownSize || Earlier.Size == AliasAnalysis::UnknownSize) return OverwriteUnknown; // Make sure that the Later size is >= the Earlier size. if (Later.Size >= Earlier.Size) return OverwriteComplete; } // Otherwise, we have to have size information, and the later store has to be // larger than the earlier one. if (Later.Size == AliasAnalysis::UnknownSize || Earlier.Size == AliasAnalysis::UnknownSize || DL == nullptr) return OverwriteUnknown; // Check to see if the later store is to the entire object (either a global, // an alloca, or a byval/inalloca argument). If so, then it clearly // overwrites any other store to the same object. const Value *UO1 = GetUnderlyingObject(P1, DL), *UO2 = GetUnderlyingObject(P2, DL); // If we can't resolve the same pointers to the same object, then we can't // analyze them at all. if (UO1 != UO2) return OverwriteUnknown; // If the "Later" store is to a recognizable object, get its size. uint64_t ObjectSize = getPointerSize(UO2, AA); if (ObjectSize != AliasAnalysis::UnknownSize) if (ObjectSize == Later.Size && ObjectSize >= Earlier.Size) return OverwriteComplete; // Okay, we have stores to two completely different pointers. Try to // decompose the pointer into a "base + constant_offset" form. If the base // pointers are equal, then we can reason about the two stores. EarlierOff = 0; LaterOff = 0; const Value *BP1 = GetPointerBaseWithConstantOffset(P1, EarlierOff, DL); const Value *BP2 = GetPointerBaseWithConstantOffset(P2, LaterOff, DL); // If the base pointers still differ, we have two completely different stores. if (BP1 != BP2) return OverwriteUnknown; // The later store completely overlaps the earlier store if: // // 1. Both start at the same offset and the later one's size is greater than // or equal to the earlier one's, or // // |--earlier--| // |-- later --| // // 2. The earlier store has an offset greater than the later offset, but which // still lies completely within the later store. // // |--earlier--| // |----- later ------| // // We have to be careful here as *Off is signed while *.Size is unsigned. if (EarlierOff >= LaterOff && Later.Size >= Earlier.Size && uint64_t(EarlierOff - LaterOff) + Earlier.Size <= Later.Size) return OverwriteComplete; // The other interesting case is if the later store overwrites the end of // the earlier store // // |--earlier--| // |-- later --| // // In this case we may want to trim the size of earlier to avoid generating // writes to addresses which will definitely be overwritten later if (LaterOff > EarlierOff && LaterOff < int64_t(EarlierOff + Earlier.Size) && int64_t(LaterOff + Later.Size) >= int64_t(EarlierOff + Earlier.Size)) return OverwriteEnd; // Otherwise, they don't completely overlap. return OverwriteUnknown; }
static uint64_t getPointerSize(const Value *V, AliasAnalysis &AA) { uint64_t Size; if (getObjectSize(V, Size, AA.getDataLayout(), AA.getTargetLibraryInfo())) return Size; return AliasAnalysis::UnknownSize; }
void DataDependence::processDepResult(Instruction *inst, MemoryDependenceAnalysis &MDA, AliasAnalysis &AA) { // TODO: This is probably a good place to check of the dependency // information is calculated on-demand MemDepResult Res = MDA.getDependency(inst); if (!Res.isNonLocal()) { // local results (not-non-local) can be simply handled. They are just // a pair of insturctions and a dependency type // Get dependency information DepInfo newInfo; newInfo = getDepInfo(Res); #ifdef MK_DEBUG //errs() << "[DEBUG] newInfo depInst == " << Res.getInst() << '\n'; if (Res.getInst() == NULL) { errs() << "[DEBUG] NULL dependency found, dep type: " << depTypeToString(newInfo.Type_) << '\n'; } #endif // Save into map assert(newInfo.valid()); LocalDeps_[inst] = newInfo; } else { // Handle NonLocal dependencies. The function call // getNonLocalPointerDependency() assumes that a result of NonLocal // has already been encountered // Get dependency information DepInfo newInfo; newInfo = getDepInfo(Res); assert(newInfo.Type_ == NonLocal); assert(Res.isNonLocal()); SmallVector<NonLocalDepResult, 4> NLDep; if (LoadInst *LI = dyn_cast<LoadInst>(inst)) { if (!LI->isUnordered()) { // FIXME: Handle atomic/volatile loads. errs() << "[WARNING] atomic/volatile loads are not handled\n"; assert(false && "atomic/volatile loads not handled"); //Deps[Inst].insert(std::make_pair(getInstTypePair(0, Unknown), //static_cast<BasicBlock *>(0))); return; } AliasAnalysis::Location Loc = AA.getLocation(LI); MDA.getNonLocalPointerDependency(Loc, true, LI->getParent(), NLDep); } else if (StoreInst *SI = dyn_cast<StoreInst>(inst)) { if (!SI->isUnordered()) { // FIXME: Handle atomic/volatile stores. errs() << "[WARNING] atomic/volatile stores are not handled\n"; assert(false && "atomic/volatile stores not handled"); //Deps[Inst].insert(std::make_pair(getInstTypePair(0, Unknown), //static_cast<BasicBlock *>(0))); return; } AliasAnalysis::Location Loc = AA.getLocation(SI); MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDep); } else if (VAArgInst *VI = dyn_cast<VAArgInst>(inst)) { AliasAnalysis::Location Loc = AA.getLocation(VI); MDA.getNonLocalPointerDependency(Loc, false, VI->getParent(), NLDep); } else { llvm_unreachable("Unknown memory instruction!"); } #ifdef MK_DEBUG errs() << "[DEBUG] NLDep.size() == " << NLDep.size() << '\n'; #endif for (auto I = NLDep.begin(), E = NLDep.end(); I != E; ++I) { NonLocalDeps_[inst].push_back(*I); } } // end else }
void Transformer4Trace::beforeTransform(Module* module, AliasAnalysis& AA) { // do not remove it, it is used in the macro ptrsize = AA.getDataLayout()->getPointerSize(); ///initialize functions // do not remove context, it is used in the macro FUNCTION_ARG_TYPE Module * m = module; LLVMContext& context = m->getContext(); F_init = cast<Function>(m->getOrInsertFunction("OnInit", FUNCTION_VOID_ARG_TYPE)); F_exit = cast<Function>(m->getOrInsertFunction("OnExit", FUNCTION_VOID_ARG_TYPE)); //F_thread_init = cast<Function>(m->getOrInsertFunction("OnThreadInit", FUNCTION_ARG_TYPE)); //F_thread_exit = cast<Function>(m->getOrInsertFunction("OnThreadExit", FUNCTION_ARG_TYPE)); F_preload = cast<Function>(m->getOrInsertFunction("OnPreLoad", FUNCTION_MEM_LN_ARG_TYPE)); F_load = cast<Function>(m->getOrInsertFunction("OnLoad", FUNCTION_MEM_LN_ARG_TYPE)); F_prestore = cast<Function>(m->getOrInsertFunction("OnPreStore", FUNCTION_MEM_LN_ARG_TYPE)); F_store = cast<Function>(m->getOrInsertFunction("OnStore", FUNCTION_MEM_LN_ARG_TYPE)); F_prelock = cast<Function>(m->getOrInsertFunction("OnPreLock", FUNCTION_MEM_LN_ARG_TYPE)); F_lock = cast<Function>(m->getOrInsertFunction("OnLock", FUNCTION_MEM_LN_ARG_TYPE)); F_preunlock = cast<Function>(m->getOrInsertFunction("OnPreUnlock", FUNCTION_MEM_LN_ARG_TYPE)); F_unlock = cast<Function>(m->getOrInsertFunction("OnUnlock", FUNCTION_MEM_LN_ARG_TYPE)); F_prefork = cast<Function>(m->getOrInsertFunction("OnPreFork", FUNCTION_MEM_LN_ARG_TYPE)); F_fork = cast<Function>(m->getOrInsertFunction("OnFork", FUNCTION_MEM_LN_ARG_TYPE)); F_prejoin = cast<Function>(m->getOrInsertFunction("OnPreJoin", FUNCTION_TID_LN_ARG_TYPE)); F_join = cast<Function>(m->getOrInsertFunction("OnJoin", FUNCTION_TID_LN_ARG_TYPE)); F_prenotify = cast<Function>(m->getOrInsertFunction("OnPreNotify", FUNCTION_2MEM_LN_ARG_TYPE)); F_notify = cast<Function>(m->getOrInsertFunction("OnNotify", FUNCTION_2MEM_LN_ARG_TYPE)); F_prewait = cast<Function>(m->getOrInsertFunction("OnPreWait", FUNCTION_2MEM_LN_ARG_TYPE)); F_wait = cast<Function>(m->getOrInsertFunction("OnWait", FUNCTION_2MEM_LN_ARG_TYPE)); if (debug()) { errs() << "Start Preprocessing...\n"; errs().flush(); } for (ilist_iterator<Function> iterF = module->getFunctionList().begin(); iterF != module->getFunctionList().end(); iterF++) { Function& f = *iterF; bool ignored = true; for (ilist_iterator<BasicBlock> iterB = f.getBasicBlockList().begin(); iterB != f.getBasicBlockList().end(); iterB++) { BasicBlock &b = *iterB; for (ilist_iterator<Instruction> iterI = b.getInstList().begin(); iterI != b.getInstList().end(); iterI++) { Instruction &inst = *iterI; // std::string &filename=getInstructionFileName(&inst) ; // unsigned ln = LOC.getLineNumber(); // errs() << inst << "\n"; // errs() << f.getName() << "\n"; // errs() << filename; // errs() << " : " << ln << "\n"; // errs() <<"************************"<< "\n"; // errs().flush(); //if (filename == "pbzip2.cpp") { ignored = false; break; //} } if (!ignored) { break; } } if (ignored) { ignored_funcs.insert(&f); } } if (debug()) { errs() << "End Preprocessing...\n"; errs().flush(); } }