Skip to content

late-gc-lowering: Prevent infinite recursion #42445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/llvm-final-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@ bool FinalLowerGC::doInitialization(Module &M) {

bool FinalLowerGC::doFinalization(Module &M)
{
GlobalValue *functionList[] = {queueRootFunc, poolAllocFunc, bigAllocFunc};
queueRootFunc = poolAllocFunc = bigAllocFunc = nullptr;
auto used = M.getGlobalVariable("llvm.compiler.used");
if (!used)
return false;
GlobalValue *functionList[] = {queueRootFunc, poolAllocFunc, bigAllocFunc};
SmallPtrSet<Constant*, 16> InitAsSet(
functionList,
functionList + sizeof(functionList) / sizeof(void*));
Expand Down
25 changes: 17 additions & 8 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1153,12 +1153,14 @@ static bool isConstGV(GlobalVariable *gv)
return gv->isConstant() || gv->getMetadata("julia.constgv");
}

static bool isLoadFromConstGV(LoadInst *LI, bool &task_local);
static bool isLoadFromConstGV(Value *v, bool &task_local)
typedef llvm::SmallPtrSet<PHINode*, 1> PhiSet;

static bool isLoadFromConstGV(LoadInst *LI, bool &task_local, PhiSet *seen = nullptr);
static bool isLoadFromConstGV(Value *v, bool &task_local, PhiSet *seen = nullptr)
{
v = v->stripInBoundsOffsets();
if (auto LI = dyn_cast<LoadInst>(v))
return isLoadFromConstGV(LI, task_local);
return isLoadFromConstGV(LI, task_local, seen);
if (auto gv = dyn_cast<GlobalVariable>(v))
return isConstGV(gv);
// null pointer
Expand All @@ -1169,12 +1171,19 @@ static bool isLoadFromConstGV(Value *v, bool &task_local)
return (CE->getOpcode() == Instruction::IntToPtr &&
isa<ConstantData>(CE->getOperand(0)));
if (auto SL = dyn_cast<SelectInst>(v))
return (isLoadFromConstGV(SL->getTrueValue(), task_local) &&
isLoadFromConstGV(SL->getFalseValue(), task_local));
return (isLoadFromConstGV(SL->getTrueValue(), task_local, seen) &&
isLoadFromConstGV(SL->getFalseValue(), task_local, seen));
if (auto Phi = dyn_cast<PHINode>(v)) {
PhiSet ThisSet(&Phi, &Phi);
if (!seen)
seen = &ThisSet;
else if (seen->count(Phi))
return true;
else
seen->insert(Phi);
auto n = Phi->getNumIncomingValues();
for (unsigned i = 0; i < n; ++i) {
if (!isLoadFromConstGV(Phi->getIncomingValue(i), task_local)) {
if (!isLoadFromConstGV(Phi->getIncomingValue(i), task_local, seen)) {
return false;
}
}
Expand Down Expand Up @@ -1206,7 +1215,7 @@ static bool isLoadFromConstGV(Value *v, bool &task_local)
//
// The white list implemented here and above in `isLoadFromConstGV(Value*)` should
// cover all the cases we and LLVM generates.
static bool isLoadFromConstGV(LoadInst *LI, bool &task_local)
static bool isLoadFromConstGV(LoadInst *LI, bool &task_local, PhiSet *seen)
{
// We only emit single slot GV in codegen
// but LLVM global merging can change the pointer operands to GEPs/bitcasts
Expand All @@ -1216,7 +1225,7 @@ static bool isLoadFromConstGV(LoadInst *LI, bool &task_local)
{"jtbaa_immut", "jtbaa_const", "jtbaa_datatype"})) {
if (gv)
return true;
return isLoadFromConstGV(load_base, task_local);
return isLoadFromConstGV(load_base, task_local, seen);
}
if (gv)
return isConstGV(gv);
Expand Down