This is an archive of the discontinued LLVM Phabricator instance.

Introduce G_CONSTANT_FOLD_BARRIER and use it to prevent constant folding hoisted constants.
ClosedPublic

Authored by aemerson on Jun 1 2023, 3:18 PM.

Details

Summary

This obsoletes D150179

The constant hoisting pass tries to hoist large constants into predecessors and also
generates remat instructions in terms of the hoisted constants. These aim to prevent
codegen from rematerializing expensive constants multiple times. So we can re-use
this optimization, we can preserve the no-op bitcasts that are used to anchor
constants to the predecessor blocks.

SelectionDAG achieves this by having the OpaqueConstant node, which is just a
normal constant with an opaque flag set. I've opted to avoid introducing a new
constant generic instruction here. Instead, we have a new G_CONSTANT_FOLD_BARRIER operation that
constitutes a folding barrier.

These are somewhat like the optimization hints, G_ASSERT_ZEXT in that they're
eliminated by the generic instruction selection code.

This change by itself has very minor improvements in -Os CTMark overall. What this
does allow is better optimizations when future combines are added that rely on having
expensive constants remain unfolded.

Diff Detail

Event Timeline

aemerson created this revision.Jun 1 2023, 3:18 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 1 2023, 3:18 PM
aemerson requested review of this revision.Jun 1 2023, 3:18 PM
tschuett added inline comments.Jun 1 2023, 11:25 PM
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
1475

I would have expected the size to be part of the heuristic. Why G_OPAQUE an i1?

aemerson added inline comments.Jun 2 2023, 12:13 AM
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
1475

There's no heuristic here. The heuristics are used in ConstantHoisting which uses NOP bitcasts hide constants. Here we're just recognizing those nop bitcasts and using G_OPAQUE accordingly.

arsenm added inline comments.Jun 2 2023, 12:21 PM
llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-hoisted-constants.ll
108

Add some cases with vectors and FP types?

aemerson added inline comments.Jun 2 2023, 10:16 PM
llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-hoisted-constants.ll
108

ConstantHoisting doesn't seem to hoist any vector or FP constants at all.

Thanks a lot for making this change :)

llvm/docs/GlobalISel/GenericOpcode.rst
945

I would generalize this to "prevent optimizations such as constant folding, sinking, or other combines."

llvm/include/llvm/Support/TargetOpcodes.def
335

Same, this may be used for other combines so I'd just say "Combine optimization barrier" ?

llvm/include/llvm/Target/GenericOpcodes.td
1477

ditto

llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
170–171

Could G_OPAQUE go in isPreISelGenericOptimizationHint as it's also some kind of optimization hint (barrier)?

aemerson added inline comments.Jun 5 2023, 9:19 AM
llvm/docs/GlobalISel/GenericOpcode.rst
945

That's fine, but should make it clear that this is an optimization barrier only for constants, not all operations. We shouldn't make the semantics too strong such that we struggle to enforce it.

llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
170–171

I initially thought that, but isPreISelGenericOptimizationHint() is used as a means to look through copy-like instructions in getDefSrcRegIgnoringCopies() so that would be the opposite of what we want.

Would G_OPAQUE_CONSTANTbe an improvement in intent? It is a constant that you cannot fold.

Would G_OPAQUE_CONSTANTbe an improvement in intent? It is a constant that you cannot fold.

Are you suggesting introducing a new form of constant? I didn't want to go down that route because we'd end up having 2 different representations of constants, 2 sets of legality rules etc.

I know that you don't like it, but the meaning of G_OPAQUE was not clear. G_OPAQUE_CONSTANT and G_OPAQUE_OPERATION to prevent constant folding and to prevent generic optimizations.

aemerson added a comment.EditedJun 5 2023, 9:35 PM

I know that you don't like it, but the meaning of G_OPAQUE was not clear. G_OPAQUE_CONSTANT and G_OPAQUE_OPERATION to prevent constant folding and to prevent generic optimizations.

Ok so you're just talking about renaming this opcode? As a noun though G_OPAQUE_CONSTANT would be inaccurate since it's not actually a constant. Perhaps G_CONSTANT_BARRIER or something?

At the moment we have no use case for a generic G_OPAQUE_OPERATION.

G_CONSTANT_FOLD_BARRIER

G_CONSTANT_FOLD_BARRIER

SGTM. I'll make that change.

aemerson updated this revision to Diff 528927.Jun 6 2023, 10:25 AM
aemerson retitled this revision from Introduce G_OPAQUE and use it to prevent constant folding hoisted constants. to Introduce G_CONSTANT_FOLD_BARRIER and use it to prevent constant folding hoisted constants..
aemerson edited the summary of this revision. (Show Details)

Rename to G_CONSTANT_FOLD_BARRIER

Pierre-vh accepted this revision.Jun 9 2023, 12:43 AM

LGTM

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
85

Will other targets (e.g. AMDGPU) need this?

This revision is now accepted and ready to land.Jun 9 2023, 12:43 AM
aemerson added inline comments.Jun 9 2023, 10:31 AM
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
85

Maybe, but I'd like to leave that to AMDGPU maintainers to decide how to legalize this. I'm not even sure of constant hoisting is used for AMDGPU.

arsenm accepted this revision.Jun 9 2023, 11:11 AM
arsenm added inline comments.
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
85

It's a bit obnoxious to have to add this to every target's legalize rules. Should probably have a default lower action that just deletes it.

aemerson added inline comments.Jun 9 2023, 11:19 AM
llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
85

Yes, agreed. Default rules have been something I've wanted for ages.