@@ -1153,12 +1153,14 @@ static bool isConstGV(GlobalVariable *gv)
1153
1153
return gv->isConstant () || gv->getMetadata (" julia.constgv" );
1154
1154
}
1155
1155
1156
- static bool isLoadFromConstGV (LoadInst *LI, bool &task_local);
1157
- static bool isLoadFromConstGV (Value *v, bool &task_local)
1156
+ typedef llvm::SmallPtrSet<PHINode*, 1 > PhiSet;
1157
+
1158
+ static bool isLoadFromConstGV (LoadInst *LI, bool &task_local, PhiSet *seen = nullptr );
1159
+ static bool isLoadFromConstGV (Value *v, bool &task_local, PhiSet *seen = nullptr )
1158
1160
{
1159
1161
v = v->stripInBoundsOffsets ();
1160
1162
if (auto LI = dyn_cast<LoadInst>(v))
1161
- return isLoadFromConstGV (LI, task_local);
1163
+ return isLoadFromConstGV (LI, task_local, seen );
1162
1164
if (auto gv = dyn_cast<GlobalVariable>(v))
1163
1165
return isConstGV (gv);
1164
1166
// null pointer
@@ -1169,12 +1171,19 @@ static bool isLoadFromConstGV(Value *v, bool &task_local)
1169
1171
return (CE->getOpcode () == Instruction::IntToPtr &&
1170
1172
isa<ConstantData>(CE->getOperand (0 )));
1171
1173
if (auto SL = dyn_cast<SelectInst>(v))
1172
- return (isLoadFromConstGV (SL->getTrueValue (), task_local) &&
1173
- isLoadFromConstGV (SL->getFalseValue (), task_local));
1174
+ return (isLoadFromConstGV (SL->getTrueValue (), task_local, seen ) &&
1175
+ isLoadFromConstGV (SL->getFalseValue (), task_local, seen ));
1174
1176
if (auto Phi = dyn_cast<PHINode>(v)) {
1177
+ PhiSet ThisSet (&Phi, &Phi);
1178
+ if (!seen)
1179
+ seen = &ThisSet;
1180
+ else if (seen->count (Phi))
1181
+ return true ;
1182
+ else
1183
+ seen->insert (Phi);
1175
1184
auto n = Phi->getNumIncomingValues ();
1176
1185
for (unsigned i = 0 ; i < n; ++i) {
1177
- if (!isLoadFromConstGV (Phi->getIncomingValue (i), task_local)) {
1186
+ if (!isLoadFromConstGV (Phi->getIncomingValue (i), task_local, seen )) {
1178
1187
return false ;
1179
1188
}
1180
1189
}
@@ -1206,7 +1215,7 @@ static bool isLoadFromConstGV(Value *v, bool &task_local)
1206
1215
//
1207
1216
// The white list implemented here and above in `isLoadFromConstGV(Value*)` should
1208
1217
// cover all the cases we and LLVM generates.
1209
- static bool isLoadFromConstGV (LoadInst *LI, bool &task_local)
1218
+ static bool isLoadFromConstGV (LoadInst *LI, bool &task_local, PhiSet *seen )
1210
1219
{
1211
1220
// We only emit single slot GV in codegen
1212
1221
// but LLVM global merging can change the pointer operands to GEPs/bitcasts
@@ -1216,7 +1225,7 @@ static bool isLoadFromConstGV(LoadInst *LI, bool &task_local)
1216
1225
{" jtbaa_immut" , " jtbaa_const" , " jtbaa_datatype" })) {
1217
1226
if (gv)
1218
1227
return true ;
1219
- return isLoadFromConstGV (load_base, task_local);
1228
+ return isLoadFromConstGV (load_base, task_local, seen );
1220
1229
}
1221
1230
if (gv)
1222
1231
return isConstGV (gv);
0 commit comments