@@ -1165,28 +1165,23 @@ static bool isLifetimeStart(const Instruction *Inst) {
1165
1165
// / Assuming To can be reached from both From and Between, does Between lie on
1166
1166
// / every path from From to To?
1167
1167
static bool liesBetween (const Instruction *From, Instruction *Between,
1168
- const Instruction *To, DominatorTree *DT) {
1168
+ const Instruction *To, const DominatorTree *DT) {
1169
1169
if (From->getParent () == Between->getParent ())
1170
1170
return DT->dominates (From, Between);
1171
1171
SmallSet<BasicBlock *, 1 > Exclusion;
1172
1172
Exclusion.insert (Between->getParent ());
1173
1173
return !isPotentiallyReachable (From, To, &Exclusion, DT);
1174
1174
}
1175
1175
1176
- // / Try to locate the three instruction involved in a missed
1177
- // / load-elimination case that is due to an intervening store.
1178
- static void reportMayClobberedLoad (LoadInst *Load, MemDepResult DepInfo,
1179
- DominatorTree *DT,
1180
- OptimizationRemarkEmitter *ORE) {
1181
- using namespace ore ;
1176
+ static const Instruction *findMayClobberedPtrAccess (LoadInst *Load,
1177
+ const DominatorTree *DT) {
1178
+ Value *PtrOp = Load->getPointerOperand ();
1179
+ if (!PtrOp->hasUseList ())
1180
+ return nullptr ;
1182
1181
1183
1182
Instruction *OtherAccess = nullptr ;
1184
1183
1185
- OptimizationRemarkMissed R (DEBUG_TYPE, " LoadClobbered" , Load);
1186
- R << " load of type " << NV (" Type" , Load->getType ()) << " not eliminated"
1187
- << setExtraArgs ();
1188
-
1189
- for (auto *U : Load->getPointerOperand ()->users ()) {
1184
+ for (auto *U : PtrOp->users ()) {
1190
1185
if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
1191
1186
auto *I = cast<Instruction>(U);
1192
1187
if (I->getFunction () == Load->getFunction () && DT->dominates (I, Load)) {
@@ -1202,32 +1197,48 @@ static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo,
1202
1197
}
1203
1198
}
1204
1199
1205
- if (!OtherAccess) {
1206
- // There is no dominating use, check if we can find a closest non-dominating
1207
- // use that lies between any other potentially available use and Load.
1208
- for (auto *U : Load->getPointerOperand ()->users ()) {
1209
- if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
1210
- auto *I = cast<Instruction>(U);
1211
- if (I->getFunction () == Load->getFunction () &&
1212
- isPotentiallyReachable (I, Load, nullptr , DT)) {
1213
- if (OtherAccess) {
1214
- if (liesBetween (OtherAccess, I, Load, DT)) {
1215
- OtherAccess = I;
1216
- } else if (!liesBetween (I, OtherAccess, Load, DT)) {
1217
- // These uses are both partially available at Load were it not for
1218
- // the clobber, but neither lies strictly after the other.
1219
- OtherAccess = nullptr ;
1220
- break ;
1221
- } // else: keep current OtherAccess since it lies between U and
1222
- // Load.
1223
- } else {
1200
+ if (OtherAccess)
1201
+ return OtherAccess;
1202
+
1203
+ // There is no dominating use, check if we can find a closest non-dominating
1204
+ // use that lies between any other potentially available use and Load.
1205
+ for (auto *U : PtrOp->users ()) {
1206
+ if (U != Load && (isa<LoadInst>(U) || isa<StoreInst>(U))) {
1207
+ auto *I = cast<Instruction>(U);
1208
+ if (I->getFunction () == Load->getFunction () &&
1209
+ isPotentiallyReachable (I, Load, nullptr , DT)) {
1210
+ if (OtherAccess) {
1211
+ if (liesBetween (OtherAccess, I, Load, DT)) {
1224
1212
OtherAccess = I;
1225
- }
1213
+ } else if (!liesBetween (I, OtherAccess, Load, DT)) {
1214
+ // These uses are both partially available at Load were it not for
1215
+ // the clobber, but neither lies strictly after the other.
1216
+ OtherAccess = nullptr ;
1217
+ break ;
1218
+ } // else: keep current OtherAccess since it lies between U and
1219
+ // Load.
1220
+ } else {
1221
+ OtherAccess = I;
1226
1222
}
1227
1223
}
1228
1224
}
1229
1225
}
1230
1226
1227
+ return OtherAccess;
1228
+ }
1229
+
1230
+ // / Try to locate the three instruction involved in a missed
1231
+ // / load-elimination case that is due to an intervening store.
1232
+ static void reportMayClobberedLoad (LoadInst *Load, MemDepResult DepInfo,
1233
+ const DominatorTree *DT,
1234
+ OptimizationRemarkEmitter *ORE) {
1235
+ using namespace ore ;
1236
+
1237
+ OptimizationRemarkMissed R (DEBUG_TYPE, " LoadClobbered" , Load);
1238
+ R << " load of type " << NV (" Type" , Load->getType ()) << " not eliminated"
1239
+ << setExtraArgs ();
1240
+
1241
+ const Instruction *OtherAccess = findMayClobberedPtrAccess (Load, DT);
1231
1242
if (OtherAccess)
1232
1243
R << " in favor of " << NV (" OtherAccess" , OtherAccess);
1233
1244
0 commit comments