[llvm] [Xtensa] Implement support for the BranchRelaxation. (PR #113450)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 10 09:55:59 PST 2024


================
@@ -376,6 +459,130 @@ unsigned XtensaInstrInfo::insertBranch(
   return Count;
 }
 
+void XtensaInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
+                                           MachineBasicBlock &DestBB,
+                                           MachineBasicBlock &RestoreBB,
+                                           const DebugLoc &DL, int64_t BrOffset,
+                                           RegScavenger *RS) const {
+  assert(RS && "RegScavenger required for long branching");
+  assert(MBB.empty() &&
+         "new block should be inserted for expanding unconditional branch");
+  assert(MBB.pred_size() == 1);
+
+  MachineFunction *MF = MBB.getParent();
+  MachineRegisterInfo &MRI = MF->getRegInfo();
+  MachineConstantPool *ConstantPool = MF->getConstantPool();
+  auto *XtensaFI = MF->getInfo<XtensaMachineFunctionInfo>();
+  MachineBasicBlock *JumpToMBB = &DestBB;
+
+  if (!isInt<32>(BrOffset))
+    report_fatal_error(
+        "Branch offsets outside of the signed 32-bit range not supported");
+
+  Register ScratchReg = MRI.createVirtualRegister(&Xtensa::ARRegClass);
+  auto II = MBB.end();
+
+  // Create l32r without last operand. We will add this operand later when
+  // JumpToMMB will be calculated and placed to the ConstantPool.
+  MachineInstr &L32R = *BuildMI(MBB, II, DL, get(Xtensa::L32R), ScratchReg);
+  BuildMI(MBB, II, DL, get(Xtensa::JX)).addReg(ScratchReg, RegState::Kill);
+
+  RS->enterBasicBlockEnd(MBB);
+  Register ScavRegister =
+      RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.getIterator(),
+                                    /*RestoreAfter=*/false, /*SpAdj=*/0,
+                                    /*AllowSpill=*/false);
+  if (ScavRegister != Xtensa::NoRegister)
+    RS->setRegUsed(ScavRegister);
+  else {
+    // The case when there is no scavenged register needs special handling.
+    // Pick A8 because it doesn't make a difference
+    ScavRegister = Xtensa::A12;
+
+    int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
+    if (FrameIndex == -1)
+      report_fatal_error(
+          "Unable to properly handle scavenged register for indirect jump, "
+          "function code size is significantly larger than estimated");
+
+    storeRegToStackSlot(MBB, L32R, ScavRegister, /*IsKill=*/true, FrameIndex,
+                        &Xtensa::ARRegClass, &RI, Register());
+    RI.eliminateFrameIndex(std::prev(L32R.getIterator()),
+                           /*SpAdj=*/0, /*FIOperandNum=*/1);
+
+    loadRegFromStackSlot(RestoreBB, RestoreBB.end(), ScavRegister, FrameIndex,
+                         &Xtensa::ARRegClass, &RI, Register());
+    RI.eliminateFrameIndex(RestoreBB.back(),
+                           /*SpAdj=*/0, /*FIOperandNum=*/1);
+    JumpToMBB = &RestoreBB;
+  }
+
+  XtensaConstantPoolValue *C = XtensaConstantPoolMBB::Create(
+      MF->getFunction().getContext(), JumpToMBB, 0);
+  unsigned Idx = ConstantPool->getConstantPoolIndex(C, Align(4));
+  L32R.addOperand(MachineOperand::CreateCPI(Idx, 0));
+
+  MRI.replaceRegWith(ScratchReg, ScavRegister);
+  MRI.clearVirtRegs();
+}
+
+unsigned XtensaInstrInfo::insertConstBranchAtInst(
+    MachineBasicBlock &MBB, MachineInstr *I, int64_t offset,
+    ArrayRef<MachineOperand> Cond, DebugLoc DL, int *BytesAdded) const {
+  // Shouldn't be a fall through.
+  assert(&MBB && "InsertBranch must not be told to insert a fallthrough");
----------------
MaskRay wrote:

This led to a Clang warning -Wundefined-bool-conversion. We ensure that the code base is warning free for recent Clang versions.

Personally I use https://raw.githubusercontent.com/chromium/chromium/main/tools/clang/scripts/update.py

https://github.com/llvm/llvm-project/pull/113450


More information about the llvm-commits mailing list