Skip to content

Commit

Permalink
Fix git mess
Browse files Browse the repository at this point in the history
  • Loading branch information
gbaraldi committed Jan 30, 2024
1 parent 1d22e85 commit e4a27bd
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 30 deletions.
37 changes: 35 additions & 2 deletions src/llvm-final-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<CallInst>(&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)
Expand Down
90 changes: 62 additions & 28 deletions src/llvm-late-gc-lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1541,45 +1541,79 @@ State LateLowerGCFrame::LocalScan(Function &F) {
assert(cast<PointerType>(CI->getArgOperand(0)->getType())->isOpaqueOrPointeeTypeMatches(getAttributeAtIndex(CI->getAttributes(), 1, Attribute::StructRet).getValueAsType()));
auto tracked = CountTrackedPointers(ElT, true);
if (tracked.count) {
AllocaInst *SRet = dyn_cast<AllocaInst>((CI->arg_begin()[0])->stripInBoundsOffsets());
assert(SRet);
{
SmallVector<AllocaInst *> allocas;
Value *SRetArg = (CI->arg_begin()[0])->stripInBoundsOffsets();
if (AllocaInst *OneSRet = dyn_cast<AllocaInst>(SRetArg)) {
allocas.push_back(OneSRet);
} else {
SmallVector<Value *> worklist;
worklist.push_back(SRetArg);
while (!worklist.empty()) {
Value *V = worklist.pop_back_val();
if (AllocaInst *Alloca = dyn_cast<AllocaInst>(V->stripInBoundsOffsets())) {
allocas.push_back(Alloca);
} else if (PHINode *Phi = dyn_cast<PHINode>(V)) {
for (Value *Incoming : Phi->incoming_values()) {
worklist.push_back(Incoming);
}
} else if (SelectInst *SI = dyn_cast<SelectInst>(SRetArg)) {
AllocaInst *TrueSRet = dyn_cast<AllocaInst>(SI->getTrueValue());
AllocaInst *FalseSRet = dyn_cast<AllocaInst>(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<PointerType>(ElT) && ElT->getPointerAddressSpace() == AddressSpace::Tracked)) {
assert(!tracked.derived);
if (tracked.all) {
S.ArrayAllocas[SRet] = tracked.count * cast<ConstantInt>(SRet->getArraySize())->getZExtValue();
}
else {
Value *arg1 = (CI->arg_begin()[1])->stripInBoundsOffsets();
AllocaInst *SRet_gc = nullptr;
if (PHINode *Phi = dyn_cast<PHINode>(arg1)) {
for (Value *V : Phi->incoming_values()) {
if (AllocaInst *Alloca = dyn_cast<AllocaInst>(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<AllocaInst *> gc_allocas;
SmallVector<Value*> worklist;
worklist.push_back(arg1);
while (!worklist.empty()) {
Value *V = worklist.pop_back_val();
if (AllocaInst *Alloca = dyn_cast<AllocaInst>(V->stripInBoundsOffsets())) {
gc_allocas.push_back(Alloca);
} else if (PHINode *Phi = dyn_cast<PHINode>(V)) {
for (Value *Incoming : Phi->incoming_values()) {
worklist.push_back(Incoming);
}
} else if (SelectInst *SI = dyn_cast<SelectInst>(arg1)) {
AllocaInst *TrueSRet = dyn_cast<AllocaInst>(SI->getTrueValue());
AllocaInst *FalseSRet = dyn_cast<AllocaInst>(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<AllocaInst>(arg1);
}
if (!SRet_gc) {
llvm_dump(CI);
llvm_dump(arg1);
assert(false && "Expected alloca");
}
Type *ElT = SRet_gc->getAllocatedType();
if (!(SRet_gc->isStaticAlloca() && isa<PointerType>(ElT) && ElT->getPointerAddressSpace() == AddressSpace::Tracked)) {
S.ArrayAllocas[SRet_gc] = tracked.count * cast<ConstantInt>(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<PointerType>(ElT) && ElT->getPointerAddressSpace() == AddressSpace::Tracked))
S.ArrayAllocas[SRet_gc] = tracked.count * cast<ConstantInt>(SRet_gc->getArraySize())->getZExtValue();
}
}
}
Expand Down

0 comments on commit e4a27bd

Please sign in to comment.