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

Tapir interaction with Global Value Numbering (GVN) #98

Closed
ehein6 opened this issue Nov 19, 2019 · 3 comments
Closed

Tapir interaction with Global Value Numbering (GVN) #98

ehein6 opened this issue Nov 19, 2019 · 3 comments

Comments

@ehein6
Copy link

ehein6 commented Nov 19, 2019

I'm implementing Tapir lowering for a new backend. Found a case where the Global Value Numbering (GVN) optimization breaks my code by hoisting a load above a lowered call to cilk_sync. I see there is Tapir-specific code in the GVN pass to block this optimization when a load depends on a detach. For example, this block of code activates when GVN runs before Tapir lowering:

// If we depend on a detach instruction, reject.
for (unsigned i = 0, e = NumDeps; i != e; ++i) {
MemDepResult DepInfo = Deps[i].getResult();
if (!(DepInfo.getInst()))
continue;
if (isa<DetachInst>(DepInfo.getInst())||
isa<SyncInst>(DepInfo.getInst())) {
DEBUG(dbgs() << "GVN: Cannot process" << *LI <<
" due to dependency on" <<
*(DepInfo.getInst()) << "\n");
return false;
}
}

In my case, GVN runs again after lowering, and by this point there's nothing special about the sync or detach blocks. What constraint is supposed to prevent this? Or is it just not safe to do GVN after lowering?

Probably you would like to see an example, will post later.

@VictorYing
Copy link
Contributor

Is your lowered call to cilk_sync treated by LLVM as readonly or readnone? I don't have access to that emusolutions repo you linked to, but, can you make the construct you're lowering your sync to into something that LLVM thinks may write to memory that might alias with the load? This approach (making syncs (and spawns) appear to have side effects in memory to prevent reordering) is discussed in the alias analysis section of the original Tapir paper. A quick hack to try might be to just insert a memory barrier/fence next to the sync during lowering.

@ehein6
Copy link
Author

ehein6 commented Nov 20, 2019

I see now that the __cilk_sync for x86, once inlined, emits volatile loads and stores, in addition to inline assembly. Probably this is what blocks GVN. Thanks for the tip, I'll give this a try.

I don't have access to that emusolutions repo you linked to

Sorry about that, edited my post to point to the public fork

@ehein6
Copy link
Author

ehein6 commented Dec 6, 2019

Converting the loads within __cilk_sync to volatile solved the problem, thanks.

@ehein6 ehein6 closed this as completed Dec 6, 2019
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

No branches or pull requests

2 participants