[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