Skip to content

Commit 316373a

Browse files
[llvm][AArch64] Refactor expansion of CALL_BTI and CALL_RVMARKER (llvm#80419)
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.
1 parent 2cb61a1 commit 316373a

File tree

1 file changed

+40
-47
lines changed

1 file changed

+40
-47
lines changed

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,39 @@ bool AArch64ExpandPseudo::expandSVESpillFill(MachineBasicBlock &MBB,
774774
return true;
775775
}
776776

777+
// Create a call to CallTarget, copying over all the operands from *MBBI,
778+
// starting at the regmask.
779+
static MachineInstr *createCall(MachineBasicBlock &MBB,
780+
MachineBasicBlock::iterator MBBI,
781+
const AArch64InstrInfo *TII,
782+
MachineOperand &CallTarget,
783+
unsigned RegMaskStartIdx) {
784+
unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
785+
MachineInstr *Call =
786+
BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opc)).getInstr();
787+
788+
assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
789+
"invalid operand for regular call");
790+
Call->addOperand(CallTarget);
791+
792+
// Register arguments are added during ISel, but cannot be added as explicit
793+
// operands of the branch as it expects to be B <target> which is only one
794+
// operand. Instead they are implicit operands used by the branch.
795+
while (!MBBI->getOperand(RegMaskStartIdx).isRegMask()) {
796+
auto MOP = MBBI->getOperand(RegMaskStartIdx);
797+
assert(MOP.isReg() && "can only add register operands");
798+
Call->addOperand(MachineOperand::CreateReg(
799+
MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
800+
/*isDead=*/false, /*isUndef=*/MOP.isUndef()));
801+
RegMaskStartIdx++;
802+
}
803+
for (const MachineOperand &MO :
804+
llvm::drop_begin(MBBI->operands(), RegMaskStartIdx))
805+
Call->addOperand(MO);
806+
807+
return Call;
808+
}
809+
777810
bool AArch64ExpandPseudo::expandCALL_RVMARKER(
778811
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) {
779812
// Expand CALL_RVMARKER pseudo to:
@@ -782,31 +815,12 @@ bool AArch64ExpandPseudo::expandCALL_RVMARKER(
782815
// - another branch, to the runtime function
783816
// Mark the sequence as bundle, to avoid passes moving other code in between.
784817
MachineInstr &MI = *MBBI;
785-
786-
MachineInstr *OriginalCall;
787818
MachineOperand &RVTarget = MI.getOperand(0);
788-
MachineOperand &CallTarget = MI.getOperand(1);
789-
assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
790-
"invalid operand for regular call");
791819
assert(RVTarget.isGlobal() && "invalid operand for attached call");
792-
unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
793-
OriginalCall = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
794-
OriginalCall->addOperand(CallTarget);
795-
796-
unsigned RegMaskStartIdx = 2;
797-
// Skip register arguments. Those are added during ISel, but are not
798-
// needed for the concrete branch.
799-
while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
800-
auto MOP = MI.getOperand(RegMaskStartIdx);
801-
assert(MOP.isReg() && "can only add register operands");
802-
OriginalCall->addOperand(MachineOperand::CreateReg(
803-
MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
804-
/*isDead=*/false, /*isUndef=*/MOP.isUndef()));
805-
RegMaskStartIdx++;
806-
}
807-
for (const MachineOperand &MO :
808-
llvm::drop_begin(MI.operands(), RegMaskStartIdx))
809-
OriginalCall->addOperand(MO);
820+
MachineInstr *OriginalCall =
821+
createCall(MBB, MBBI, TII, MI.getOperand(1),
822+
// Regmask starts after the RV and call targets.
823+
/*RegMaskStartIdx=*/2);
810824

811825
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ORRXrs))
812826
.addReg(AArch64::FP, RegState::Define)
@@ -834,31 +848,10 @@ bool AArch64ExpandPseudo::expandCALL_BTI(MachineBasicBlock &MBB,
834848
// - a BTI instruction
835849
// Mark the sequence as a bundle, to avoid passes moving other code in
836850
// between.
837-
838851
MachineInstr &MI = *MBBI;
839-
MachineOperand &CallTarget = MI.getOperand(0);
840-
assert((CallTarget.isGlobal() || CallTarget.isReg()) &&
841-
"invalid operand for regular call");
842-
unsigned Opc = CallTarget.isGlobal() ? AArch64::BL : AArch64::BLR;
843-
MachineInstr *Call =
844-
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)).getInstr();
845-
Call->addOperand(CallTarget);
846-
847-
// 1 because we already added the branch target above.
848-
unsigned RegMaskStartIdx = 1;
849-
// The branch is BL <target>, so we cannot attach the arguments of the called
850-
// function to it. Those must be added as implicitly used by the branch.
851-
while (!MI.getOperand(RegMaskStartIdx).isRegMask()) {
852-
auto MOP = MI.getOperand(RegMaskStartIdx);
853-
assert(MOP.isReg() && "can only add register operands");
854-
Call->addOperand(MachineOperand::CreateReg(
855-
MOP.getReg(), /*Def=*/false, /*Implicit=*/true, /*isKill=*/false,
856-
/*isDead=*/false, /*isUndef=*/MOP.isUndef()));
857-
RegMaskStartIdx++;
858-
}
859-
for (const MachineOperand &MO :
860-
llvm::drop_begin(MI.operands(), RegMaskStartIdx))
861-
Call->addOperand(MO);
852+
MachineInstr *Call = createCall(MBB, MBBI, TII, MI.getOperand(0),
853+
// Regmask starts after the call target.
854+
/*RegMaskStartIdx=*/1);
862855

863856
Call->setCFIType(*MBB.getParent(), MI.getCFIType());
864857

0 commit comments

Comments
 (0)