This is an archive of the discontinued LLVM Phabricator instance.

Account for PATCHABLE instrs in Branch Relaxation
ClosedPublic

Authored by dhoekwater on Apr 10 2023, 5:25 PM.

Details

Summary

PATCHABLE_* instructions expand to up to 36-byte
sleds. Updating the size of PATCHABLE instructions
causes them to be outlined, so we need to add a
check to prevent the outliner from considering
basic blocks that contain PATCHABLE instructions.

Diff Detail

Event Timeline

dhoekwater created this revision.Apr 10 2023, 5:25 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 10 2023, 5:25 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
dhoekwater requested review of this revision.Apr 10 2023, 5:25 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 10 2023, 5:25 PM
paquette added inline comments.Apr 11 2023, 10:50 AM
llvm/lib/CodeGen/TargetInstrInfo.cpp
1653–1654

I think this could be a llvm::find_if?

return find_if(MBB.getFirstNonDebugInstr(), MBB.getLastNonDebugInstr(), [](const MachineInstr &MI) {
   unsigned Opc = MI.getOpcode();
   switch(Opc) {
      default:
          return false;
      case TargetOpcode::FENTRY_CALL:
      ...
         return true;
   }
}) != MBB.end();

That'd make it easy to add new opcodes/remove opcodes.

dhoekwater added inline comments.Apr 11 2023, 11:15 AM
llvm/lib/CodeGen/TargetInstrInfo.cpp
1653–1654

It definitely could be, and it makes the function visually a lot cleaner. Because PATCHABLE instructions are always inserted at the start or at/just before the end, the previous and current implementations are O(1) in the number of instructions.

Being fairly unfamiliar with the performance characteristics of the codebase, I was hesitant to scan through the whole basic block. If the small performance difference isn't a concern, I'd be happy to switch to llvm::find_if.

paquette added inline comments.Apr 11 2023, 11:17 AM
llvm/lib/CodeGen/TargetInstrInfo.cpp
1653–1654

Ah I see. Yeah let's keep it like this.

paquette accepted this revision.Apr 11 2023, 11:17 AM

I think it would be good to have a MIR testcase for this.

Other than that, I think this looks good.

This revision is now accepted and ready to land.Apr 11 2023, 11:17 AM

I think it would be good to have a MIR testcase for this.

branch-relax-xray.ll tests that Branch Relaxation relaxes branches that are out-of-range because of XRay sleds, and machine-outliner-patchable.ll tests that XRay sleds aren't outlined. Why the MIR test case?

I think it would be good to have a MIR testcase for this.

branch-relax-xray.ll tests that Branch Relaxation relaxes branches that are out-of-range because of XRay sleds, and machine-outliner-patchable.ll tests that XRay sleds aren't outlined. Why the MIR test case?

Because we can see clearly which MIR opcodes should not be outlined, and it defends us against other optimizer changes in earlier passes. Like, if the MIR test starts failing, we know 100% that it's an outliner issue and not some other pass dropping the X-ray ops or something.

Because we can see clearly which MIR opcodes should not be outlined, and it defends us against other optimizer changes in earlier passes. Like, if the MIR test starts failing, we know 100% that it's an outliner issue and not some other pass dropping the X-ray ops or something.

Got it, thanks! I'll write that up real quick.

Test to make sure XRay patchable instructions aren't outlined. I think technically I could break this into two separate patches now that I have two independent tests. I don't think that's necessary, but please let me know if it's preferred.

I think it's okay to keep all of this in one patch.

I put the MIR test through Compiler Explorer to see what is outlined (and removed some of the stuff that isn't necessary in MIR):

https://godbolt.org/z/e85n9Wh8r

It looks like this, without this patch, does outline something with PATCHABLE_FUNCTION_EXIT, but we don't get any outlining behaviour for PATCHABLE_FUNCTION_ENTRY.

Would it be possible to add a case where PATCHABLE_FUNCTION_ENTRY is outlined without this patch?

Because isMBBSafeToOutlineFrom already accounted for TargetOpcode::FENTRY_CALL and TargetOpcode::PATCHABLE_FUNCTION_ENTER, I won't be able to write a test that makes PATCHABLE_FUNCTION_ENTER outlined without this patch.

I could probably write a test that makes sure TargetOpcode::PATCHABLE_RET and TargetOpcode::PATCHABLE_TAIL_CALL aren't outlined, but neither of those instructions are inserted on AArch64 (they're only inserted on ppc64le and x86_64, respectively). AFAIK no test exists to make sure they aren't outlined.

This revision was automatically updated to reflect the committed changes.