-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm][AArch64] Refactor expansion of CALL_BTI and CALL_RVMARKER #80419
Conversation
After a lot of churn in expandCALL_BTI, it ended up doing the exact same thing that expandCALL_RVMARKER does. This change factors out the common code to make that clear.
Still investigating a smoother way to do this, doing this along the way. |
@llvm/pr-subscribers-backend-aarch64 Author: David Spickett (DavidSpickett) ChangesAfter a lot of churn in expandCALL_BTI, it ended up doing the exact same thing that expandCALL_RVMARKER does. This change factors out the common code to make that clear. Full diff: https://github.com/llvm/llvm-project/pull/80419.diff 1 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 1af064b6de3cb..b2c52b443753d 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -774,6 +774,39 @@ bool AArch64ExpandPseudo::expandSVESpillFill(MachineBasicBlock &MBB,
return true;
}
+// Create a call to CallTarget, copying over all the operands from *MBBI,
+// starting at the regmask.
+static MachineInstr *createCall(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ const AArch64InstrInfo *TII,
+ MachineOperand &CallTarget,
+ unsigned RegMaskStartIdx) {
+ unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
+ MachineInstr *Call =
+ BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opc)).getInstr();
+
+ assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
+ "invalid operand for regular call");
+ Call->addOperand(CallTarget);
+
+ // Register arguments are added during ISel, but cannot be added as explicit
+ // operands of the branch as it expects to be B <target> which is only one
+ // operand. Instead they are implicit operands used by the branch.
+ while (!MBBI->getOperand(RegMaskStartIdx).isRegMask()) {
+ auto MOP = MBBI->getOperand(RegMaskStartIdx);
+ assert(MOP.isReg() && "can only add register operands");
+ Call->addOperand(MachineOperand::CreateReg(
+ MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
+ /*isDead=*/false, /*isUndef=*/MOP.isUndef()));
+ RegMaskStartIdx++;
+ }
+ for (const MachineOperand &MO :
+ llvm::drop_begin(MBBI->operands(), RegMaskStartIdx))
+ Call->addOperand(MO);
+
+ return Call;
+}
+
bool AArch64ExpandPseudo::expandCALL_RVMARKER(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) {
// Expand CALL_RVMARKER pseudo to:
@@ -782,31 +815,12 @@ bool AArch64ExpandPseudo::expandCALL_RVMARKER(
// - another branch, to the runtime function
// Mark the sequence as bundle, to avoid passes moving other code in between.
MachineInstr &MI = *MBBI;
-
- MachineInstr *OriginalCall;
MachineOperand &RVTarget = MI.getOperand(0);
- MachineOperand &CallTarget = MI.getOperand(1);
- assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
- "invalid operand for regular call");
assert(RVTarget.isGlobal() && "invalid operand for attached call");
- unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
- OriginalCall = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
- OriginalCall->addOperand(CallTarget);
-
- unsigned RegMaskStartIdx = 2;
- // Skip register arguments. Those are added during ISel, but are not
- // needed for the concrete branch.
- while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
- auto MOP = MI.getOperand(RegMaskStartIdx);
- assert(MOP.isReg() && "can only add register operands");
- OriginalCall->addOperand(MachineOperand::CreateReg(
- MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
- /*isDead=*/false, /*isUndef=*/MOP.isUndef()));
- RegMaskStartIdx++;
- }
- for (const MachineOperand &MO :
- llvm::drop_begin(MI.operands(), RegMaskStartIdx))
- OriginalCall->addOperand(MO);
+ MachineInstr *OriginalCall =
+ createCall(MBB, MBBI, TII, MI.getOperand(1),
+ // Regmask starts after the RV and call targets.
+ /*RegMaskStartIdx=*/2);
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORRXrs))
.addReg(AArch64::FP, RegState::Define)
@@ -834,31 +848,10 @@ bool AArch64ExpandPseudo::expandCALL_BTI(MachineBasicBlock &MBB,
// - a BTI instruction
// Mark the sequence as a bundle, to avoid passes moving other code in
// between.
-
MachineInstr &MI = *MBBI;
- MachineOperand &CallTarget = MI.getOperand(0);
- assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
- "invalid operand for regular call");
- unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
- MachineInstr *Call =
- BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
- Call->addOperand(CallTarget);
-
- // 1 because we already added the branch target above.
- unsigned RegMaskStartIdx = 1;
- // The branch is BL <target>, so we cannot attach the arguments of the called
- // function to it. Those must be added as implicitly used by the branch.
- while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
- auto MOP = MI.getOperand(RegMaskStartIdx);
- assert(MOP.isReg() && "can only add register operands");
- Call->addOperand(MachineOperand::CreateReg(
- MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
- /*isDead=*/false, /*isUndef=*/MOP.isUndef()));
- RegMaskStartIdx++;
- }
- for (const MachineOperand &MO :
- llvm::drop_begin(MI.operands(), RegMaskStartIdx))
- Call->addOperand(MO);
+ MachineInstr *Call = createCall(MBB, MBBI, TII, MI.getOperand(0),
+ // Regmask starts after the call target.
+ /*RegMaskStartIdx=*/1);
Call->setCFIType(*MBB.getParent(), MI.getCFIType());
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice cleanup, thanks!
After a lot of churn in expandCALL_BTI, it ended up doing the exact same thing that expandCALL_RVMARKER does. This change factors out the common code to make that clear.