@@ -184,6 +184,7 @@ class InferAddressSpaces : public FunctionPass {
184
184
185
185
class InferAddressSpacesImpl {
186
186
AssumptionCache ∾
187
+ Function *F = nullptr ;
187
188
const DominatorTree *DT = nullptr ;
188
189
const TargetTransformInfo *TTI = nullptr ;
189
190
const DataLayout *DL = nullptr ;
@@ -212,14 +213,17 @@ class InferAddressSpacesImpl {
212
213
const PredicatedAddrSpaceMapTy &PredicatedAS,
213
214
SmallVectorImpl<const Use *> *PoisonUsesToFix) const ;
214
215
216
+ void performPointerReplacement (
217
+ Value *V, Value *NewV, Use &U, ValueToValueMapTy &ValueWithNewAddrSpace,
218
+ SmallVectorImpl<Instruction *> &DeadInstructions) const ;
219
+
215
220
// Changes the flat address expressions in function F to point to specific
216
221
// address spaces if InferredAddrSpace says so. Postorder is the postorder of
217
222
// all flat expressions in the use-def graph of function F.
218
- bool
219
- rewriteWithNewAddressSpaces (ArrayRef<WeakTrackingVH> Postorder,
220
- const ValueToAddrSpaceMapTy &InferredAddrSpace,
221
- const PredicatedAddrSpaceMapTy &PredicatedAS,
222
- Function *F) const ;
223
+ bool rewriteWithNewAddressSpaces (
224
+ ArrayRef<WeakTrackingVH> Postorder,
225
+ const ValueToAddrSpaceMapTy &InferredAddrSpace,
226
+ const PredicatedAddrSpaceMapTy &PredicatedAS) const ;
223
227
224
228
void appendsFlatAddressExpressionToPostorderStack (
225
229
Value *V, PostorderStackTy &PostorderStack,
@@ -842,8 +846,9 @@ unsigned InferAddressSpacesImpl::joinAddressSpaces(unsigned AS1,
842
846
return (AS1 == AS2) ? AS1 : FlatAddrSpace;
843
847
}
844
848
845
- bool InferAddressSpacesImpl::run (Function &F) {
846
- DL = &F.getDataLayout ();
849
+ bool InferAddressSpacesImpl::run (Function &F_) {
850
+ F = &F_;
851
+ DL = &F->getDataLayout ();
847
852
848
853
if (AssumeDefaultIsFlatAddressSpace)
849
854
FlatAddrSpace = 0 ;
@@ -855,7 +860,7 @@ bool InferAddressSpacesImpl::run(Function &F) {
855
860
}
856
861
857
862
// Collects all flat address expressions in postorder.
858
- std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions (F);
863
+ std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions (* F);
859
864
860
865
// Runs a data-flow analysis to refine the address spaces of every expression
861
866
// in Postorder.
@@ -865,8 +870,8 @@ bool InferAddressSpacesImpl::run(Function &F) {
865
870
866
871
// Changes the address spaces of the flat address expressions who are inferred
867
872
// to point to a specific address space.
868
- return rewriteWithNewAddressSpaces (Postorder, InferredAddrSpace, PredicatedAS,
869
- &F );
873
+ return rewriteWithNewAddressSpaces (Postorder, InferredAddrSpace,
874
+ PredicatedAS );
870
875
}
871
876
872
877
// Constants need to be tracked through RAUW to handle cases with nested
@@ -1164,10 +1169,105 @@ static Value::use_iterator skipToNextUser(Value::use_iterator I,
1164
1169
return I;
1165
1170
}
1166
1171
1172
+ void InferAddressSpacesImpl::performPointerReplacement (
1173
+ Value *V, Value *NewV, Use &U, ValueToValueMapTy &ValueWithNewAddrSpace,
1174
+ SmallVectorImpl<Instruction *> &DeadInstructions) const {
1175
+
1176
+ User *CurUser = U.getUser ();
1177
+
1178
+ unsigned AddrSpace = V->getType ()->getPointerAddressSpace ();
1179
+ if (replaceIfSimplePointerUse (*TTI, CurUser, AddrSpace, V, NewV))
1180
+ return ;
1181
+
1182
+ // Skip if the current user is the new value itself.
1183
+ if (CurUser == NewV)
1184
+ return ;
1185
+
1186
+ if (auto *CurUserI = dyn_cast<Instruction>(CurUser);
1187
+ CurUserI && CurUserI->getFunction () != F)
1188
+ return ;
1189
+
1190
+ // Handle more complex cases like intrinsic that need to be remangled.
1191
+ if (auto *MI = dyn_cast<MemIntrinsic>(CurUser)) {
1192
+ if (!MI->isVolatile () && handleMemIntrinsicPtrUse (MI, V, NewV))
1193
+ return ;
1194
+ }
1195
+
1196
+ if (auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1197
+ if (rewriteIntrinsicOperands (II, V, NewV))
1198
+ return ;
1199
+ }
1200
+
1201
+ if (isa<Instruction>(CurUser)) {
1202
+ if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUser)) {
1203
+ // If we can infer that both pointers are in the same addrspace,
1204
+ // transform e.g.
1205
+ // %cmp = icmp eq float* %p, %q
1206
+ // into
1207
+ // %cmp = icmp eq float addrspace(3)* %new_p, %new_q
1208
+
1209
+ unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1210
+ int SrcIdx = U.getOperandNo ();
1211
+ int OtherIdx = (SrcIdx == 0 ) ? 1 : 0 ;
1212
+ Value *OtherSrc = Cmp->getOperand (OtherIdx);
1213
+
1214
+ if (Value *OtherNewV = ValueWithNewAddrSpace.lookup (OtherSrc)) {
1215
+ if (OtherNewV->getType ()->getPointerAddressSpace () == NewAS) {
1216
+ Cmp->setOperand (OtherIdx, OtherNewV);
1217
+ Cmp->setOperand (SrcIdx, NewV);
1218
+ return ;
1219
+ }
1220
+ }
1221
+
1222
+ // Even if the type mismatches, we can cast the constant.
1223
+ if (auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1224
+ if (isSafeToCastConstAddrSpace (KOtherSrc, NewAS)) {
1225
+ Cmp->setOperand (SrcIdx, NewV);
1226
+ Cmp->setOperand (OtherIdx, ConstantExpr::getAddrSpaceCast (
1227
+ KOtherSrc, NewV->getType ()));
1228
+ return ;
1229
+ }
1230
+ }
1231
+ }
1232
+
1233
+ if (AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(CurUser)) {
1234
+ unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1235
+ if (ASC->getDestAddressSpace () == NewAS) {
1236
+ ASC->replaceAllUsesWith (NewV);
1237
+ DeadInstructions.push_back (ASC);
1238
+ return ;
1239
+ }
1240
+ }
1241
+
1242
+ // Otherwise, replaces the use with flat(NewV).
1243
+ if (Instruction *VInst = dyn_cast<Instruction>(V)) {
1244
+ // Don't create a copy of the original addrspacecast.
1245
+ if (U == V && isa<AddrSpaceCastInst>(V))
1246
+ return ;
1247
+
1248
+ // Insert the addrspacecast after NewV.
1249
+ BasicBlock::iterator InsertPos;
1250
+ if (Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1251
+ InsertPos = std::next (NewVInst->getIterator ());
1252
+ else
1253
+ InsertPos = std::next (VInst->getIterator ());
1254
+
1255
+ while (isa<PHINode>(InsertPos))
1256
+ ++InsertPos;
1257
+ // This instruction may contain multiple uses of V, update them all.
1258
+ CurUser->replaceUsesOfWith (
1259
+ V, new AddrSpaceCastInst (NewV, V->getType (), " " , InsertPos));
1260
+ } else {
1261
+ CurUser->replaceUsesOfWith (V, ConstantExpr::getAddrSpaceCast (
1262
+ cast<Constant>(NewV), V->getType ()));
1263
+ }
1264
+ }
1265
+ }
1266
+
1167
1267
bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces (
1168
1268
ArrayRef<WeakTrackingVH> Postorder,
1169
1269
const ValueToAddrSpaceMapTy &InferredAddrSpace,
1170
- const PredicatedAddrSpaceMapTy &PredicatedAS, Function *F ) const {
1270
+ const PredicatedAddrSpaceMapTy &PredicatedAS) const {
1171
1271
// For each address expression to be modified, creates a clone of it with its
1172
1272
// pointer operands converted to the new address space. Since the pointer
1173
1273
// operands are converted, the clone is naturally in the new address space by
@@ -1258,100 +1358,13 @@ bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1258
1358
Value::use_iterator I, E, Next;
1259
1359
for (I = V->use_begin (), E = V->use_end (); I != E;) {
1260
1360
Use &U = *I;
1261
- User *CurUser = U.getUser ();
1262
1361
1263
1362
// Some users may see the same pointer operand in multiple operands. Skip
1264
1363
// to the next instruction.
1265
1364
I = skipToNextUser (I, E);
1266
1365
1267
- unsigned AddrSpace = V->getType ()->getPointerAddressSpace ();
1268
- if (replaceIfSimplePointerUse (*TTI, CurUser, AddrSpace, V, NewV))
1269
- continue ;
1270
-
1271
- // Skip if the current user is the new value itself.
1272
- if (CurUser == NewV)
1273
- continue ;
1274
-
1275
- if (auto *CurUserI = dyn_cast<Instruction>(CurUser);
1276
- CurUserI && CurUserI->getFunction () != F)
1277
- continue ;
1278
-
1279
- // Handle more complex cases like intrinsic that need to be remangled.
1280
- if (auto *MI = dyn_cast<MemIntrinsic>(CurUser)) {
1281
- if (!MI->isVolatile () && handleMemIntrinsicPtrUse (MI, V, NewV))
1282
- continue ;
1283
- }
1284
-
1285
- if (auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1286
- if (rewriteIntrinsicOperands (II, V, NewV))
1287
- continue ;
1288
- }
1289
-
1290
- if (isa<Instruction>(CurUser)) {
1291
- if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUser)) {
1292
- // If we can infer that both pointers are in the same addrspace,
1293
- // transform e.g.
1294
- // %cmp = icmp eq float* %p, %q
1295
- // into
1296
- // %cmp = icmp eq float addrspace(3)* %new_p, %new_q
1297
-
1298
- unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1299
- int SrcIdx = U.getOperandNo ();
1300
- int OtherIdx = (SrcIdx == 0 ) ? 1 : 0 ;
1301
- Value *OtherSrc = Cmp->getOperand (OtherIdx);
1302
-
1303
- if (Value *OtherNewV = ValueWithNewAddrSpace.lookup (OtherSrc)) {
1304
- if (OtherNewV->getType ()->getPointerAddressSpace () == NewAS) {
1305
- Cmp->setOperand (OtherIdx, OtherNewV);
1306
- Cmp->setOperand (SrcIdx, NewV);
1307
- continue ;
1308
- }
1309
- }
1310
-
1311
- // Even if the type mismatches, we can cast the constant.
1312
- if (auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1313
- if (isSafeToCastConstAddrSpace (KOtherSrc, NewAS)) {
1314
- Cmp->setOperand (SrcIdx, NewV);
1315
- Cmp->setOperand (OtherIdx, ConstantExpr::getAddrSpaceCast (
1316
- KOtherSrc, NewV->getType ()));
1317
- continue ;
1318
- }
1319
- }
1320
- }
1321
-
1322
- if (AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(CurUser)) {
1323
- unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1324
- if (ASC->getDestAddressSpace () == NewAS) {
1325
- ASC->replaceAllUsesWith (NewV);
1326
- DeadInstructions.push_back (ASC);
1327
- continue ;
1328
- }
1329
- }
1330
-
1331
- // Otherwise, replaces the use with flat(NewV).
1332
- if (Instruction *VInst = dyn_cast<Instruction>(V)) {
1333
- // Don't create a copy of the original addrspacecast.
1334
- if (U == V && isa<AddrSpaceCastInst>(V))
1335
- continue ;
1336
-
1337
- // Insert the addrspacecast after NewV.
1338
- BasicBlock::iterator InsertPos;
1339
- if (Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1340
- InsertPos = std::next (NewVInst->getIterator ());
1341
- else
1342
- InsertPos = std::next (VInst->getIterator ());
1343
-
1344
- while (isa<PHINode>(InsertPos))
1345
- ++InsertPos;
1346
- // This instruction may contain multiple uses of V, update them all.
1347
- CurUser->replaceUsesOfWith (
1348
- V, new AddrSpaceCastInst (NewV, V->getType (), " " , InsertPos));
1349
- } else {
1350
- CurUser->replaceUsesOfWith (
1351
- V, ConstantExpr::getAddrSpaceCast (cast<Constant>(NewV),
1352
- V->getType ()));
1353
- }
1354
- }
1366
+ performPointerReplacement (V, NewV, U, ValueWithNewAddrSpace,
1367
+ DeadInstructions);
1355
1368
}
1356
1369
1357
1370
if (V->use_empty ()) {
0 commit comments