Targets often have constraints on their MIR that need to hold true throughout
certain regions of the backend but cannot be verified in the MachineVerifier.
Some examples include:
- Immediates must be in a certain range on a given instruction
- Certain instructions must not appear for certain subtargets
- Certain instructions must not appear in delay slots
- Fences need to occur before a some types of load but fence/load/load is preferable to fence/load/fence/load
and so on.
Sometimes, it's enough to roll verification into the pass that does the
relevant work as there's no chance of something else interfering but sometimes
there's also a risk of subsequent passes violating constraints on the MIR due
to assumptions that turn out to be untrue or just simply bugs.
This patch expands on the existing MachineVerifier mechanism by introducing
a TargetMachineVerifier that installs itself into -verify-machineinstrs and
MachineFunction::verify() and therefore runs after every pass or more
frequently if requested. The generic MachineVerifier runs first so it should be
safe for the TargetMachineVerifier to assume that the MIR is generally ok and
that defs dominate uses, etc, etc.
There's no specific mechanism for having certain verifications apply beyond (or
until) a certain point in the backend but I'd recommend using function
attributes set by a given pass (like GlobalISel) or the equivalent in
MachineFunctionInfo to achieve this.
There's a simple sample verification in AArch64 but my main focus is an out of
tree target so I haven't gone very far with verifying AArch64. I'm posting this
to see if there's general interest in having this mechanism upstream.
Long term, I foresee a VerifyMethod (to go with PrintMethod, DecodeMethod, etc.)
on Instructions and Operands in tablegen that populate this pass with sanity
checks to detect when C++ code violates constraints defined in tablegen. I'm
aware that some targets are exploiting the lack of checks to do things that
conflict with tablegen definitions so such a thing will have to be opt-in.