This is an archive of the discontinued LLVM Phabricator instance.

Speed up Function::isIntrinsic() by adding a bit to GlobalValue. NFC
ClosedPublic

Authored by jlebar on Jul 28 2016, 5:00 PM.

Details

Summary

Previously isIntrinsic() called getName(). This involves a hashtable
lookup, so is nontrivially expensive. And isIntrinsic() is called
frequently, particularly by dyn_cast<IntrinsicInstr>.

This patch steals a bit of IntID and uses that to store whether or not
getName() starts with "llvm."

Diff Detail

Repository
rL LLVM

Event Timeline

jlebar updated this revision to Diff 66062.Jul 28 2016, 5:00 PM
jlebar retitled this revision from to Speed up Function::isIntrinsic() by adding a bit to GlobalValue. NFC.
jlebar updated this object.
jlebar added subscribers: llvm-commits, sanjoy.

I reverted the old change in rL277087.

Justin Bogner wrote in an email to the list:

I'm a bit less comfortable with this change than I was with the other
one - it's more of a straight performance hack this way, whereas the
other way fit better in a future where target-specific intrinsics are
more of a first class idea.

I'll let others comment on whether or not this is worth it as a
hopefully temporary thing for the performance gain in the short term.

Anyone else want to chime in here? To me it seems like a relatively simple change that gets us a substantial win, but I hear Justin B.'s position as well.

jlebar edited reviewers, added: rnk; removed: chandlerc.Aug 17 2016, 5:09 PM
rnk edited edge metadata.Aug 18 2016, 9:25 AM
rnk added a subscriber: beanz.

Justin Bogner wrote in an email to the list:

I'm a bit less comfortable with this change than I was with the other
one - it's more of a straight performance hack this way, whereas the
other way fit better in a future where target-specific intrinsics are
more of a first class idea.

Do you think we should move more towards LLVM having a single enum of all target intrinsics, or more towards a place where LLVM has target neutral intrinsics, and then there is a separate target-specific intrinsic ID space that mid-level optimizers can't know about?

This change actually seems like a step towards that world, which the AMDGPU backend is already half-in: all intrinsics are named "llvm.*" and many of them are not included in Intrinsic::ID.

Maybe in the long run we should move all target intrinsics out of include/llvm/IR/Intrinsics*.td, and down into lib/Target. We'd use TargetIntrinsicInfo to look up the ID. Then we can go back to the old, non-bitfield solution. It also makes it easier for us to compile out the intrinsic name to ID tables for disabled targets, which I think @beanz wanted to do. I don't think IR can talk to Target, so we probably can't do this the obvious way.

Sean Silva wrote on the list:

Sorry if I missed it, but do you have perf measurements posted somewhere?

Sorry, those were in the patch for the last way I tried to do this. It's good for a 1.5% e2e speedup compiling an Eigen benchmark.

In D22949#519623, @rnk wrote:

which I think @beanz wanted to do.

@bogner has taken over my primary interests in that. In general I think pushing target-specific things (like intrinsics) into targets is a really great idea. I have this pipe dream of someday being able to make dynamically loadable targets, which I think would be really cool.

chandlerc accepted this revision.Dec 28 2016, 2:22 PM
chandlerc edited edge metadata.

LGTM, let's ship it.

I alse hear Justin's concern here, especially what he wrote up on the mailing list. However, I like one thing he said: this will essentially get reverted if/when we go down that path. That seems totally fine to me considering how isolated this change is. When the time comes, it'll be easy and transparent to rip out. I think the performance hack in the interim is worth it, and will also keep us honest as we explore options to fix intrinsics in a more fundamental way by holding the higher performance bar.

-Chandler

This revision is now accepted and ready to land.Dec 28 2016, 2:22 PM
This revision was automatically updated to reflect the committed changes.
rnk added a comment.Dec 28 2016, 4:07 PM

Also, this comment in Value.h could use an update:

/// \brief Return a constant reference to the value's name.
///
/// This is cheap and guaranteed to return the same reference as long as the
/// value is not modified.
StringRef getName() const;

A hash table lookup is only cheap in grad school.

llvm/trunk/include/llvm/IR/GlobalValue.h
145

Please use unsigned so this doesn't grow Value on Windows. This program compiles without error with MSVC:

enum IntrinsicID : unsigned { ID0 = 0 };
struct Foo { IntrinsicID id : 31; bool bit : 1; };
struct Bar { IntrinsicID id : 31; unsigned bit : 1; };
static_assert(sizeof(Foo) == 8, "");
static_assert(sizeof(Bar) == 4, "");