@@ -1124,123 +1124,139 @@ int64_t llvm::getPtrStride(PredicatedScalarEvolution &PSE, Value *Ptr,
1124
1124
return Stride;
1125
1125
}
1126
1126
1127
- Optional<int > llvm::getPointersDiff (Value *PtrA, Value *PtrB,
1128
- const DataLayout &DL, ScalarEvolution &SE,
1129
- bool StrictCheck, bool CheckType) {
1130
- assert (PtrA && PtrB && " Expected non-nullptr pointers." );
1131
- // Make sure that A and B are different pointers.
1132
- if (PtrA == PtrB)
1133
- return 0 ;
1134
-
1135
- // Make sure that PtrA and PtrB have the same type if required
1136
- if (CheckType && PtrA->getType () != PtrB->getType ())
1137
- return None;
1138
-
1139
- unsigned ASA = PtrA->getType ()->getPointerAddressSpace ();
1140
- unsigned ASB = PtrB->getType ()->getPointerAddressSpace ();
1141
-
1142
- // Check that the address spaces match.
1143
- if (ASA != ASB)
1144
- return None;
1145
- unsigned IdxWidth = DL.getIndexSizeInBits (ASA);
1146
-
1147
- APInt OffsetA (IdxWidth, 0 ), OffsetB (IdxWidth, 0 );
1148
- Value *PtrA1 = PtrA->stripAndAccumulateInBoundsConstantOffsets (DL, OffsetA);
1149
- Value *PtrB1 = PtrB->stripAndAccumulateInBoundsConstantOffsets (DL, OffsetB);
1150
-
1151
- int Val;
1152
- if (PtrA1 == PtrB1) {
1153
- // Retrieve the address space again as pointer stripping now tracks through
1154
- // `addrspacecast`.
1155
- ASA = cast<PointerType>(PtrA1->getType ())->getAddressSpace ();
1156
- ASB = cast<PointerType>(PtrB1->getType ())->getAddressSpace ();
1157
- // Check that the address spaces match and that the pointers are valid.
1158
- if (ASA != ASB)
1159
- return None;
1160
-
1161
- IdxWidth = DL.getIndexSizeInBits (ASA);
1162
- OffsetA = OffsetA.sextOrTrunc (IdxWidth);
1163
- OffsetB = OffsetB.sextOrTrunc (IdxWidth);
1164
-
1165
- OffsetB -= OffsetA;
1166
- Val = OffsetB.getSExtValue ();
1167
- } else {
1168
- // Otherwise compute the distance with SCEV between the base pointers.
1169
- const SCEV *PtrSCEVA = SE.getSCEV (PtrA);
1170
- const SCEV *PtrSCEVB = SE.getSCEV (PtrB);
1171
- const auto *Diff =
1172
- dyn_cast<SCEVConstant>(SE.getMinusSCEV (PtrSCEVB, PtrSCEVA));
1173
- if (!Diff)
1174
- return None;
1175
- Val = Diff->getAPInt ().getSExtValue ();
1176
- }
1177
- Type *Ty = cast<PointerType>(PtrA->getType ())->getElementType ();
1178
- int Size = DL.getTypeStoreSize (Ty);
1179
- int Dist = Val / Size;
1180
-
1181
- // Ensure that the calculated distance matches the type-based one after all
1182
- // the bitcasts removal in the provided pointers.
1183
- if (!StrictCheck || Dist * Size == Val)
1184
- return Dist;
1185
- return None;
1186
- }
1187
-
1188
1127
bool llvm::sortPtrAccesses (ArrayRef<Value *> VL, const DataLayout &DL,
1189
1128
ScalarEvolution &SE,
1190
1129
SmallVectorImpl<unsigned > &SortedIndices) {
1191
1130
assert (llvm::all_of (
1192
1131
VL, [](const Value *V) { return V->getType ()->isPointerTy (); }) &&
1193
1132
" Expected list of pointer operands." );
1133
+ SmallVector<std::pair<int64_t , Value *>, 4 > OffValPairs;
1134
+ OffValPairs.reserve (VL.size ());
1135
+
1194
1136
// Walk over the pointers, and map each of them to an offset relative to
1195
1137
// first pointer in the array.
1196
1138
Value *Ptr0 = VL[0 ];
1139
+ const SCEV *Scev0 = SE.getSCEV (Ptr0);
1140
+ Value *Obj0 = getUnderlyingObject (Ptr0);
1141
+
1142
+ llvm::SmallSet<int64_t , 4 > Offsets;
1143
+ for (auto *Ptr : VL) {
1144
+ // TODO: Outline this code as a special, more time consuming, version of
1145
+ // computeConstantDifference() function.
1146
+ if (Ptr->getType ()->getPointerAddressSpace () !=
1147
+ Ptr0->getType ()->getPointerAddressSpace ())
1148
+ return false ;
1149
+ // If a pointer refers to a different underlying object, bail - the
1150
+ // pointers are by definition incomparable.
1151
+ Value *CurrObj = getUnderlyingObject (Ptr);
1152
+ if (CurrObj != Obj0)
1153
+ return false ;
1197
1154
1198
- using DistOrdPair = std::pair<int64_t , int >;
1199
- auto Compare = [](const DistOrdPair &L, const DistOrdPair &R) {
1200
- return L.first < R.first ;
1201
- };
1202
- std::set<DistOrdPair, decltype (Compare)> Offsets (Compare);
1203
- Offsets.emplace (0 , 0 );
1204
- int Cnt = 1 ;
1205
- bool IsConsecutive = true ;
1206
- for (auto *Ptr : VL.drop_front ()) {
1207
- Optional<int > Diff = getPointersDiff (Ptr0, Ptr, DL, SE);
1155
+ const SCEV *Scev = SE.getSCEV (Ptr);
1156
+ const auto *Diff = dyn_cast<SCEVConstant>(SE.getMinusSCEV (Scev, Scev0));
1157
+ // The pointers may not have a constant offset from each other, or SCEV
1158
+ // may just not be smart enough to figure out they do. Regardless,
1159
+ // there's nothing we can do.
1208
1160
if (!Diff)
1209
1161
return false ;
1210
1162
1211
1163
// Check if the pointer with the same offset is found.
1212
- int64_t Offset = *Diff;
1213
- auto Res = Offsets.emplace (Offset, Cnt);
1214
- if (!Res.second )
1164
+ int64_t Offset = Diff->getAPInt ().getSExtValue ();
1165
+ if (!Offsets.insert (Offset).second )
1215
1166
return false ;
1216
- // Consecutive order if the inserted element is the last one.
1217
- IsConsecutive = IsConsecutive && std::next (Res.first ) == Offsets.end ();
1218
- ++Cnt;
1167
+ OffValPairs.emplace_back (Offset, Ptr);
1219
1168
}
1220
1169
SortedIndices.clear ();
1221
- if (!IsConsecutive) {
1222
- // Fill SortedIndices array only if it is non-consecutive.
1223
- SortedIndices.resize (VL.size ());
1224
- Cnt = 0 ;
1225
- for (const std::pair<int64_t , int > &Pair : Offsets) {
1226
- IsConsecutive = IsConsecutive && Cnt == Pair.second ;
1227
- SortedIndices[Cnt] = Pair.second ;
1228
- ++Cnt;
1229
- }
1230
- }
1170
+ SortedIndices.resize (VL.size ());
1171
+ std::iota (SortedIndices.begin (), SortedIndices.end (), 0 );
1172
+
1173
+ // Sort the memory accesses and keep the order of their uses in UseOrder.
1174
+ llvm::stable_sort (SortedIndices, [&](unsigned Left, unsigned Right) {
1175
+ return OffValPairs[Left].first < OffValPairs[Right].first ;
1176
+ });
1177
+
1178
+ // Check if the order is consecutive already.
1179
+ if (llvm::all_of (SortedIndices, [&SortedIndices](const unsigned I) {
1180
+ return I == SortedIndices[I];
1181
+ }))
1182
+ SortedIndices.clear ();
1183
+
1231
1184
return true ;
1232
1185
}
1233
1186
1187
+ // / Take the address space operand from the Load/Store instruction.
1188
+ // / Returns -1 if this is not a valid Load/Store instruction.
1189
+ static unsigned getAddressSpaceOperand (Value *I) {
1190
+ if (LoadInst *L = dyn_cast<LoadInst>(I))
1191
+ return L->getPointerAddressSpace ();
1192
+ if (StoreInst *S = dyn_cast<StoreInst>(I))
1193
+ return S->getPointerAddressSpace ();
1194
+ return -1 ;
1195
+ }
1196
+
1234
1197
// / Returns true if the memory operations \p A and \p B are consecutive.
1235
1198
bool llvm::isConsecutiveAccess (Value *A, Value *B, const DataLayout &DL,
1236
1199
ScalarEvolution &SE, bool CheckType) {
1237
1200
Value *PtrA = getLoadStorePointerOperand (A);
1238
1201
Value *PtrB = getLoadStorePointerOperand (B);
1239
- if (!PtrA || !PtrB)
1202
+ unsigned ASA = getAddressSpaceOperand (A);
1203
+ unsigned ASB = getAddressSpaceOperand (B);
1204
+
1205
+ // Check that the address spaces match and that the pointers are valid.
1206
+ if (!PtrA || !PtrB || (ASA != ASB))
1207
+ return false ;
1208
+
1209
+ // Make sure that A and B are different pointers.
1210
+ if (PtrA == PtrB)
1211
+ return false ;
1212
+
1213
+ // Make sure that A and B have the same type if required.
1214
+ if (CheckType && PtrA->getType () != PtrB->getType ())
1240
1215
return false ;
1241
- Optional<int > Diff =
1242
- getPointersDiff (PtrA, PtrB, DL, SE, /* StrictCheck=*/ true , CheckType);
1243
- return Diff && *Diff == 1 ;
1216
+
1217
+ unsigned IdxWidth = DL.getIndexSizeInBits (ASA);
1218
+ Type *Ty = cast<PointerType>(PtrA->getType ())->getElementType ();
1219
+
1220
+ APInt OffsetA (IdxWidth, 0 ), OffsetB (IdxWidth, 0 );
1221
+ PtrA = PtrA->stripAndAccumulateInBoundsConstantOffsets (DL, OffsetA);
1222
+ PtrB = PtrB->stripAndAccumulateInBoundsConstantOffsets (DL, OffsetB);
1223
+
1224
+ // Retrieve the address space again as pointer stripping now tracks through
1225
+ // `addrspacecast`.
1226
+ ASA = cast<PointerType>(PtrA->getType ())->getAddressSpace ();
1227
+ ASB = cast<PointerType>(PtrB->getType ())->getAddressSpace ();
1228
+ // Check that the address spaces match and that the pointers are valid.
1229
+ if (ASA != ASB)
1230
+ return false ;
1231
+
1232
+ IdxWidth = DL.getIndexSizeInBits (ASA);
1233
+ OffsetA = OffsetA.sextOrTrunc (IdxWidth);
1234
+ OffsetB = OffsetB.sextOrTrunc (IdxWidth);
1235
+
1236
+ APInt Size (IdxWidth, DL.getTypeStoreSize (Ty));
1237
+
1238
+ // OffsetDelta = OffsetB - OffsetA;
1239
+ const SCEV *OffsetSCEVA = SE.getConstant (OffsetA);
1240
+ const SCEV *OffsetSCEVB = SE.getConstant (OffsetB);
1241
+ const SCEV *OffsetDeltaSCEV = SE.getMinusSCEV (OffsetSCEVB, OffsetSCEVA);
1242
+ const APInt &OffsetDelta = cast<SCEVConstant>(OffsetDeltaSCEV)->getAPInt ();
1243
+
1244
+ // Check if they are based on the same pointer. That makes the offsets
1245
+ // sufficient.
1246
+ if (PtrA == PtrB)
1247
+ return OffsetDelta == Size;
1248
+
1249
+ // Compute the necessary base pointer delta to have the necessary final delta
1250
+ // equal to the size.
1251
+ // BaseDelta = Size - OffsetDelta;
1252
+ const SCEV *SizeSCEV = SE.getConstant (Size);
1253
+ const SCEV *BaseDelta = SE.getMinusSCEV (SizeSCEV, OffsetDeltaSCEV);
1254
+
1255
+ // Otherwise compute the distance with SCEV between the base pointers.
1256
+ const SCEV *PtrSCEVA = SE.getSCEV (PtrA);
1257
+ const SCEV *PtrSCEVB = SE.getSCEV (PtrB);
1258
+ const SCEV *X = SE.getAddExpr (PtrSCEVA, BaseDelta);
1259
+ return X == PtrSCEVB;
1244
1260
}
1245
1261
1246
1262
MemoryDepChecker::VectorizationSafetyStatus
0 commit comments