Skip to content
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

Experiment with a slighly adjusted pipeline #52850

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open

Conversation

gbaraldi
Copy link
Member

and add GC final lowering verification.

@gbaraldi
Copy link
Member Author

@nanosoldier runbenchmarks(ALL, vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

@gbaraldi
Copy link
Member Author

@nanosoldier runbenchmarks(!"scalar", vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

@gbaraldi
Copy link
Member Author

@nanosoldier runbenchmarks(!"scalar", vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

Comment on lines +405 to +406
FPM.addPass(InstCombinePass());
FPM.addPass(AggressiveInstCombinePass());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it make sense to do 2 instcombine right next to each other?

Copy link
Member Author

@gbaraldi gbaraldi Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth customizing the AggressiveInstCombinePass slightly since the defaults include some options that are likely not useful for us specifically from https://llvm.org/doxygen/AggressiveInstCombine_8cpp.html:

  • foldSqrt is probalby useless because we generate LLVM sqrt
  • tryToRecognizePopCount probably isn't useful since we have count_ones
  • foldMemChr I don't think we use memchr (but not sure).

This is unlikely to matter much, but probably could save a bit of compile time here and there.

@vtjnash
Copy link
Member

vtjnash commented Oct 16, 2024

looks like you need to fix a couple tests:

Failed Tests (2):
2024-10-16 14:39:21 EDT	  Julia :: image-codegen.jl
2024-10-16 14:39:21 EDT	  Julia :: pipeline-prints.ll

also rerunning nanosoldier, since a lot of changes have happened since:
@nanosoldier runbenchmarks(!"scalar", vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

@oscardssmith
Copy link
Member

Looks overall pretty good, but there are a couple 10x regressions (look like vectorization failures). Is there an easy way from nanosoldier for us to test compile time to make sure it's comparable?

@Zentrik
Copy link
Member

Zentrik commented Oct 17, 2024

Isn't that what the inference benchmarks are for, which look like no change to me.

@gbaraldi
Copy link
Member Author

I took a big look at it. There's still a couple regressions, but it seems to be a pretty clear overall win. If anyone wants to take a further look

  1. ["union", "array", ("perf_countequals", "Int8")]
  2. ["array", "index", ("sumelt_boundscheck", "Base.ReinterpretArray{BaseBenchmarks.ArrayBenchmarks.PairVals{Int32}, 2, Int64, Matrix{Int64}, false}")] We are failing to elide a boundscheck
  3. The simd conditional loop ones (they are very noisy (per run and per machine)

The 16x regression is now gone with my latest commit

@gbaraldi
Copy link
Member Author

Do we want to run a pkgeval? Im slightly worried about the fact that I had to modify passes.

Comment on lines +219 to +246
#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);
auto IS_INTRINSIC = [&](auto intrinsic) {
auto intrinsic2 = getOrNull(intrinsic);
if (intrinsic2 == callee) {
errs() << "Final-GC-lowering didn't eliminate all intrinsics'" << F.getName() << "', dumping entire module!\n\n";
errs() << *F.getParent() << "\n";
abort();
}
};
IS_INTRINSIC(jl_intrinsics::newGCFrame);
IS_INTRINSIC(jl_intrinsics::pushGCFrame);
IS_INTRINSIC(jl_intrinsics::popGCFrame);
IS_INTRINSIC(jl_intrinsics::getGCFrameSlot);
IS_INTRINSIC(jl_intrinsics::GCAllocBytes);
IS_INTRINSIC(jl_intrinsics::queueGCRoot);
IS_INTRINSIC(jl_intrinsics::safepoint);
}
}
#endif
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With something like #56188 this may fail if we use llvm.compiler.used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused? Why would it fail? After this it should be an addrspacecast

}
}
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());}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting?

Comment on lines +1226 to +1228
if (TrueSRet && FalseSRet) {
worklist.push_back(TrueSRet);
worklist.push_back(FalseSRet);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if TrueSRet == FalseSRet but it hasn't been eliminated yet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the solution is to make gc_allocas a set instead of a smallvector. So if we end up pushing the same thing twice that's still fine

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());}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting

if (auto change = dyn_cast<ConstantInt>(CI->getArgOperand(1)))
Depth -= change->getLimitedValue();
else if (auto Phi = dyn_cast<PHINode>(CI->getArgOperand(1))) {
//This should really do a dataflow analysis but assuming worst case means that we will always have enough space
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//This should really do a dataflow analysis but assuming worst case means that we will always have enough space
// XXX: This should really do a dataflow analysis but assuming worst case means that we will always have enough space

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coould we have an IR test for this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one :). I was also talking with @topolarity and @vtjnash that we should just do what that pass does at codegen time and remove it.

if (auto change = dyn_cast<ConstantInt>(it.first->getArgOperand(1)))
minPops = change->getLimitedValue();
else if (auto Phi = dyn_cast<PHINode>(it.first->getArgOperand(1))) {
//This should really do a dataflow analysis but assuming worst case means that we will always have enough space
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//This should really do a dataflow analysis but assuming worst case means that we will always have enough space
// XXX: This should really do a dataflow analysis but assuming worst case means that we will always have enough space

src/pipeline.cpp Outdated
LPM.addPass(LoopRotatePass());
LPM.addPass(LoopDeletionPass());
FPM.addPass(createFunctionToLoopPassAdaptor(
std::move(LPM), /*UseMemorySSA=*/false, /*UseBlockFrequencyInfo=*/false));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::move(LPM), /*UseMemorySSA=*/false, /*UseBlockFrequencyInfo=*/false));
std::move(LPM), /*UseMemorySSA=*/false, /*UseBlockFrequencyInfo=*/false));

@vchuravy
Copy link
Member

@nanosoldier runtests(ALL, vs = ":master", configuration = (buildflags=["LLVM_ASSERTIONS=1", "FORCE_ASSERTIONS=1"],), vs_configuration = (buildflags = ["LLVM_ASSERTIONS=1", "FORCE_ASSERTIONS=1"],))

@nanosoldier
Copy link
Collaborator

The package evaluation job you requested has completed - possible new issues were detected.
The full report is available.

@gbaraldi
Copy link
Member Author

@nanosoldier runbenchmarks(ALL, vs=":master")

@nanosoldier
Copy link
Collaborator

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here.

@gbaraldi
Copy link
Member Author

["union", "array", ("map", "*", "Float64", "(false, true)")] seems to be quite a large regression in my mac 2x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants