PointerOffsetPair LoadCombine::getPointerOffsetPair(LoadInst &LI) { PointerOffsetPair POP; POP.Pointer = LI.getPointerOperand(); POP.Offset = 0; while (isa<BitCastInst>(POP.Pointer) || isa<GetElementPtrInst>(POP.Pointer)) { if (auto *GEP = dyn_cast<GetElementPtrInst>(POP.Pointer)) { auto &DL = LI.getModule()->getDataLayout(); unsigned BitWidth = DL.getPointerTypeSizeInBits(GEP->getType()); APInt Offset(BitWidth, 0); if (GEP->accumulateConstantOffset(DL, Offset)) POP.Offset += Offset.getZExtValue(); else // Can't handle GEPs with variable indices. return POP; POP.Pointer = GEP->getPointerOperand(); } else if (auto *BC = dyn_cast<BitCastInst>(POP.Pointer)) POP.Pointer = BC->getOperand(0); } return POP; }
PointerOffsetPair LoadCombine::getPointerOffsetPair(LoadInst &LI) { auto &DL = LI.getModule()->getDataLayout(); PointerOffsetPair POP; POP.Pointer = LI.getPointerOperand(); unsigned BitWidth = DL.getPointerSizeInBits(LI.getPointerAddressSpace()); POP.Offset = APInt(BitWidth, 0); while (isa<BitCastInst>(POP.Pointer) || isa<GetElementPtrInst>(POP.Pointer)) { if (auto *GEP = dyn_cast<GetElementPtrInst>(POP.Pointer)) { APInt LastOffset = POP.Offset; if (!GEP->accumulateConstantOffset(DL, POP.Offset)) { // Can't handle GEPs with variable indices. POP.Offset = LastOffset; return POP; } POP.Pointer = GEP->getPointerOperand(); } else if (auto *BC = dyn_cast<BitCastInst>(POP.Pointer)) { POP.Pointer = BC->getOperand(0); } } return POP; }
bool Scalarizer::visitLoadInst(LoadInst &LI) { if (!ScalarizeLoadStore) return false; if (!LI.isSimple()) return false; VectorLayout Layout; if (!getVectorLayout(LI.getType(), LI.getAlignment(), Layout, LI.getModule()->getDataLayout())) return false; unsigned NumElems = Layout.VecTy->getNumElements(); IRBuilder<> Builder(&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; }