From e4a27bdef7a9a34f0e5192c600b40584a284bc10 Mon Sep 17 00:00:00 2001 From: gbaraldi Date: Fri, 12 Jan 2024 14:41:43 -0300 Subject: [PATCH] Fix git mess --- src/llvm-final-gc-lowering.cpp | 37 +++++++++++++- src/llvm-late-gc-lowering.cpp | 90 +++++++++++++++++++++++----------- 2 files changed, 97 insertions(+), 30 deletions(-) diff --git a/src/llvm-final-gc-lowering.cpp b/src/llvm-final-gc-lowering.cpp index 5a53ce4d8e510..3d600138f4d87 100644 --- a/src/llvm-final-gc-lowering.cpp +++ b/src/llvm-final-gc-lowering.cpp @@ -230,14 +230,14 @@ bool FinalLowerGC::runOnFunction(Function &F) initAll(*F.getParent()); if (!pgcstack_getter && !adoptthread_func) { LLVM_DEBUG(dbgs() << "FINAL GC LOWERING: Skipping function " << F.getName() << "\n"); - return false; + goto verify_skip; } // Look for a call to 'julia.get_pgcstack'. pgcstack = getPGCstack(F); if (!pgcstack) { LLVM_DEBUG(dbgs() << "FINAL GC LOWERING: Skipping function " << F.getName() << " no pgcstack\n"); - return false; + goto verify_skip; } LLVM_DEBUG(dbgs() << "FINAL GC LOWERING: Processing function " << F.getName() << "\n"); queueRootFunc = getOrDeclare(jl_well_known::GCQueueRoot); @@ -277,6 +277,39 @@ bool FinalLowerGC::runOnFunction(Function &F) } return true; + + verify_skip: +#ifdef JL_VERIFY_PASSES + for (auto &BB : F) { + for (auto &I : make_early_inc_range(BB)) { + auto *CI = dyn_cast(&I); + if (!CI) + continue; + + Value *callee = CI->getCalledOperand(); + assert(callee); +#define IS_INTRINSIC(INTRINSIC) \ + do { \ + auto intrinsic = getOrNull(jl_intrinsics::INTRINSIC); \ + if (intrinsic == callee) { \ + errs() << "Final-GC-lowering didn't eliminate all intrinsics'" << F.getName() << "', dumping entire module!\n\n"; \ + errs() << *F.getParent() << "\n"; \ + abort(); \ + } \ + } while (0) + IS_INTRINSIC(newGCFrame); + IS_INTRINSIC(pushGCFrame); + IS_INTRINSIC(popGCFrame); + IS_INTRINSIC(getGCFrameSlot); + IS_INTRINSIC(GCAllocBytes); + IS_INTRINSIC(queueGCRoot); + IS_INTRINSIC(safepoint); + +#undef IS_INTRINSIC + } + } +#endif + return false; } PreservedAnalyses FinalLowerGCPass::run(Function &F, FunctionAnalysisManager &AM) diff --git a/src/llvm-late-gc-lowering.cpp b/src/llvm-late-gc-lowering.cpp index edb3aad8f2328..5451a57916567 100644 --- a/src/llvm-late-gc-lowering.cpp +++ b/src/llvm-late-gc-lowering.cpp @@ -1541,9 +1541,40 @@ State LateLowerGCFrame::LocalScan(Function &F) { assert(cast(CI->getArgOperand(0)->getType())->isOpaqueOrPointeeTypeMatches(getAttributeAtIndex(CI->getAttributes(), 1, Attribute::StructRet).getValueAsType())); auto tracked = CountTrackedPointers(ElT, true); if (tracked.count) { - AllocaInst *SRet = dyn_cast((CI->arg_begin()[0])->stripInBoundsOffsets()); - assert(SRet); - { + SmallVector allocas; + Value *SRetArg = (CI->arg_begin()[0])->stripInBoundsOffsets(); + if (AllocaInst *OneSRet = dyn_cast(SRetArg)) { + allocas.push_back(OneSRet); + } else { + SmallVector worklist; + worklist.push_back(SRetArg); + while (!worklist.empty()) { + Value *V = worklist.pop_back_val(); + if (AllocaInst *Alloca = dyn_cast(V->stripInBoundsOffsets())) { + allocas.push_back(Alloca); + } else if (PHINode *Phi = dyn_cast(V)) { + for (Value *Incoming : Phi->incoming_values()) { + worklist.push_back(Incoming); + } + } else if (SelectInst *SI = dyn_cast(SRetArg)) { + AllocaInst *TrueSRet = dyn_cast(SI->getTrueValue()); + AllocaInst *FalseSRet = dyn_cast(SI->getFalseValue()); + if (TrueSRet && FalseSRet) { + worklist.push_back(TrueSRet); + worklist.push_back(FalseSRet); + } else { + llvm_dump(SI); + assert(false && "Malformed Select"); + } + } else { + llvm_dump(V); + assert(false && "Unexpected SRet argument"); + } + } + } + assert(allocas.size() > 0); + assert(std::all_of(allocas.begin(), allocas.end(), [&] (AllocaInst* SRetAlloca) {return (SRetAlloca->getArraySize() == allocas[0]->getArraySize() && SRetAlloca->getAllocatedType() == allocas[0]->getAllocatedType());})); + for (AllocaInst *SRet : allocas) { if (!(SRet->isStaticAlloca() && isa(ElT) && ElT->getPointerAddressSpace() == AddressSpace::Tracked)) { assert(!tracked.derived); if (tracked.all) { @@ -1551,35 +1582,38 @@ State LateLowerGCFrame::LocalScan(Function &F) { } else { Value *arg1 = (CI->arg_begin()[1])->stripInBoundsOffsets(); - AllocaInst *SRet_gc = nullptr; - if (PHINode *Phi = dyn_cast(arg1)) { - for (Value *V : Phi->incoming_values()) { - if (AllocaInst *Alloca = dyn_cast(V->stripInBoundsOffsets())) { - if (SRet_gc == nullptr) { - SRet_gc = Alloca; - } else if (SRet_gc == Alloca) { - continue; - } else { - llvm_dump(Alloca); - llvm_dump(SRet_gc); - assert(false && "Allocas in Phi node should match"); - } + SmallVector gc_allocas; + SmallVector worklist; + worklist.push_back(arg1); + while (!worklist.empty()) { + Value *V = worklist.pop_back_val(); + if (AllocaInst *Alloca = dyn_cast(V->stripInBoundsOffsets())) { + gc_allocas.push_back(Alloca); + } else if (PHINode *Phi = dyn_cast(V)) { + for (Value *Incoming : Phi->incoming_values()) { + worklist.push_back(Incoming); + } + } else if (SelectInst *SI = dyn_cast(arg1)) { + AllocaInst *TrueSRet = dyn_cast(SI->getTrueValue()); + AllocaInst *FalseSRet = dyn_cast(SI->getFalseValue()); + if (TrueSRet && FalseSRet) { + worklist.push_back(TrueSRet); + worklist.push_back(FalseSRet); } else { - llvm_dump(V->stripInBoundsOffsets()); - assert(false && "Expected alloca"); + llvm_dump(SI); + assert(false && "Malformed Select"); } + } else { + llvm_dump(V); + assert(false && "Unexpected SRet argument"); } - } else { - SRet_gc = dyn_cast(arg1); } - if (!SRet_gc) { - llvm_dump(CI); - llvm_dump(arg1); - assert(false && "Expected alloca"); - } - Type *ElT = SRet_gc->getAllocatedType(); - if (!(SRet_gc->isStaticAlloca() && isa(ElT) && ElT->getPointerAddressSpace() == AddressSpace::Tracked)) { - S.ArrayAllocas[SRet_gc] = tracked.count * cast(SRet_gc->getArraySize())->getZExtValue(); + + assert(gc_allocas.size() > 0); + assert(std::all_of(gc_allocas.begin(), gc_allocas.end(), [&] (AllocaInst* SRetAlloca) {return (SRetAlloca->getArraySize() == gc_allocas[0]->getArraySize() && SRetAlloca->getAllocatedType() == gc_allocas[0]->getAllocatedType());})); + for (AllocaInst *SRet_gc : gc_allocas) { + if (!(SRet_gc->isStaticAlloca() && isa(ElT) && ElT->getPointerAddressSpace() == AddressSpace::Tracked)) + S.ArrayAllocas[SRet_gc] = tracked.count * cast(SRet_gc->getArraySize())->getZExtValue(); } } }