This was originally split out from D149889: Now that getGEPCost can more
accurately determine when an GEP will be folded, this patch updates
NaryReassociate to take advantage of it.
Unfortunately I wasn't able to create a test case for this where the GEP was
both foldable and reassociatable. Actually I couldn't find any instances of
this branch being taken since most targets can't fold more than a reg+reg add.
But posting this patch anyway for completeness sake.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/include/llvm/Analysis/TargetTransformInfo.h | ||
---|---|---|
302 | "for using getGEPCost" sounds a bit odd... maybe better say "// Helper function to get cost of already materialized GEP instruction"? | |
llvm/lib/Analysis/TargetTransformInfo.cpp | ||
243 | I don't think it's a good idea to have one more place where we define default value for AccessType. Especially taking into account it's incompatible with existing ones. The problem I see is that AccessType will be defaulted to different values depending on particular API used. It's unexpected to get different results depending if getInstructionCost or getGEPCost is used. I believe we should leave a single place (inside TargetTransformInfoImplCRTPBase::getGEPCost) where default is selected. | |
llvm/lib/Transforms/Scalar/NaryReassociate.cpp | ||
331 | It seems to be possible to simplify all other existing calls to getGEPCost the same way. Are you going to fix them as well? |
llvm/lib/Analysis/TargetTransformInfo.cpp | ||
---|---|---|
243 | Unfortunately we lose access to the GEP's users in TargetTransformInfoImplCRTPBase::getGEPCost, since it works on operands and not the GEP itself, so I'm not sure if we can calculate the default there.
getInstructionCost actually duplicates this "check first user" logic, but I agree, it's annoying to have this code duplication. IIRC I ended up duplicating it because there was no easy way to call TargetTransformInfo::getGEPCost from inside TargetTransformInfoImplCRTPBase. Maybe we could rejig this helper function to something like getGEPUserAccessType, which would then be used like getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(), Ops, getGEPUserAccessType(GEP), CostKind); | |
llvm/lib/Transforms/Scalar/NaryReassociate.cpp | ||
331 | Ideally yes, there's at least one other place in NaryReassociate that I'm aware of. I was planning on leaving that to a separate patch |
llvm/lib/Analysis/TargetTransformInfo.cpp | ||
---|---|---|
243 |
Ok, I see.
It's not quite true. getInstructionCost will use default if there is a single user while getGEPCost if there is at least one user.
Thinking out it a bit more I find the idea of choosing AccessType implicitly inside TTI problematic. Even if the GEP itself is materialized it's really implementation specific if its users have been already updated or not. For that reason I think the best would be to take AccessType into account only if it is given and don't guess. I understand having getGEPCost which takes GEP is convenient but extending TTI's API with new interfaces with complex interdependencies is error prune (due to type erased nature of TTI) . Probably the easiest solution would be to simply pass all args each time (as it's done now) or introduce say getFullyMaterializedGEPCost utility somewhere else (not inside TTI). |
"for using getGEPCost" sounds a bit odd... maybe better say "// Helper function to get cost of already materialized GEP instruction"?