With this change ImplicitNullCheck optimization uses alias analysis and
can use load/store memory access for implicit null check if there are other
load/store before but memory accesses do not alias.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
Some comments inline.
lib/CodeGen/ImplicitNullChecks.cpp | ||
---|---|---|
323 ↗ | (On Diff #89639) | s/alias/aliases/ |
329 ↗ | (On Diff #89639) | Can we pull the body of this loop out into a static helper? |
335 ↗ | (On Diff #89639) | Can we return SR_Impossible here if the MachineInstr that was the store also has no mem operands? |
342 ↗ | (On Diff #89639) | The indents are off -- please use clang-format. |
351 ↗ | (On Diff #89639) | Maybe move this check up to avoid wasting work if AA isn't available? Btw, given the way you're getting AA, I'd expect it always be present since otherwise getAnalysis<AAResultsWrapperPass>().getAAResults() will have to be a null reference which is undefined behavior. |
358 ↗ | (On Diff #89639) | What about multiple memoperands on the same machine instruction? |
Will prepapre an update.
lib/CodeGen/ImplicitNullChecks.cpp | ||
---|---|---|
323 ↗ | (On Diff #89639) | ok |
329 ↗ | (On Diff #89639) | will do |
335 ↗ | (On Diff #89639) | makes sense. |
342 ↗ | (On Diff #89639) | sure |
351 ↗ | (On Diff #89639) | we can be in a good shape even if AA is not available. Say if other instruction is a spill. See the previous check: PSV != null and PSV->mayAlias is false. So it is not good to move AA check earlier. WRT AA is not null I will double check your idea. |
358 ↗ | (On Diff #89639) | Not sure it is possible but we can iterate over mem operands. |
lib/CodeGen/ImplicitNullChecks.cpp | ||
---|---|---|
358 ↗ | (On Diff #89639) | I'd also be happy with either of:
|
Comments inline.
lib/CodeGen/ImplicitNullChecks.cpp | ||
---|---|---|
302 ↗ | (On Diff #89835) | Can we name this as a verb, like areMemoryOpsAliased? |
319 ↗ | (On Diff #89835) | This clause is a bit odd -- without this clause, the nested loop returns SR_Suitable only if all pairs of mem operands are NoAlias. But this clause returns SR_Suitable even if one of PrevMI mem operands is a PseudoSourceValue with !PSV->mayAlias(MFI). Why do we have this difference? If we have to, I'd prefer checking for PseudoSourceValue in a loop only over PrevMI->memoperands() outside this nested loop. Also: can one of MI.memoperands() be a PseudoSourceValue? If not, please add an assert. |
328 ↗ | (On Diff #89835) | Spacing is off here, but I'll run clang-format on the diff before pushing it so don't bother fixing it right now. |
364 ↗ | (On Diff #89835) | s/SR_impossible/SR_Impossible/ |
366 ↗ | (On Diff #89835) | This layering seems odd to me -- AliasMemoryOp should not return a SuitabilityResult IMO, since it has no idea on why it has been asked to compute aliasing between the two instructions. It almost feels like it should return a tri-stated AliasResult with AR_NoAlias, AR_MayAlias and AR_WillAliasEverything. That would be a bit more code, but I think the intent will be cleaner. |
addressed comments, please review.
Also I've run clang-format against ImplicitNullChecks.cpp and it shows a bit other issues not directly related to my change.
Specifically it does not like one-line enum. If you'd like I can fix it as well.
You can use git clang-format (after installing https://github.com/llvm-mirror/clang/blob/master/tools/clang-format/git-clang-format) to format just code touched by a specific commit. For instance, to format the code touched in the most recent commit, you can do git clang-format HEAD^.
Specifically it does not like one-line enum. If you'd like I can fix it as well.
lgtm with really minor tweaks
lib/CodeGen/ImplicitNullChecks.cpp | ||
---|---|---|
168 ↗ | (On Diff #89967) | The ImplicitNullChecks:: is not needed here, is it? Also, I'd prefer plural here, as areMemoryOpsAliased. |
309 ↗ | (On Diff #89967) | s/if/If/ |
324 ↗ | (On Diff #89967) | No need for the else. That is, you can say: if (...) return ...; continue; |