void GraphBuilder::visitLoadInst(LoadInst &LI) { // // Create a DSNode for the pointer dereferenced by the load. If the DSNode // is NULL, do nothing more (this can occur if the load is loading from a // NULL pointer constant (bugpoint can generate such code). // DSNodeHandle Ptr = getValueDest(LI.getPointerOperand()); if (Ptr.isNull()) return; // Load from null // Make that the node is read from... Ptr.getNode()->setReadMarker(); // Ensure a typerecord exists... Ptr.getNode()->growSizeForType(LI.getType(), Ptr.getOffset()); if (isa<PointerType>(LI.getType())) setDestTo(LI, getLink(Ptr)); // check that it is the inserted value if(TypeInferenceOptimize) if(LI.hasOneUse()) if(StoreInst *SI = dyn_cast<StoreInst>(*(LI.use_begin()))) if(SI->getOperand(0) == &LI) { ++NumIgnoredInst; return; } Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset()); }
/// RewriteSingleStoreAlloca - If there is only a single store to this value, /// replace any loads of it that are directly dominated by the definition with /// the value stored. void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI) { StoreInst *OnlyStore = Info.OnlyStore; bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0)); BasicBlock *StoreBB = OnlyStore->getParent(); int StoreIndex = -1; // Clear out UsingBlocks. We will reconstruct it here if needed. Info.UsingBlocks.clear(); for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E; ) { Instruction *UserInst = cast<Instruction>(*UI++); if (!isa<LoadInst>(UserInst)) { assert(UserInst == OnlyStore && "Should only have load/stores"); continue; } LoadInst *LI = cast<LoadInst>(UserInst); // Okay, if we have a load from the alloca, we want to replace it with the // only value stored to the alloca. We can do this if the value is // dominated by the store. If not, we use the rest of the mem2reg machinery // to insert the phi nodes as needed. if (!StoringGlobalVal) { // Non-instructions are always dominated. if (LI->getParent() == StoreBB) { // If we have a use that is in the same block as the store, compare the // indices of the two instructions to see which one came first. If the // load came before the store, we can't handle it. if (StoreIndex == -1) StoreIndex = LBI.getInstructionIndex(OnlyStore); if (unsigned(StoreIndex) > LBI.getInstructionIndex(LI)) { // Can't handle this load, bail out. Info.UsingBlocks.push_back(StoreBB); continue; } } else if (LI->getParent() != StoreBB && !dominates(StoreBB, LI->getParent())) { // If the load and store are in different blocks, use BB dominance to // check their relationships. If the store doesn't dom the use, bail // out. Info.UsingBlocks.push_back(LI->getParent()); continue; } } // Otherwise, we *can* safely rewrite this load. Value *ReplVal = OnlyStore->getOperand(0); // If the replacement value is the load, this must occur in unreachable // code. if (ReplVal == LI) ReplVal = UndefValue::get(LI->getType()); LI->replaceAllUsesWith(ReplVal); if (AST && LI->getType()->isPointerTy()) AST->deleteValue(LI); LI->eraseFromParent(); LBI.deleteValue(LI); } }
/// MoveExtToFormExtLoad - Move a zext or sext fed by a load into the same /// basic block as the load, unless conditions are unfavorable. This allows /// SelectionDAG to fold the extend into the load. /// bool CodeGenPrepare::MoveExtToFormExtLoad(Instruction *I) { // Look for a load being extended. LoadInst *LI = dyn_cast<LoadInst>(I->getOperand(0)); if (!LI) return false; // If they're already in the same block, there's nothing to do. if (LI->getParent() == I->getParent()) return false; // If the load has other users and the truncate is not free, this probably // isn't worthwhile. if (!LI->hasOneUse() && TLI && (TLI->isTypeLegal(TLI->getValueType(LI->getType())) || !TLI->isTypeLegal(TLI->getValueType(I->getType()))) && !TLI->isTruncateFree(I->getType(), LI->getType())) return false; // Check whether the target supports casts folded into loads. unsigned LType; if (isa<ZExtInst>(I)) LType = ISD::ZEXTLOAD; else { assert(isa<SExtInst>(I) && "Unexpected ext type!"); LType = ISD::SEXTLOAD; } if (TLI && !TLI->isLoadExtLegal(LType, TLI->getValueType(LI->getType()))) return false; // Move the extend into the same block as the load, so that SelectionDAG // can fold it. I->removeFromParent(); I->insertAfter(LI); ++NumExtsMoved; return true; }
void InstrumentMemoryAccesses::visitLoadInst(LoadInst &LI) { // Instrument a load instruction with a load check. Value *AccessSize = ConstantInt::get(SizeTy, TD->getTypeStoreSize(LI.getType())); instrument(LI.getPointerOperand(), AccessSize, LoadCheckFunction, LI); ++LoadsInstrumented; }
void Interpreter::visitLoadInst(LoadInst &I) { ExecutionContext &SF = ECStack.back(); GenericValue SRC = getOperandValue(I.getPointerOperand(), SF); GenericValue *Ptr = (GenericValue*)GVTOP(SRC); GenericValue Result = LoadValueFromMemory(Ptr, I.getType()); SetValue(&I, Result, SF); }
bool AMDGPUCodeGenPrepare::visitLoadInst(LoadInst &I) { if (!WidenLoads) return false; if ((I.getPointerAddressSpace() == AMDGPUASI.CONSTANT_ADDRESS || I.getPointerAddressSpace() == AMDGPUASI.CONSTANT_ADDRESS_32BIT) && canWidenScalarExtLoad(I)) { IRBuilder<> Builder(&I); Builder.SetCurrentDebugLocation(I.getDebugLoc()); Type *I32Ty = Builder.getInt32Ty(); Type *PT = PointerType::get(I32Ty, I.getPointerAddressSpace()); Value *BitCast= Builder.CreateBitCast(I.getPointerOperand(), PT); LoadInst *WidenLoad = Builder.CreateLoad(BitCast); WidenLoad->copyMetadata(I); // If we have range metadata, we need to convert the type, and not make // assumptions about the high bits. if (auto *Range = WidenLoad->getMetadata(LLVMContext::MD_range)) { ConstantInt *Lower = mdconst::extract<ConstantInt>(Range->getOperand(0)); if (Lower->getValue().isNullValue()) { WidenLoad->setMetadata(LLVMContext::MD_range, nullptr); } else { Metadata *LowAndHigh[] = { ConstantAsMetadata::get(ConstantInt::get(I32Ty, Lower->getValue().zext(32))), // Don't make assumptions about the high bits. ConstantAsMetadata::get(ConstantInt::get(I32Ty, 0)) }; WidenLoad->setMetadata(LLVMContext::MD_range, MDNode::get(Mod->getContext(), LowAndHigh)); } } int TySize = Mod->getDataLayout().getTypeSizeInBits(I.getType()); Type *IntNTy = Builder.getIntNTy(TySize); Value *ValTrunc = Builder.CreateTrunc(WidenLoad, IntNTy); Value *ValOrig = Builder.CreateBitCast(ValTrunc, I.getType()); I.replaceAllUsesWith(ValOrig); I.eraseFromParent(); return true; } return false; }
void PropagateJuliaAddrspaces::visitLoadInst(LoadInst &LI) { unsigned AS = LI.getPointerAddressSpace(); if (!isSpecialAS(AS)) return; Value *Replacement = LiftPointer(LI.getPointerOperand(), LI.getType(), &LI); if (!Replacement) return; LI.setOperand(LoadInst::getPointerOperandIndex(), Replacement); }
bool AMDGPUCodeGenPrepare::canWidenScalarExtLoad(LoadInst &I) const { Type *Ty = I.getType(); const DataLayout &DL = Mod->getDataLayout(); int TySize = DL.getTypeSizeInBits(Ty); unsigned Align = I.getAlignment() ? I.getAlignment() : DL.getABITypeAlignment(Ty); return I.isSimple() && TySize < 32 && Align >= 4 && DA->isUniform(&I); }
void LLSTDebuggingPass::insertLoadInstCheck(Function& F) { Value* BrokenPointerMessage = m_builder->CreateGlobalStringPtr("\npointer is broken\n"); InstructionVector Loads; for (Function::iterator BB = F.begin(); BB != F.end(); ++BB) { for(BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) { if (LoadInst* Load = dyn_cast<LoadInst>(II)) { Loads.push_back(Load); } } } for(std::size_t i = 0; i < Loads.size(); i++) { LoadInst* Load = dyn_cast<LoadInst>(Loads[i]); if (belongsToSmalltalkType( Load->getType() )) { //split BB right after load inst. The new BB contains code that will be executed if pointer is OK BasicBlock* PointerIsOkBB = Load->getParent()->splitBasicBlock(++( static_cast<BasicBlock::iterator>(Load) )); BasicBlock* PointerIsBrokenBB = BasicBlock::Create(m_module->getContext(), "", &F, PointerIsOkBB); BasicBlock* PointerIsNotSmallIntBB = BasicBlock::Create(m_module->getContext(), "", &F, PointerIsBrokenBB); Instruction* branchToPointerIsOkBB = ++( static_cast<BasicBlock::iterator>(Load) ); //branchToPointerIsOkBB is created by splitBasicBlock() just after load inst //We force builder to insert instructions before branchToPointerIsOkBB m_builder->SetInsertPoint(branchToPointerIsOkBB); //If pointer to class is null, jump to PointerIsBroken, otherwise to PointerIsOkBB Value* objectPtr = m_builder->CreateBitCast( Load, m_baseTypes.object->getPointerTo()); Value* isSmallInt = m_builder->CreateCall(isSmallInteger, objectPtr); m_builder->CreateCondBr(isSmallInt, PointerIsOkBB, PointerIsNotSmallIntBB); m_builder->SetInsertPoint(PointerIsNotSmallIntBB); Value* klassPtr = m_builder->CreateCall(getObjectClass, objectPtr); Value* pointerIsNull = m_builder->CreateICmpEQ(klassPtr, ConstantPointerNull::get(m_baseTypes.klass->getPointerTo()) ); m_builder->CreateCondBr(pointerIsNull, PointerIsBrokenBB, PointerIsOkBB); branchToPointerIsOkBB->eraseFromParent(); //We don't need it anymore m_builder->SetInsertPoint(PointerIsBrokenBB); m_builder->CreateCall(_printf, BrokenPointerMessage); m_builder->CreateBr(PointerIsOkBB); } } }
void GCInvariantVerifier::visitLoadInst(LoadInst &LI) { Type *Ty = LI.getType(); if (Ty->isPointerTy()) { unsigned AS = cast<PointerType>(Ty)->getAddressSpace(); Check(AS != AddressSpace::CalleeRooted && AS != AddressSpace::Derived, "Illegal load of gc relevant value", &LI); } Ty = LI.getPointerOperand()->getType(); if (Ty->isPointerTy()) { unsigned AS = cast<PointerType>(Ty)->getAddressSpace(); Check(AS != AddressSpace::CalleeRooted, "Illegal store of callee rooted value", &LI); } }
bool IRTranslator::translateLoad(const LoadInst &LI) { assert(LI.isSimple() && "only simple loads are supported at the moment"); MachineFunction &MF = MIRBuilder.getMF(); unsigned Res = getOrCreateVReg(LI); unsigned Addr = getOrCreateVReg(*LI.getPointerOperand()); LLT VTy{*LI.getType()}, PTy{*LI.getPointerOperand()->getType()}; MIRBuilder.buildLoad( VTy, PTy, Res, Addr, *MF.getMachineMemOperand(MachinePointerInfo(LI.getPointerOperand()), MachineMemOperand::MOLoad, VTy.getSizeInBits() / 8, getMemOpAlignment(LI))); return true; }
void ArrayIndexChecker::visitLoadInst(LoadInst& I) { DEBUG(dbgs() << "ArrayIndexChecker: visiting load " << I << "\n"); visitValue(*I.getPointerOperand()); if (I.getType()->isPointerTy()) { auto pos = std::find(ptr_value_vec_.begin(), ptr_value_vec_.end(), &I); assert(pos != ptr_value_vec_.end()); index_t varIdx = pos - ptr_value_vec_.begin(); assert(idx2addr_.find(varIdx) != idx2addr_.end()); if (addr2version_[idx2addr_[varIdx]] != 0) throw ArrayIndexIsNotConstant; } DEBUG(dbgs() << "ArrayIndexChecker: visited load\n"); }
void TracingNoGiri::visitLoadInst(LoadInst &LI) { instrumentLock(&LI); // Get the ID of the load instruction. Value *LoadID = ConstantInt::get(Int32Type, lsNumPass->getID(&LI)); // Cast the pointer into a void pointer type. Value *Pointer = LI.getPointerOperand(); Pointer = castTo(Pointer, VoidPtrType, Pointer->getName(), &LI); // Get the size of the loaded data. uint64_t size = TD->getTypeStoreSize(LI.getType()); Value *LoadSize = ConstantInt::get(Int64Type, size); // Create the call to the run-time to record the load instruction. std::vector<Value *> args=make_vector<Value *>(LoadID, Pointer, LoadSize, 0); CallInst::Create(RecordLoad, args, "", &LI); instrumentUnlock(&LI); ++NumLoads; // Update statistics }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB) { BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end(); // Skip static allocas at the top of the entry block so they don't become // dynamic when we split the block. If we used our optimized stack layout, // then there will only be one alloca and it will come first. for (; IP != BE; ++IP) { AllocaInst *AI = dyn_cast<AllocaInst>(IP); if (!AI || !AI->isStaticAlloca()) break; } bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc = IsEntryBB ? IP->getDebugLoc().getFnDebugLoc(*C) : IP->getDebugLoc(); IRBuilder<> IRB(IP); IRB.SetCurrentDebugLocation(EntryLoc); SmallVector<Value *, 1> Indices; Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + SanCovFunction->getNumUses()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(Monotonic); Load->setAlignment(4); Load->setMetadata(F.getParent()->getMDKindID("nosanitize"), MDNode::get(*C, None)); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm); // Avoids callback merge. if (ClExperimentalTracing) { // Experimental support for tracing. // Insert a callback with the same guard variable as used for coverage. IRB.SetInsertPoint(IP); IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } }
void Closure::unpack_struct(Scope<Value *> &dst, Value *src, IRBuilder<> *builder) { // src should be a pointer to a struct of the type returned by build_type int idx = 0; LLVMContext &context = builder->getContext(); vector<string> nm = names(); for (size_t i = 0; i < nm.size(); i++) { Value *ptr = builder->CreateConstInBoundsGEP2_32(src, 0, idx++); LoadInst *load = builder->CreateLoad(ptr); if (load->getType()->isPointerTy()) { // Give it a unique type so that tbaa tells llvm that this can't alias anything load->setMetadata("tbaa", MDNode::get(context, vec<Value *>(MDString::get(context, nm[i])))); } dst.push(nm[i], load); load->setName(nm[i]); } }
/// Try to fold load I. bool UnrolledInstAnalyzer::visitLoad(LoadInst &I) { Value *AddrOp = I.getPointerOperand(); auto AddressIt = SimplifiedAddresses.find(AddrOp); if (AddressIt == SimplifiedAddresses.end()) return false; ConstantInt *SimplifiedAddrOp = AddressIt->second.Offset; auto *GV = dyn_cast<GlobalVariable>(AddressIt->second.Base); // We're only interested in loads that can be completely folded to a // constant. if (!GV || !GV->hasDefinitiveInitializer() || !GV->isConstant()) return false; ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(GV->getInitializer()); if (!CDS) return false; // We might have a vector load from an array. FIXME: for now we just bail // out in this case, but we should be able to resolve and simplify such // loads. if(!CDS->isElementTypeCompatible(I.getType())) return false; int ElemSize = CDS->getElementType()->getPrimitiveSizeInBits() / 8U; if (SimplifiedAddrOp->getValue().getActiveBits() >= 64) return false; int64_t Index = SimplifiedAddrOp->getSExtValue() / ElemSize; if (Index >= CDS->getNumElements()) { // FIXME: For now we conservatively ignore out of bound accesses, but // we're allowed to perform the optimization in this case. return false; } Constant *CV = CDS->getElementAsConstant(Index); assert(CV && "Constant expected."); SimplifiedValues[&I] = CV; return true; }
bool Scalarizer::visitLoadInst(LoadInst &LI) { if (!ScalarizeLoadStore) return false; if (!LI.isSimple()) return false; VectorLayout Layout; if (!getVectorLayout(LI.getType(), LI.getAlignment(), Layout)) return false; unsigned NumElems = Layout.VecTy->getNumElements(); IRBuilder<> Builder(LI.getParent(), &LI); Scatterer Ptr = scatter(&LI, LI.getPointerOperand()); ValueVector Res; Res.resize(NumElems); for (unsigned I = 0; I < NumElems; ++I) Res[I] = Builder.CreateAlignedLoad(Ptr[I], Layout.getElemAlign(I), LI.getName() + ".i" + Twine(I)); gather(&LI, Res); return true; }
/// PromoteValuesInLoop - Try to promote memory values to scalars by sinking /// stores out of the loop and moving loads to before the loop. We do this by /// looping over the stores in the loop, looking for stores to Must pointers /// which are loop invariant. We promote these memory locations to use allocas /// instead. These allocas can easily be raised to register values by the /// PromoteMem2Reg functionality. /// void LICM::PromoteValuesInLoop() { // PromotedValues - List of values that are promoted out of the loop. Each // value has an alloca instruction for it, and a canonical version of the // pointer. std::vector<std::pair<AllocaInst*, Value*> > PromotedValues; std::map<Value*, AllocaInst*> ValueToAllocaMap; // Map of ptr to alloca FindPromotableValuesInLoop(PromotedValues, ValueToAllocaMap); if (ValueToAllocaMap.empty()) return; // If there are values to promote. Changed = true; NumPromoted += PromotedValues.size(); std::vector<Value*> PointerValueNumbers; // Emit a copy from the value into the alloca'd value in the loop preheader TerminatorInst *LoopPredInst = Preheader->getTerminator(); for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { Value *Ptr = PromotedValues[i].second; // If we are promoting a pointer value, update alias information for the // inserted load. Value *LoadValue = 0; if (isa<PointerType>(cast<PointerType>(Ptr->getType())->getElementType())) { // Locate a load or store through the pointer, and assign the same value // to LI as we are loading or storing. Since we know that the value is // stored in this loop, this will always succeed. for (Value::use_iterator UI = Ptr->use_begin(), E = Ptr->use_end(); UI != E; ++UI) if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) { LoadValue = LI; break; } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) { if (SI->getOperand(1) == Ptr) { LoadValue = SI->getOperand(0); break; } } assert(LoadValue && "No store through the pointer found!"); PointerValueNumbers.push_back(LoadValue); // Remember this for later. } // Load from the memory we are promoting. LoadInst *LI = new LoadInst(Ptr, Ptr->getName()+".promoted", LoopPredInst); if (LoadValue) CurAST->copyValue(LoadValue, LI); // Store into the temporary alloca. new StoreInst(LI, PromotedValues[i].first, LoopPredInst); } // Scan the basic blocks in the loop, replacing uses of our pointers with // uses of the allocas in question. // for (Loop::block_iterator I = CurLoop->block_begin(), E = CurLoop->block_end(); I != E; ++I) { BasicBlock *BB = *I; // Rewrite all loads and stores in the block of the pointer... for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E; ++II) { if (LoadInst *L = dyn_cast<LoadInst>(II)) { std::map<Value*, AllocaInst*>::iterator I = ValueToAllocaMap.find(L->getOperand(0)); if (I != ValueToAllocaMap.end()) L->setOperand(0, I->second); // Rewrite load instruction... } else if (StoreInst *S = dyn_cast<StoreInst>(II)) { std::map<Value*, AllocaInst*>::iterator I = ValueToAllocaMap.find(S->getOperand(1)); if (I != ValueToAllocaMap.end()) S->setOperand(1, I->second); // Rewrite store instruction... } } } // Now that the body of the loop uses the allocas instead of the original // memory locations, insert code to copy the alloca value back into the // original memory location on all exits from the loop. Note that we only // want to insert one copy of the code in each exit block, though the loop may // exit to the same block more than once. // SmallPtrSet<BasicBlock*, 16> ProcessedBlocks; SmallVector<BasicBlock*, 8> ExitBlocks; CurLoop->getExitBlocks(ExitBlocks); for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) { if (!ProcessedBlocks.insert(ExitBlocks[i])) continue; // Copy all of the allocas into their memory locations. BasicBlock::iterator BI = ExitBlocks[i]->getFirstNonPHI(); Instruction *InsertPos = BI; unsigned PVN = 0; for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) { // Load from the alloca. LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos); // If this is a pointer type, update alias info appropriately. if (isa<PointerType>(LI->getType())) CurAST->copyValue(PointerValueNumbers[PVN++], LI); // Store into the memory we promoted. new StoreInst(LI, PromotedValues[i].second, InsertPos); } } // Now that we have done the deed, use the mem2reg functionality to promote // all of the new allocas we just created into real SSA registers. // std::vector<AllocaInst*> PromotedAllocas; PromotedAllocas.reserve(PromotedValues.size()); for (unsigned i = 0, e = PromotedValues.size(); i != e; ++i) PromotedAllocas.push_back(PromotedValues[i].first); PromoteMemToReg(PromotedAllocas, *DT, *DF, CurAST); }
/// InstCombineLoadCast - Fold 'load (cast P)' -> cast (load P)' when possible. static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI, const DataLayout *DL) { User *CI = cast<User>(LI.getOperand(0)); Value *CastOp = CI->getOperand(0); PointerType *DestTy = cast<PointerType>(CI->getType()); Type *DestPTy = DestTy->getElementType(); if (PointerType *SrcTy = dyn_cast<PointerType>(CastOp->getType())) { // If the address spaces don't match, don't eliminate the cast. if (DestTy->getAddressSpace() != SrcTy->getAddressSpace()) return nullptr; Type *SrcPTy = SrcTy->getElementType(); if (DestPTy->isIntegerTy() || DestPTy->isPointerTy() || DestPTy->isVectorTy()) { // If the source is an array, the code below will not succeed. Check to // see if a trivial 'gep P, 0, 0' will help matters. Only do this for // constants. if (ArrayType *ASrcTy = dyn_cast<ArrayType>(SrcPTy)) if (Constant *CSrc = dyn_cast<Constant>(CastOp)) if (ASrcTy->getNumElements() != 0) { Type *IdxTy = DL ? DL->getIntPtrType(SrcTy) : Type::getInt64Ty(SrcTy->getContext()); Value *Idx = Constant::getNullValue(IdxTy); Value *Idxs[2] = { Idx, Idx }; CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs); SrcTy = cast<PointerType>(CastOp->getType()); SrcPTy = SrcTy->getElementType(); } if (IC.getDataLayout() && (SrcPTy->isIntegerTy() || SrcPTy->isPointerTy() || SrcPTy->isVectorTy()) && // Do not allow turning this into a load of an integer, which is then // casted to a pointer, this pessimizes pointer analysis a lot. (SrcPTy->isPtrOrPtrVectorTy() == LI.getType()->isPtrOrPtrVectorTy()) && IC.getDataLayout()->getTypeSizeInBits(SrcPTy) == IC.getDataLayout()->getTypeSizeInBits(DestPTy)) { // Okay, we are casting from one integer or pointer type to another of // the same size. Instead of casting the pointer before the load, cast // the result of the loaded value. LoadInst *NewLoad = IC.Builder->CreateLoad(CastOp, LI.isVolatile(), CI->getName()); NewLoad->setAlignment(LI.getAlignment()); NewLoad->setAtomic(LI.getOrdering(), LI.getSynchScope()); // Now cast the result of the load. PointerType *OldTy = dyn_cast<PointerType>(NewLoad->getType()); PointerType *NewTy = dyn_cast<PointerType>(LI.getType()); if (OldTy && NewTy && OldTy->getAddressSpace() != NewTy->getAddressSpace()) { return new AddrSpaceCastInst(NewLoad, LI.getType()); } return new BitCastInst(NewLoad, LI.getType()); } } } return nullptr; }
bool NVPTXLowerAggrCopies::runOnFunction(Function &F) { SmallVector<LoadInst *, 4> aggrLoads; SmallVector<MemTransferInst *, 4> aggrMemcpys; SmallVector<MemSetInst *, 4> aggrMemsets; DataLayout *TD = &getAnalysis<DataLayout>(); LLVMContext &Context = F.getParent()->getContext(); // // Collect all the aggrLoads, aggrMemcpys and addrMemsets. // //const BasicBlock *firstBB = &F.front(); // first BB in F for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { //BasicBlock *bb = BI; for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE; ++II) { if (LoadInst * load = dyn_cast<LoadInst>(II)) { if (load->hasOneUse() == false) continue; if (TD->getTypeStoreSize(load->getType()) < MaxAggrCopySize) continue; User *use = *(load->use_begin()); if (StoreInst * store = dyn_cast<StoreInst>(use)) { if (store->getOperand(0) != load) //getValueOperand continue; aggrLoads.push_back(load); } } else if (MemTransferInst * intr = dyn_cast<MemTransferInst>(II)) { Value *len = intr->getLength(); // If the number of elements being copied is greater // than MaxAggrCopySize, lower it to a loop if (ConstantInt * len_int = dyn_cast < ConstantInt > (len)) { if (len_int->getZExtValue() >= MaxAggrCopySize) { aggrMemcpys.push_back(intr); } } else { // turn variable length memcpy/memmov into loop aggrMemcpys.push_back(intr); } } else if (MemSetInst * memsetintr = dyn_cast<MemSetInst>(II)) { Value *len = memsetintr->getLength(); if (ConstantInt * len_int = dyn_cast<ConstantInt>(len)) { if (len_int->getZExtValue() >= MaxAggrCopySize) { aggrMemsets.push_back(memsetintr); } } else { // turn variable length memset into loop aggrMemsets.push_back(memsetintr); } } } } if ((aggrLoads.size() == 0) && (aggrMemcpys.size() == 0) && (aggrMemsets.size() == 0)) return false; // // Do the transformation of an aggr load/copy/set to a loop // for (unsigned i = 0, e = aggrLoads.size(); i != e; ++i) { LoadInst *load = aggrLoads[i]; StoreInst *store = dyn_cast<StoreInst>(*load->use_begin()); Value *srcAddr = load->getOperand(0); Value *dstAddr = store->getOperand(1); unsigned numLoads = TD->getTypeStoreSize(load->getType()); Value *len = ConstantInt::get(Type::getInt32Ty(Context), numLoads); convertTransferToLoop(store, srcAddr, dstAddr, len, load->isVolatile(), store->isVolatile(), Context, F); store->eraseFromParent(); load->eraseFromParent(); } for (unsigned i = 0, e = aggrMemcpys.size(); i != e; ++i) { MemTransferInst *cpy = aggrMemcpys[i]; Value *len = cpy->getLength(); // llvm 2.7 version of memcpy does not have volatile // operand yet. So always making it non-volatile // optimistically, so that we don't see unnecessary // st.volatile in ptx convertTransferToLoop(cpy, cpy->getSource(), cpy->getDest(), len, false, false, Context, F); cpy->eraseFromParent(); } for (unsigned i = 0, e = aggrMemsets.size(); i != e; ++i) { MemSetInst *memsetinst = aggrMemsets[i]; Value *len = memsetinst->getLength(); Value *val = memsetinst->getValue(); convertMemSetToLoop(memsetinst, memsetinst->getDest(), len, val, Context, F); memsetinst->eraseFromParent(); } return true; }
/// Many allocas are only used within a single basic block. If this is the /// case, avoid traversing the CFG and inserting a lot of potentially useless /// PHI nodes by just performing a single linear pass over the basic block /// using the Alloca. /// /// If we cannot promote this alloca (because it is read before it is written), /// return true. This is necessary in cases where, due to control flow, the /// alloca is potentially undefined on some control flow paths. e.g. code like /// this is potentially correct: /// /// for (...) { if (c) { A = undef; undef = B; } } /// /// ... so long as A is not used before undef is set. static void promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, LargeBlockInfo &LBI, AliasSetTracker *AST) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not // significantly pessimize the small block case. This uses LargeBlockInfo to // make it efficient to get the index of various operations in the block. // Walk the use-def list of the alloca, getting the locations of all stores. typedef SmallVector<std::pair<unsigned, StoreInst *>, 64> StoresByIndexTy; StoresByIndexTy StoresByIndex; for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E; ++UI) if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) StoresByIndex.push_back(std::make_pair(LBI.getInstructionIndex(SI), SI)); // Sort the stores by their index, making it efficient to do a lookup with a // binary search. std::sort(StoresByIndex.begin(), StoresByIndex.end(), StoreIndexSearchPredicate()); // Walk all of the loads from this alloca, replacing them with the nearest // store above them, if any. for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;) { LoadInst *LI = dyn_cast<LoadInst>(*UI++); if (!LI) continue; unsigned LoadIdx = LBI.getInstructionIndex(LI); // Find the nearest store that has a lower index than this load. StoresByIndexTy::iterator I = std::lower_bound(StoresByIndex.begin(), StoresByIndex.end(), std::make_pair(LoadIdx, static_cast<StoreInst *>(0)), StoreIndexSearchPredicate()); if (I == StoresByIndex.begin()) // If there is no store before this load, the load takes the undef value. LI->replaceAllUsesWith(UndefValue::get(LI->getType())); else // Otherwise, there was a store before this load, the load takes its value. LI->replaceAllUsesWith(llvm::prior(I)->second->getOperand(0)); if (AST && LI->getType()->isPointerTy()) AST->deleteValue(LI); LI->eraseFromParent(); LBI.deleteValue(LI); } // Remove the (now dead) stores and alloca. while (!AI->use_empty()) { StoreInst *SI = cast<StoreInst>(AI->use_back()); // Record debuginfo for the store before removing it. if (DbgDeclareInst *DDI = Info.DbgDeclare) { DIBuilder DIB(*AI->getParent()->getParent()->getParent()); ConvertDebugDeclareToDebugValue(DDI, SI, DIB); } SI->eraseFromParent(); LBI.deleteValue(SI); } if (AST) AST->deleteValue(AI); AI->eraseFromParent(); LBI.deleteValue(AI); // The alloca's debuginfo can be removed as well. if (DbgDeclareInst *DDI = Info.DbgDeclare) DDI->eraseFromParent(); ++NumLocalPromoted; }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, size_t Idx, bool UseCalls) { BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; if (IsEntryBB) { if (auto SP = F.getSubprogram()) EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); // Keep static allocas and llvm.localescape calls in the entry block. Even // if we aren't splitting the block, it's nice for allocas to be before // calls. IP = PrepareToSplitEntryBlock(BB, IP); } else { EntryLoc = IP->getDebugLoc(); } IRBuilder<> IRB(&*IP); IRB.SetCurrentDebugLocation(EntryLoc); if (Options.TracePC) { IRB.CreateCall(SanCovTracePC); // gets the PC using GET_CALLER_PC. IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } else if (Options.TracePCGuard) { //auto GuardVar = new GlobalVariable( // *F.getParent(), Int64Ty, false, GlobalVariable::LinkOnceODRLinkage, // Constant::getNullValue(Int64Ty), "__sancov_guard." + F.getName()); // if (auto Comdat = F.getComdat()) // GuardVar->setComdat(Comdat); // TODO: add debug into to GuardVar. // GuardVar->setSection(SanCovTracePCGuardSection); // auto GuardPtr = IRB.CreatePointerCast(GuardVar, IntptrPtrTy); auto GuardPtr = IRB.CreateIntToPtr( IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy), ConstantInt::get(IntptrTy, Idx * 4)), Int32PtrTy); if (!UseCalls) { auto GuardLoad = IRB.CreateLoad(GuardPtr); GuardLoad->setAtomic(AtomicOrdering::Monotonic); GuardLoad->setAlignment(8); SetNoSanitizeMetadata(GuardLoad); // Don't instrument with e.g. asan. auto Cmp = IRB.CreateICmpNE( GuardLoad, Constant::getNullValue(GuardLoad->getType())); auto Ins = SplitBlockAndInsertIfThen( Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetCurrentDebugLocation(EntryLoc); IRB.SetInsertPoint(Ins); } IRB.CreateCall(SanCovTracePCGuard, GuardPtr); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } else { Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (Options.TraceBB) { IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } else if (UseCalls) { IRB.CreateCall(SanCovWithCheckFunction, GuardP); } else { LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(AtomicOrdering::Monotonic); Load->setAlignment(4); SetNoSanitizeMetadata(Load); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } } if (Options.Use8bitCounters) { IRB.SetInsertPoint(&*IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); StoreInst *SI = IRB.CreateStore(Inc, P); SetNoSanitizeMetadata(LI); SetNoSanitizeMetadata(SI); } }
/// Many allocas are only used within a single basic block. If this is the /// case, avoid traversing the CFG and inserting a lot of potentially useless /// PHI nodes by just performing a single linear pass over the basic block /// using the Alloca. /// /// If we cannot promote this alloca (because it is read before it is written), /// return false. This is necessary in cases where, due to control flow, the /// alloca is undefined only on some control flow paths. e.g. code like /// this is correct in LLVM IR: /// // A is an alloca with no stores so far /// for (...) { /// int t = *A; /// if (!first_iteration) /// use(t); /// *A = 42; /// } static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info, LargeBlockInfo &LBI, const DataLayout &DL, DominatorTree &DT, AssumptionCache *AC) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not // significantly pessimize the small block case. This uses LargeBlockInfo to // make it efficient to get the index of various operations in the block. // Walk the use-def list of the alloca, getting the locations of all stores. using StoresByIndexTy = SmallVector<std::pair<unsigned, StoreInst *>, 64>; StoresByIndexTy StoresByIndex; for (User *U : AI->users()) if (StoreInst *SI = dyn_cast<StoreInst>(U)) StoresByIndex.push_back(std::make_pair(LBI.getInstructionIndex(SI), SI)); // Sort the stores by their index, making it efficient to do a lookup with a // binary search. llvm::sort(StoresByIndex, less_first()); // Walk all of the loads from this alloca, replacing them with the nearest // store above them, if any. for (auto UI = AI->user_begin(), E = AI->user_end(); UI != E;) { LoadInst *LI = dyn_cast<LoadInst>(*UI++); if (!LI) continue; unsigned LoadIdx = LBI.getInstructionIndex(LI); // Find the nearest store that has a lower index than this load. StoresByIndexTy::iterator I = std::lower_bound(StoresByIndex.begin(), StoresByIndex.end(), std::make_pair(LoadIdx, static_cast<StoreInst *>(nullptr)), less_first()); if (I == StoresByIndex.begin()) { if (StoresByIndex.empty()) // If there are no stores, the load takes the undef value. LI->replaceAllUsesWith(UndefValue::get(LI->getType())); else // There is no store before this load, bail out (load may be affected // by the following stores - see main comment). return false; } else { // Otherwise, there was a store before this load, the load takes its value. // Note, if the load was marked as nonnull we don't want to lose that // information when we erase it. So we preserve it with an assume. Value *ReplVal = std::prev(I)->second->getOperand(0); if (AC && LI->getMetadata(LLVMContext::MD_nonnull) && !isKnownNonZero(ReplVal, DL, 0, AC, LI, &DT)) addAssumeNonNull(AC, LI); // If the replacement value is the load, this must occur in unreachable // code. if (ReplVal == LI) ReplVal = UndefValue::get(LI->getType()); LI->replaceAllUsesWith(ReplVal); } LI->eraseFromParent(); LBI.deleteValue(LI); } // Remove the (now dead) stores and alloca. while (!AI->use_empty()) { StoreInst *SI = cast<StoreInst>(AI->user_back()); // Record debuginfo for the store before removing it. for (DbgVariableIntrinsic *DII : Info.DbgDeclares) { DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false); ConvertDebugDeclareToDebugValue(DII, SI, DIB); } SI->eraseFromParent(); LBI.deleteValue(SI); } AI->eraseFromParent(); LBI.deleteValue(AI); // The alloca's debuginfo can be removed as well. for (DbgVariableIntrinsic *DII : Info.DbgDeclares) { DII->eraseFromParent(); LBI.deleteValue(DII); } ++NumLocalPromoted; return true; }
void Lint::visitLoadInst(LoadInst &I) { visitMemoryReference(I, I.getPointerOperand(), DL->getTypeStoreSize(I.getType()), I.getAlignment(), I.getType(), MemRef::Read); }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls) { // Don't insert coverage for unreachable blocks: we will never call // __sanitizer_cov() for them, so counting them in // NumberOfInstrumentedBlocks() might complicate calculation of code coverage // percentage. Also, unreachable instructions frequently have no debug // locations. if (isa<UnreachableInst>(BB.getTerminator())) return; BasicBlock::iterator IP = BB.getFirstInsertionPt(), BE = BB.end(); // Skip static allocas at the top of the entry block so they don't become // dynamic when we split the block. If we used our optimized stack layout, // then there will only be one alloca and it will come first. for (; IP != BE; ++IP) { AllocaInst *AI = dyn_cast<AllocaInst>(IP); if (!AI || !AI->isStaticAlloca()) break; } bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; if (IsEntryBB) { if (auto SP = getDISubprogram(&F)) EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); } else { EntryLoc = IP->getDebugLoc(); } IRBuilder<> IRB(IP); IRB.SetCurrentDebugLocation(EntryLoc); SmallVector<Value *, 1> Indices; Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (UseCalls) { IRB.CreateCall(SanCovWithCheckFunction, GuardP); } else { LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(Monotonic); Load->setAlignment(4); SetNoSanitizeMetadata(Load); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } if (Options.Use8bitCounters) { IRB.SetInsertPoint(IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); StoreInst *SI = IRB.CreateStore(Inc, P); SetNoSanitizeMetadata(LI); SetNoSanitizeMetadata(SI); } if (Options.TraceBB) { // Experimental support for tracing. // Insert a callback with the same guard variable as used for coverage. IRB.SetInsertPoint(IP); IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } }
/// PromoteSingleBlockAlloca - Many allocas are only used within a single basic /// block. If this is the case, avoid traversing the CFG and inserting a lot of /// potentially useless PHI nodes by just performing a single linear pass over /// the basic block using the Alloca. /// /// If we cannot promote this alloca (because it is read before it is written), /// return true. This is necessary in cases where, due to control flow, the /// alloca is potentially undefined on some control flow paths. e.g. code like /// this is potentially correct: /// /// for (...) { if (c) { A = undef; undef = B; } } /// /// ... so long as A is not used before undef is set. /// void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI) { // The trickiest case to handle is when we have large blocks. Because of this, // this code is optimized assuming that large blocks happen. This does not // significantly pessimize the small block case. This uses LargeBlockInfo to // make it efficient to get the index of various operations in the block. // Clear out UsingBlocks. We will reconstruct it here if needed. Info.UsingBlocks.clear(); // Walk the use-def list of the alloca, getting the locations of all stores. typedef SmallVector<std::pair<unsigned, StoreInst*>, 64> StoresByIndexTy; StoresByIndexTy StoresByIndex; for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E; ++UI) if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) StoresByIndex.push_back(std::make_pair(LBI.getInstructionIndex(SI), SI)); // If there are no stores to the alloca, just replace any loads with undef. if (StoresByIndex.empty()) { for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;) if (LoadInst *LI = dyn_cast<LoadInst>(*UI++)) { LI->replaceAllUsesWith(UndefValue::get(LI->getType())); if (AST && LI->getType()->isPointerTy()) AST->deleteValue(LI); LBI.deleteValue(LI); LI->eraseFromParent(); } return; } // Sort the stores by their index, making it efficient to do a lookup with a // binary search. std::sort(StoresByIndex.begin(), StoresByIndex.end()); // Walk all of the loads from this alloca, replacing them with the nearest // store above them, if any. for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;) { LoadInst *LI = dyn_cast<LoadInst>(*UI++); if (!LI) continue; unsigned LoadIdx = LBI.getInstructionIndex(LI); // Find the nearest store that has a lower than this load. StoresByIndexTy::iterator I = std::lower_bound(StoresByIndex.begin(), StoresByIndex.end(), std::pair<unsigned, StoreInst*>(LoadIdx, static_cast<StoreInst*>(0)), StoreIndexSearchPredicate()); // If there is no store before this load, then we can't promote this load. if (I == StoresByIndex.begin()) { // Can't handle this load, bail out. Info.UsingBlocks.push_back(LI->getParent()); continue; } // Otherwise, there was a store before this load, the load takes its value. --I; LI->replaceAllUsesWith(I->second->getOperand(0)); if (AST && LI->getType()->isPointerTy()) AST->deleteValue(LI); LI->eraseFromParent(); LBI.deleteValue(LI); } }
void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, bool UseCalls) { // Don't insert coverage for unreachable blocks: we will never call // __sanitizer_cov() for them, so counting them in // NumberOfInstrumentedBlocks() might complicate calculation of code coverage // percentage. Also, unreachable instructions frequently have no debug // locations. if (isa<UnreachableInst>(BB.getTerminator())) return; BasicBlock::iterator IP = BB.getFirstInsertionPt(); bool IsEntryBB = &BB == &F.getEntryBlock(); DebugLoc EntryLoc; if (IsEntryBB) { if (auto SP = getDISubprogram(&F)) EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); // Keep static allocas and llvm.localescape calls in the entry block. Even // if we aren't splitting the block, it's nice for allocas to be before // calls. IP = PrepareToSplitEntryBlock(BB, IP); } else { EntryLoc = IP->getDebugLoc(); } IRBuilder<> IRB(&*IP); IRB.SetCurrentDebugLocation(EntryLoc); Value *GuardP = IRB.CreateAdd( IRB.CreatePointerCast(GuardArray, IntptrTy), ConstantInt::get(IntptrTy, (1 + NumberOfInstrumentedBlocks()) * 4)); Type *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty()); GuardP = IRB.CreateIntToPtr(GuardP, Int32PtrTy); if (Options.TracePC) { IRB.CreateCall(SanCovTracePC); } else if (Options.TraceBB) { IRB.CreateCall(IsEntryBB ? SanCovTraceEnter : SanCovTraceBB, GuardP); } else if (UseCalls) { IRB.CreateCall(SanCovWithCheckFunction, GuardP); } else { LoadInst *Load = IRB.CreateLoad(GuardP); Load->setAtomic(Monotonic); Load->setAlignment(4); SetNoSanitizeMetadata(Load); Value *Cmp = IRB.CreateICmpSGE(Constant::getNullValue(Load->getType()), Load); Instruction *Ins = SplitBlockAndInsertIfThen( Cmp, &*IP, false, MDBuilder(*C).createBranchWeights(1, 100000)); IRB.SetInsertPoint(Ins); IRB.SetCurrentDebugLocation(EntryLoc); // __sanitizer_cov gets the PC of the instruction using GET_CALLER_PC. IRB.CreateCall(SanCovFunction, GuardP); IRB.CreateCall(EmptyAsm, {}); // Avoids callback merge. } if (Options.Use8bitCounters) { IRB.SetInsertPoint(&*IP); Value *P = IRB.CreateAdd( IRB.CreatePointerCast(EightBitCounterArray, IntptrTy), ConstantInt::get(IntptrTy, NumberOfInstrumentedBlocks() - 1)); P = IRB.CreateIntToPtr(P, IRB.getInt8PtrTy()); LoadInst *LI = IRB.CreateLoad(P); Value *Inc = IRB.CreateAdd(LI, ConstantInt::get(IRB.getInt8Ty(), 1)); StoreInst *SI = IRB.CreateStore(Inc, P); SetNoSanitizeMetadata(LI); SetNoSanitizeMetadata(SI); } }
/// \brief Rewrite as many loads as possible given a single store. /// /// When there is only a single store, we can use the domtree to trivially /// replace all of the dominated loads with the stored value. Do so, and return /// true if this has successfully promoted the alloca entirely. If this returns /// false there were some loads which were not dominated by the single store /// and thus must be phi-ed with undef. We fall back to the standard alloca /// promotion algorithm in that case. static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI, DominatorTree &DT, AliasSetTracker *AST) { StoreInst *OnlyStore = Info.OnlyStore; bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0)); BasicBlock *StoreBB = OnlyStore->getParent(); int StoreIndex = -1; // Clear out UsingBlocks. We will reconstruct it here if needed. Info.UsingBlocks.clear(); for (Value::use_iterator UI = AI->use_begin(), E = AI->use_end(); UI != E;) { Instruction *UserInst = cast<Instruction>(*UI++); if (!isa<LoadInst>(UserInst)) { assert(UserInst == OnlyStore && "Should only have load/stores"); continue; } LoadInst *LI = cast<LoadInst>(UserInst); // Okay, if we have a load from the alloca, we want to replace it with the // only value stored to the alloca. We can do this if the value is // dominated by the store. If not, we use the rest of the mem2reg machinery // to insert the phi nodes as needed. if (!StoringGlobalVal) { // Non-instructions are always dominated. if (LI->getParent() == StoreBB) { // If we have a use that is in the same block as the store, compare the // indices of the two instructions to see which one came first. If the // load came before the store, we can't handle it. if (StoreIndex == -1) StoreIndex = LBI.getInstructionIndex(OnlyStore); if (unsigned(StoreIndex) > LBI.getInstructionIndex(LI)) { // Can't handle this load, bail out. Info.UsingBlocks.push_back(StoreBB); continue; } } else if (LI->getParent() != StoreBB && !DT.dominates(StoreBB, LI->getParent())) { // If the load and store are in different blocks, use BB dominance to // check their relationships. If the store doesn't dom the use, bail // out. Info.UsingBlocks.push_back(LI->getParent()); continue; } } // Otherwise, we *can* safely rewrite this load. Value *ReplVal = OnlyStore->getOperand(0); // If the replacement value is the load, this must occur in unreachable // code. if (ReplVal == LI) ReplVal = UndefValue::get(LI->getType()); LI->replaceAllUsesWith(ReplVal); if (AST && LI->getType()->isPointerTy()) AST->deleteValue(LI); LI->eraseFromParent(); LBI.deleteValue(LI); } // Finally, after the scan, check to see if the store is all that is left. if (!Info.UsingBlocks.empty()) return false; // If not, we'll have to fall back for the remainder. // Record debuginfo for the store and remove the declaration's // debuginfo. if (DbgDeclareInst *DDI = Info.DbgDeclare) { DIBuilder DIB(*AI->getParent()->getParent()->getParent()); ConvertDebugDeclareToDebugValue(DDI, Info.OnlyStore, DIB); DDI->eraseFromParent(); } // Remove the (now dead) store and alloca. Info.OnlyStore->eraseFromParent(); LBI.deleteValue(Info.OnlyStore); if (AST) AST->deleteValue(AI); AI->eraseFromParent(); LBI.deleteValue(AI); return true; }
void Closure::unpack_struct(Scope<Value *> &dst, llvm::Type * #if LLVM_VERSION >= 37 type #endif , Value *src, IRBuilder<> *builder) { // type, type of src should be a pointer to a struct of the type returned by build_type int idx = 0; LLVMContext &context = builder->getContext(); vector<string> nm = names(); for (size_t i = 0; i < nm.size(); i++) { #if LLVM_VERSION >= 37 Value *ptr = builder->CreateConstInBoundsGEP2_32(type, src, 0, idx++); #else Value *ptr = builder->CreateConstInBoundsGEP2_32(src, 0, idx++); #endif LoadInst *load = builder->CreateLoad(ptr); if (load->getType()->isPointerTy()) { // Give it a unique type so that tbaa tells llvm that this can't alias anything LLVMMDNodeArgumentType md_args[] = {MDString::get(context, nm[i])}; load->setMetadata("tbaa", MDNode::get(context, md_args)); } dst.push(nm[i], load); load->setName(nm[i]); } }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. Search for insert/extractvalue instructions // that can be simplified. // // Inputs: // M - A reference to the LLVM module to transform. // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool SimplifyLoad::runOnModule(Module& M) { // Repeat till no change bool changed; do { changed = false; for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { LoadInst *LI = dyn_cast<LoadInst>(I++); if(!LI) continue; if(LI->hasOneUse()) { if(CastInst *CI = dyn_cast<CastInst>(*(LI->use_begin()))) { if(LI->getType()->isPointerTy()) { if(ConstantExpr *CE = dyn_cast<ConstantExpr>(LI->getOperand(0))) { if(const PointerType *PTy = dyn_cast<PointerType>(CE->getOperand(0)->getType())) if(PTy->getElementType() == CI->getType()) { LoadInst *LINew = new LoadInst(CE->getOperand(0), "", LI); CI->replaceAllUsesWith(LINew); } } } } } } } } } while(changed); return (numErased > 0); }