+ // If the loaded value is smaller than the available value, then we can
+ // extract out a piece from it. If the available value is too small, then we
+ // can't do anything.
+ assert(StoreSize >= LoadSize && "CanCoerceMustAliasedValueToLoad fail");
+
+ // Convert source pointers to integers, which can be manipulated.
+ if (isa<PointerType>(StoredValTy)) {
+ StoredValTy = TD.getIntPtrType(StoredValTy->getContext());
+ StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt);
+ }
+
+ // Convert vectors and fp to integer, which can be manipulated.
+ if (!isa<IntegerType>(StoredValTy)) {
+ StoredValTy = IntegerType::get(StoredValTy->getContext(), StoreSize);
+ StoredVal = new BitCastInst(StoredVal, StoredValTy, "", InsertPt);
+ }
+
+ // If this is a big-endian system, we need to shift the value down to the low
+ // bits so that a truncate will work.
+ if (TD.isBigEndian()) {
+ Constant *Val = ConstantInt::get(StoredVal->getType(), StoreSize-LoadSize);
+ StoredVal = BinaryOperator::CreateLShr(StoredVal, Val, "tmp", InsertPt);
+ }
+
+ // Truncate the integer to the right size now.
+ const Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadSize);
+ StoredVal = new TruncInst(StoredVal, NewIntTy, "trunc", InsertPt);
+
+ if (LoadedTy == NewIntTy)
+ return StoredVal;
+
+ // If the result is a pointer, inttoptr.
+ if (isa<PointerType>(LoadedTy))
+ return new IntToPtrInst(StoredVal, LoadedTy, "inttoptr", InsertPt);
+
+ // Otherwise, bitcast.
+ return new BitCastInst(StoredVal, LoadedTy, "bitcast", InsertPt);
+}
+
+/// GetBaseWithConstantOffset - Analyze the specified pointer to see if it can
+/// be expressed as a base pointer plus a constant offset. Return the base and
+/// offset to the caller.
+static Value *GetBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
+ const TargetData &TD) {
+ Operator *PtrOp = dyn_cast<Operator>(Ptr);
+ if (PtrOp == 0) return Ptr;
+
+ // Just look through bitcasts.
+ if (PtrOp->getOpcode() == Instruction::BitCast)
+ return GetBaseWithConstantOffset(PtrOp->getOperand(0), Offset, TD);
+
+ // If this is a GEP with constant indices, we can look through it.
+ GEPOperator *GEP = dyn_cast<GEPOperator>(PtrOp);
+ if (GEP == 0 || !GEP->hasAllConstantIndices()) return Ptr;
+
+ gep_type_iterator GTI = gep_type_begin(GEP);
+ for (User::op_iterator I = GEP->idx_begin(), E = GEP->idx_end(); I != E;
+ ++I, ++GTI) {
+ ConstantInt *OpC = cast<ConstantInt>(*I);
+ if (OpC->isZero()) continue;
+
+ // Handle a struct and array indices which add their offset to the pointer.
+ if (const StructType *STy = dyn_cast<StructType>(*GTI)) {
+ Offset += TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue());
+ } else {
+ uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType());
+ Offset += OpC->getSExtValue()*Size;
+ }
+ }
+
+ // Re-sign extend from the pointer size if needed to get overflow edge cases
+ // right.
+ unsigned PtrSize = TD.getPointerSizeInBits();
+ if (PtrSize < 64)
+ Offset = (Offset << (64-PtrSize)) >> (64-PtrSize);
+
+ return GetBaseWithConstantOffset(GEP->getPointerOperand(), Offset, TD);
+}
+
+
+/// AnalyzeLoadFromClobberingStore - This function is called when we have a
+/// memdep query of a load that ends up being a clobbering store. This means
+/// that the store *may* provide bits used by the load but we can't be sure
+/// because the pointers don't mustalias. Check this case to see if there is
+/// anything more we can do before we give up. This returns -1 if we have to
+/// give up, or a byte number in the stored value of the piece that feeds the
+/// load.
+static int AnalyzeLoadFromClobberingStore(LoadInst *L, StoreInst *DepSI,
+ const TargetData &TD) {
+ // If the loaded or stored value is an first class array or struct, don't try
+ // to transform them. We need to be able to bitcast to integer.
+ if (isa<StructType>(L->getType()) || isa<ArrayType>(L->getType()) ||
+ isa<StructType>(DepSI->getOperand(0)->getType()) ||
+ isa<ArrayType>(DepSI->getOperand(0)->getType()))
+ return -1;
+
+ int64_t StoreOffset = 0, LoadOffset = 0;
+ Value *StoreBase =
+ GetBaseWithConstantOffset(DepSI->getPointerOperand(), StoreOffset, TD);
+ Value *LoadBase =
+ GetBaseWithConstantOffset(L->getPointerOperand(), LoadOffset, TD);
+ if (StoreBase != LoadBase)
+ return -1;
+
+ // If the load and store are to the exact same address, they should have been
+ // a must alias. AA must have gotten confused.
+ // FIXME: Study to see if/when this happens.
+ if (LoadOffset == StoreOffset) {
+#if 0
+ errs() << "STORE/LOAD DEP WITH COMMON POINTER MISSED:\n"
+ << "Base = " << *StoreBase << "\n"
+ << "Store Ptr = " << *DepSI->getPointerOperand() << "\n"
+ << "Store Offs = " << StoreOffset << " - " << *DepSI << "\n"
+ << "Load Ptr = " << *L->getPointerOperand() << "\n"
+ << "Load Offs = " << LoadOffset << " - " << *L << "\n\n";
+ errs() << "'" << L->getParent()->getParent()->getName() << "'"
+ << *L->getParent();
+#endif
+ return -1;
+ }
+
+ // If the load and store don't overlap at all, the store doesn't provide
+ // anything to the load. In this case, they really don't alias at all, AA
+ // must have gotten confused.
+ // FIXME: Investigate cases where this bails out, e.g. rdar://7238614. Then
+ // remove this check, as it is duplicated with what we have below.
+ uint64_t StoreSize = TD.getTypeSizeInBits(DepSI->getOperand(0)->getType());
+ uint64_t LoadSize = TD.getTypeSizeInBits(L->getType());
+
+ if ((StoreSize & 7) | (LoadSize & 7))
+ return -1;
+ StoreSize >>= 3; // Convert to bytes.
+ LoadSize >>= 3;
+
+
+ bool isAAFailure = false;
+ if (StoreOffset < LoadOffset) {
+ isAAFailure = StoreOffset+int64_t(StoreSize) <= LoadOffset;
+ } else {
+ isAAFailure = LoadOffset+int64_t(LoadSize) <= StoreOffset;
+ }
+ if (isAAFailure) {
+#if 0
+ errs() << "STORE LOAD DEP WITH COMMON BASE:\n"
+ << "Base = " << *StoreBase << "\n"
+ << "Store Ptr = " << *DepSI->getPointerOperand() << "\n"
+ << "Store Offs = " << StoreOffset << " - " << *DepSI << "\n"
+ << "Load Ptr = " << *L->getPointerOperand() << "\n"
+ << "Load Offs = " << LoadOffset << " - " << *L << "\n\n";
+ errs() << "'" << L->getParent()->getParent()->getName() << "'"
+ << *L->getParent();
+#endif
+ return -1;
+ }
+
+ // If the Load isn't completely contained within the stored bits, we don't
+ // have all the bits to feed it. We could do something crazy in the future
+ // (issue a smaller load then merge the bits in) but this seems unlikely to be
+ // valuable.
+ if (StoreOffset > LoadOffset ||
+ StoreOffset+StoreSize < LoadOffset+LoadSize)
+ return -1;
+
+ // Okay, we can do this transformation. Return the number of bytes into the
+ // store that the load is.
+ return LoadOffset-StoreOffset;
+}
+
+
+/// GetStoreValueForLoad - This function is called when we have a
+/// memdep query of a load that ends up being a clobbering store. This means
+/// that the store *may* provide bits used by the load but we can't be sure
+/// because the pointers don't mustalias. Check this case to see if there is
+/// anything more we can do before we give up.
+static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset,
+ const Type *LoadTy,
+ Instruction *InsertPt, const TargetData &TD){
+ LLVMContext &Ctx = SrcVal->getType()->getContext();
+
+ uint64_t StoreSize = TD.getTypeSizeInBits(SrcVal->getType())/8;
+ uint64_t LoadSize = TD.getTypeSizeInBits(LoadTy)/8;
+
+
+ // Compute which bits of the stored value are being used by the load. Convert
+ // to an integer type to start with.
+ if (isa<PointerType>(SrcVal->getType()))
+ SrcVal = new PtrToIntInst(SrcVal, TD.getIntPtrType(Ctx), "tmp", InsertPt);
+ if (!isa<IntegerType>(SrcVal->getType()))
+ SrcVal = new BitCastInst(SrcVal, IntegerType::get(Ctx, StoreSize*8),
+ "tmp", InsertPt);
+
+ // Shift the bits to the least significant depending on endianness.
+ unsigned ShiftAmt;
+ if (TD.isLittleEndian()) {
+ ShiftAmt = Offset*8;
+ } else {
+ ShiftAmt = (StoreSize-LoadSize-Offset)*8;
+ }
+
+ if (ShiftAmt)
+ SrcVal = BinaryOperator::CreateLShr(SrcVal,
+ ConstantInt::get(SrcVal->getType(), ShiftAmt), "tmp", InsertPt);
+
+ if (LoadSize != StoreSize)
+ SrcVal = new TruncInst(SrcVal, IntegerType::get(Ctx, LoadSize*8),
+ "tmp", InsertPt);
+
+ return CoerceAvailableValueToLoadType(SrcVal, LoadTy, InsertPt, TD);
+}
+
+struct AvailableValueInBlock {
+ /// BB - The basic block in question.
+ BasicBlock *BB;
+ /// V - The value that is live out of the block.
+ Value *V;
+ /// Offset - The byte offset in V that is interesting for the load query.
+ unsigned Offset;
+
+ static AvailableValueInBlock get(BasicBlock *BB, Value *V,
+ unsigned Offset = 0) {
+ AvailableValueInBlock Res;
+ Res.BB = BB;
+ Res.V = V;
+ Res.Offset = Offset;
+ return Res;
+ }
+};
+
+/// ConstructSSAForLoadSet - Given a set of loads specified by ValuesPerBlock,
+/// construct SSA form, allowing us to eliminate LI. This returns the value
+/// that should be used at LI's definition site.
+static Value *ConstructSSAForLoadSet(LoadInst *LI,
+ SmallVectorImpl<AvailableValueInBlock> &ValuesPerBlock,
+ const TargetData *TD,
+ AliasAnalysis *AA) {
+ SmallVector<PHINode*, 8> NewPHIs;
+ SSAUpdater SSAUpdate(&NewPHIs);
+ SSAUpdate.Initialize(LI);
+
+ const Type *LoadTy = LI->getType();
+
+ for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) {
+ BasicBlock *BB = ValuesPerBlock[i].BB;
+ Value *AvailableVal = ValuesPerBlock[i].V;
+ unsigned Offset = ValuesPerBlock[i].Offset;
+
+ if (SSAUpdate.HasValueForBlock(BB))
+ continue;
+
+ if (AvailableVal->getType() != LoadTy) {
+ assert(TD && "Need target data to handle type mismatch case");
+ AvailableVal = GetStoreValueForLoad(AvailableVal, Offset, LoadTy,
+ BB->getTerminator(), *TD);
+
+ if (Offset) {
+ DEBUG(errs() << "GVN COERCED NONLOCAL VAL:\n"
+ << *ValuesPerBlock[i].V << '\n'
+ << *AvailableVal << '\n' << "\n\n\n");