Hello all,
I want to add a custom intrinsic to the LLVM IR which would be lowered into a pseudo instruction since it doesn’t correspond to any real instruction defined by the architecture. The speciality of this intrinsic/pseudo instruction that it should behave like a scheduling barrier: every instruction before the intrinsic has to be emitted before the intrinsic, the same goes for all instructions after the intrinsic, and this should hold after any optimization in opt and llc.
Can anyone tell me if this is something available in the current LLVM infrastructure and if so, what should be the correct way to create this intrinsic/pseudo instruction? Which bit should be set to 1? isBarrier or hasSideEffects or both? I cannot find the documentation for these 2 bits other than the comments in Target.td, so I’d like to have some explanation here.
Thank you so much for your help,
Hi,
I want to add a custom intrinsic to the LLVM IR which would be lowered into a pseudo instruction since it doesn't correspond to any real instruction defined by the architecture. The speciality of this intrinsic/pseudo instruction that it should behave like a scheduling barrier: every instruction before the intrinsic has to be emitted before the intrinsic, the same goes for all instructions after the intrinsic, and this should hold after any optimization in opt and llc.
That's going to be very difficult. LLVM allows intrinsics to have
unmodelled side-effects that prevent reordering with instructions that
might also have side-effects (including loads and stores). But it
assumes that simple arithmetic instructions (like "add") have no
effect other than what's in the IR so they can be freely moved past
anything.
The difference occasionally comes up when people want begin-benchmark
and end-benchmark intrinsics, but really the whole concept of what's
calculated between two points is pretty fuzzy.
Which bit should be set to 1? isBarrier or hasSideEffects or both?
hasSideEffects is the closest, with the caveats above.
isBarrier has nothing to do with fences. It's applied to unconditional
branches so that LLVM knows that a basic-block ending with that
instruction won't fall-through.
Cheers.
Tim.
Hi Tim,
Thank you a lot for your reply. So IIUC, optimization passes in opt do not reorder IR instructions, only passes in llc that move MIR instructions around. Is it correct?
On the back-end (llc) side, hasSideEffects might prevent some reordering. But I just learn about TargetInstrInfo::isSchedulingBoundary. Can you tell me what are the differences between the two please?
Thank you very much (again),
Hi Son,
So IIUC, optimization passes in opt do not reorder IR instructions, only passes in llc that move MIR instructions around. Is it correct?
I don't think active scheduling (i.e. trying to optimize order for
speed) goes on in IR, but incidental movements will definitely happen.
On the back-end (llc) side, hasSideEffects might prevent some reordering. But I just learn about TargetInstrInfo::isSchedulingBoundary. Can you tell me what are the differences between the two please?
Not in detail, I'm afraid. I'd never heard of isSchedulingBoundary
before. It looks like it might improve matters if you really want to
enforce no movement, but it wasn't designed for the purpose so I
couldn't guarantee it.
Cheers.
Tim.
Hi Son,
So IIUC, optimization passes in opt do not reorder IR instructions, only passes in llc that move MIR instructions around. Is it correct?
I don't think active scheduling (i.e. trying to optimize order for
speed) goes on in IR, but incidental movements will definitely happen.
On the back-end (llc) side, hasSideEffects might prevent some reordering. But I just learn about TargetInstrInfo::isSchedulingBoundary. Can you tell me what are the differences between the two please?
Not in detail, I'm afraid. I'd never heard of isSchedulingBoundary
before. It looks like it might improve matters if you really want to
enforce no movement, but it wasn't designed for the purpose so I
couldn't guarantee it.
I believe isSchedulingBoundary is a tool to designate scheduling areas for the machine scheduler. I don't think it will prevent movement in all cases. I would not expect things like MachineLICM or SelectionDAG combines to look at it when they deal with instructions without side effects or memory operands...
Hi Tim and Matthias,
Thank you a lot for your replies. So currently LLVM doesn’t have any mechanism to strictly prevent any reordering in any level (IR, DAG or MIR), is it something desirable?
@Tim Northover
I don’t think active scheduling (i.e. trying to optimize order for
speed) goes on in IR, but incidental movements will definitely happen.
So is there any way to prevent these incidental movements in the IR?
Again, thanks for your help