-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Strip address space after gcframe allocation #22414
Comments
This is a bit annoying since it requires rewriting essentially every single instruction. The other problem is with function signatures which you can't really update. |
Note for the missed optimizations, we can simply drop the ni requirement when we get past this pass. |
WIP. Doesn't rewrite IR yet as replacing the LLVM functions breaks because of stale EDIT: this is getting hairy. RAUW not working because of types mismatching requires us to recreate a bunch of instructions, many of which don't have "exhaustive" ctors (eg. AllocaInst alignment requires separate call). Unless I'm missing something, patching the back-ends is probably going to be easier? |
Spent some more time at it, see this branch, but it is getting unwieldy because of basically two issues:
// create a module with alloca(ptr with as) |> gep
auto M = new Module("mod", Ctx);
auto FT = FunctionType::get(Type::getVoidTy(Ctx), false);
Function *F = cast<Function>(M->getOrInsertFunction("fun", FT));
auto BB = BasicBlock::Create(Ctx, "entry", F);
IRBuilder<> Builder(Ctx);
Builder.SetInsertPoint(BB);
auto ElTy = Type::getInt32Ty(Ctx);
auto PtrTy = ElTy->getPointerTo(10);
auto Alloca = Builder.CreateAlloca(PtrTy, ConstantInt::get(ElTy, 1));
auto GEP = Builder.CreateGEP(Alloca, ConstantInt::get(ElTy, 0));
Builder.CreateRetVoid();
F->dump();
GEP->getType()->dump();
Let's now replace the alloca with one for a generic pointer (mimicking what we need to do): // plain RAUW checks type
template<typename T>
void unsafeReplaceAllUsesWith(T *from, T *to) {
while (!from->use_empty()) {
auto &U = *from->use_begin();
U.set(to);
}
}
auto GenericPtrTy = ElTy->getPointerTo(0);
Builder.SetInsertPoint(Alloca);
auto GenericAlloca = Builder.CreateAlloca(GenericPtrTy, Alloca->getArraySize());
unsafeReplaceAllUsesWith(Alloca, GenericAlloca);
Alloca->eraseFromParent();
F->dump();
GEP->getType()->dump();
Surprisingly, the GEP's output type hasn't been updated. Which means we have to recreate that instruction as well...
The result of 1 + 2 is that we need to process and possible rewrite each instruction (because changes do not percolate through), while requiring special-case handling for most instructions/value. Hence all this code which doesn't even get me very far yet. |
That's actually what I'm doing in https://github.com/JuliaLang/julia/pull/22684/files#diff-396d884a3fff7980811535c6018c6f6dR192 |
Thumbs up in this. The |
What Rust does is irrelevant here... |
The use of address space for gcframe allocation is nice but currently has a few issues.
It seems that it might disable some optimizations that is legal to do after gcframe allocation
It makes
code_llvm
really hard to read. Just to give a taste, this is the code_llvm forg2(Ref(1), Ref(2))
with@noinline g2(a...) = a[1][]
.The text was updated successfully, but these errors were encountered: