@@ -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 &CurFn) {
850
+ F = &CurFn;
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
@@ -1168,10 +1173,103 @@ static Value::use_iterator skipToNextUser(Value::use_iterator I,
1168
1173
return I;
1169
1174
}
1170
1175
1176
+ void InferAddressSpacesImpl::performPointerReplacement (
1177
+ Value *V, Value *NewV, Use &U, ValueToValueMapTy &ValueWithNewAddrSpace,
1178
+ SmallVectorImpl<Instruction *> &DeadInstructions) const {
1179
+
1180
+ User *CurUser = U.getUser ();
1181
+
1182
+ unsigned AddrSpace = V->getType ()->getPointerAddressSpace ();
1183
+ if (replaceIfSimplePointerUse (*TTI, CurUser, AddrSpace, V, NewV))
1184
+ return ;
1185
+
1186
+ // Skip if the current user is the new value itself.
1187
+ if (CurUser == NewV)
1188
+ return ;
1189
+
1190
+ auto *CurUserI = dyn_cast<Instruction>(CurUser);
1191
+ if (!CurUserI || CurUserI->getFunction () != F)
1192
+ return ;
1193
+
1194
+ // Handle more complex cases like intrinsic that need to be remangled.
1195
+ if (auto *MI = dyn_cast<MemIntrinsic>(CurUser)) {
1196
+ if (!MI->isVolatile () && handleMemIntrinsicPtrUse (MI, V, NewV))
1197
+ return ;
1198
+ }
1199
+
1200
+ if (auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1201
+ if (rewriteIntrinsicOperands (II, V, NewV))
1202
+ return ;
1203
+ }
1204
+
1205
+ if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUserI)) {
1206
+ // If we can infer that both pointers are in the same addrspace,
1207
+ // transform e.g.
1208
+ // %cmp = icmp eq float* %p, %q
1209
+ // into
1210
+ // %cmp = icmp eq float addrspace(3)* %new_p, %new_q
1211
+
1212
+ unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1213
+ int SrcIdx = U.getOperandNo ();
1214
+ int OtherIdx = (SrcIdx == 0 ) ? 1 : 0 ;
1215
+ Value *OtherSrc = Cmp->getOperand (OtherIdx);
1216
+
1217
+ if (Value *OtherNewV = ValueWithNewAddrSpace.lookup (OtherSrc)) {
1218
+ if (OtherNewV->getType ()->getPointerAddressSpace () == NewAS) {
1219
+ Cmp->setOperand (OtherIdx, OtherNewV);
1220
+ Cmp->setOperand (SrcIdx, NewV);
1221
+ return ;
1222
+ }
1223
+ }
1224
+
1225
+ // Even if the type mismatches, we can cast the constant.
1226
+ if (auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1227
+ if (isSafeToCastConstAddrSpace (KOtherSrc, NewAS)) {
1228
+ Cmp->setOperand (SrcIdx, NewV);
1229
+ Cmp->setOperand (OtherIdx, ConstantExpr::getAddrSpaceCast (
1230
+ KOtherSrc, NewV->getType ()));
1231
+ return ;
1232
+ }
1233
+ }
1234
+ }
1235
+
1236
+ if (AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(CurUserI)) {
1237
+ unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1238
+ if (ASC->getDestAddressSpace () == NewAS) {
1239
+ ASC->replaceAllUsesWith (NewV);
1240
+ DeadInstructions.push_back (ASC);
1241
+ return ;
1242
+ }
1243
+ }
1244
+
1245
+ // Otherwise, replaces the use with flat(NewV).
1246
+ if (Instruction *VInst = dyn_cast<Instruction>(V)) {
1247
+ // Don't create a copy of the original addrspacecast.
1248
+ if (U == V && isa<AddrSpaceCastInst>(V))
1249
+ return ;
1250
+
1251
+ // Insert the addrspacecast after NewV.
1252
+ BasicBlock::iterator InsertPos;
1253
+ if (Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1254
+ InsertPos = std::next (NewVInst->getIterator ());
1255
+ else
1256
+ InsertPos = std::next (VInst->getIterator ());
1257
+
1258
+ while (isa<PHINode>(InsertPos))
1259
+ ++InsertPos;
1260
+ // This instruction may contain multiple uses of V, update them all.
1261
+ CurUser->replaceUsesOfWith (
1262
+ V, new AddrSpaceCastInst (NewV, V->getType (), " " , InsertPos));
1263
+ } else {
1264
+ CurUserI->replaceUsesOfWith (
1265
+ V, ConstantExpr::getAddrSpaceCast (cast<Constant>(NewV), V->getType ()));
1266
+ }
1267
+ }
1268
+
1171
1269
bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces (
1172
1270
ArrayRef<WeakTrackingVH> Postorder,
1173
1271
const ValueToAddrSpaceMapTy &InferredAddrSpace,
1174
- const PredicatedAddrSpaceMapTy &PredicatedAS, Function *F ) const {
1272
+ const PredicatedAddrSpaceMapTy &PredicatedAS) const {
1175
1273
// For each address expression to be modified, creates a clone of it with its
1176
1274
// pointer operands converted to the new address space. Since the pointer
1177
1275
// operands are converted, the clone is naturally in the new address space by
@@ -1262,100 +1360,13 @@ bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1262
1360
Value::use_iterator I, E, Next;
1263
1361
for (I = V->use_begin (), E = V->use_end (); I != E;) {
1264
1362
Use &U = *I;
1265
- User *CurUser = U.getUser ();
1266
1363
1267
1364
// Some users may see the same pointer operand in multiple operands. Skip
1268
1365
// to the next instruction.
1269
1366
I = skipToNextUser (I, E);
1270
1367
1271
- unsigned AddrSpace = V->getType ()->getPointerAddressSpace ();
1272
- if (replaceIfSimplePointerUse (*TTI, CurUser, AddrSpace, V, NewV))
1273
- continue ;
1274
-
1275
- // Skip if the current user is the new value itself.
1276
- if (CurUser == NewV)
1277
- continue ;
1278
-
1279
- if (auto *CurUserI = dyn_cast<Instruction>(CurUser);
1280
- CurUserI && CurUserI->getFunction () != F)
1281
- continue ;
1282
-
1283
- // Handle more complex cases like intrinsic that need to be remangled.
1284
- if (auto *MI = dyn_cast<MemIntrinsic>(CurUser)) {
1285
- if (!MI->isVolatile () && handleMemIntrinsicPtrUse (MI, V, NewV))
1286
- continue ;
1287
- }
1288
-
1289
- if (auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1290
- if (rewriteIntrinsicOperands (II, V, NewV))
1291
- continue ;
1292
- }
1293
-
1294
- if (isa<Instruction>(CurUser)) {
1295
- if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUser)) {
1296
- // If we can infer that both pointers are in the same addrspace,
1297
- // transform e.g.
1298
- // %cmp = icmp eq float* %p, %q
1299
- // into
1300
- // %cmp = icmp eq float addrspace(3)* %new_p, %new_q
1301
-
1302
- unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1303
- int SrcIdx = U.getOperandNo ();
1304
- int OtherIdx = (SrcIdx == 0 ) ? 1 : 0 ;
1305
- Value *OtherSrc = Cmp->getOperand (OtherIdx);
1306
-
1307
- if (Value *OtherNewV = ValueWithNewAddrSpace.lookup (OtherSrc)) {
1308
- if (OtherNewV->getType ()->getPointerAddressSpace () == NewAS) {
1309
- Cmp->setOperand (OtherIdx, OtherNewV);
1310
- Cmp->setOperand (SrcIdx, NewV);
1311
- continue ;
1312
- }
1313
- }
1314
-
1315
- // Even if the type mismatches, we can cast the constant.
1316
- if (auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1317
- if (isSafeToCastConstAddrSpace (KOtherSrc, NewAS)) {
1318
- Cmp->setOperand (SrcIdx, NewV);
1319
- Cmp->setOperand (OtherIdx, ConstantExpr::getAddrSpaceCast (
1320
- KOtherSrc, NewV->getType ()));
1321
- continue ;
1322
- }
1323
- }
1324
- }
1325
-
1326
- if (AddrSpaceCastInst *ASC = dyn_cast<AddrSpaceCastInst>(CurUser)) {
1327
- unsigned NewAS = NewV->getType ()->getPointerAddressSpace ();
1328
- if (ASC->getDestAddressSpace () == NewAS) {
1329
- ASC->replaceAllUsesWith (NewV);
1330
- DeadInstructions.push_back (ASC);
1331
- continue ;
1332
- }
1333
- }
1334
-
1335
- // Otherwise, replaces the use with flat(NewV).
1336
- if (Instruction *VInst = dyn_cast<Instruction>(V)) {
1337
- // Don't create a copy of the original addrspacecast.
1338
- if (U == V && isa<AddrSpaceCastInst>(V))
1339
- continue ;
1340
-
1341
- // Insert the addrspacecast after NewV.
1342
- BasicBlock::iterator InsertPos;
1343
- if (Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1344
- InsertPos = std::next (NewVInst->getIterator ());
1345
- else
1346
- InsertPos = std::next (VInst->getIterator ());
1347
-
1348
- while (isa<PHINode>(InsertPos))
1349
- ++InsertPos;
1350
- // This instruction may contain multiple uses of V, update them all.
1351
- CurUser->replaceUsesOfWith (
1352
- V, new AddrSpaceCastInst (NewV, V->getType (), " " , InsertPos));
1353
- } else {
1354
- CurUser->replaceUsesOfWith (
1355
- V, ConstantExpr::getAddrSpaceCast (cast<Constant>(NewV),
1356
- V->getType ()));
1357
- }
1358
- }
1368
+ performPointerReplacement (V, NewV, U, ValueWithNewAddrSpace,
1369
+ DeadInstructions);
1359
1370
}
1360
1371
1361
1372
if (V->use_empty ()) {
0 commit comments