[llvm] [BOLT][AArch64] Add isPush & isPop (PR #120713)
Alexey Moksyakov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 17 05:04:59 PST 2025
https://github.com/yavtuk updated https://github.com/llvm/llvm-project/pull/120713
>From a09e0d862578ceda34ce38a78d5727085271accb Mon Sep 17 00:00:00 2001
From: Moksyakov Alexey <yavtuk at yandex.ru>
Date: Fri, 20 Dec 2024 09:18:41 +0000
Subject: [PATCH] [BOLT][Aarch64] Add isPush & isPop checking
This functionality is needed for inliner pass and also
for correct dyno stats.
---
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 446 ++++++++++++++++--
1 file changed, 400 insertions(+), 46 deletions(-)
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index d84da10b5bbe69..0b6f21527f0acf 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -134,10 +134,15 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
using MCPlusBuilder::MCPlusBuilder;
MCPhysReg getStackPointer() const override { return AArch64::SP; }
+ MCPhysReg getFramePointer() const override { return AArch64::FP; }
- bool isPush(const MCInst &Inst) const override { return false; }
+ bool isPush(const MCInst &Inst) const override {
+ return isStoreToStack(Inst);
+ };
- bool isPop(const MCInst &Inst) const override { return false; }
+ bool isPop(const MCInst &Inst) const override {
+ return isLoadFromStack(Inst);
+ };
void createCall(MCInst &Inst, const MCSymbol *Target,
MCContext *Ctx) override {
@@ -244,59 +249,207 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
bool isLDRB(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRBBpost ||
- Inst.getOpcode() == AArch64::LDRBBpre ||
- Inst.getOpcode() == AArch64::LDRBBroW ||
- Inst.getOpcode() == AArch64::LDRBBroX ||
- Inst.getOpcode() == AArch64::LDRBBui ||
- Inst.getOpcode() == AArch64::LDRSBWpost ||
- Inst.getOpcode() == AArch64::LDRSBWpre ||
- Inst.getOpcode() == AArch64::LDRSBWroW ||
- Inst.getOpcode() == AArch64::LDRSBWroX ||
- Inst.getOpcode() == AArch64::LDRSBWui ||
- Inst.getOpcode() == AArch64::LDRSBXpost ||
- Inst.getOpcode() == AArch64::LDRSBXpre ||
- Inst.getOpcode() == AArch64::LDRSBXroW ||
- Inst.getOpcode() == AArch64::LDRSBXroX ||
- Inst.getOpcode() == AArch64::LDRSBXui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRBpost:
+ case AArch64::LDRBBpost:
+ case AArch64::LDRBBpre:
+ case AArch64::LDRBBroW:
+ case AArch64::LDRBroW:
+ case AArch64::LDRBroX:
+ case AArch64::LDRBBroX:
+ case AArch64::LDRBBui:
+ case AArch64::LDRBui:
+ case AArch64::LDRBpre:
+ case AArch64::LDRSBWpost:
+ case AArch64::LDRSBWpre:
+ case AArch64::LDRSBWroW:
+ case AArch64::LDRSBWroX:
+ case AArch64::LDRSBWui:
+ case AArch64::LDRSBXpost:
+ case AArch64::LDRSBXpre:
+ case AArch64::LDRSBXroW:
+ case AArch64::LDRSBXroX:
+ case AArch64::LDRSBXui:
+ case AArch64::LDURBi:
+ case AArch64::LDURBBi:
+ case AArch64::LDURSBWi:
+ case AArch64::LDURSBXi:
+ case AArch64::LDTRBi:
+ case AArch64::LDTRSBWi:
+ case AArch64::LDTRSBXi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool isLDRH(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRHHpost ||
- Inst.getOpcode() == AArch64::LDRHHpre ||
- Inst.getOpcode() == AArch64::LDRHHroW ||
- Inst.getOpcode() == AArch64::LDRHHroX ||
- Inst.getOpcode() == AArch64::LDRHHui ||
- Inst.getOpcode() == AArch64::LDRSHWpost ||
- Inst.getOpcode() == AArch64::LDRSHWpre ||
- Inst.getOpcode() == AArch64::LDRSHWroW ||
- Inst.getOpcode() == AArch64::LDRSHWroX ||
- Inst.getOpcode() == AArch64::LDRSHWui ||
- Inst.getOpcode() == AArch64::LDRSHXpost ||
- Inst.getOpcode() == AArch64::LDRSHXpre ||
- Inst.getOpcode() == AArch64::LDRSHXroW ||
- Inst.getOpcode() == AArch64::LDRSHXroX ||
- Inst.getOpcode() == AArch64::LDRSHXui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRHpost:
+ case AArch64::LDRHHpost:
+ case AArch64::LDRHHpre:
+ case AArch64::LDRHroW:
+ case AArch64::LDRHHroW:
+ case AArch64::LDRHroX:
+ case AArch64::LDRHHroX:
+ case AArch64::LDRHHui:
+ case AArch64::LDRHui:
+ case AArch64::LDRHpre:
+ case AArch64::LDRSHWpost:
+ case AArch64::LDRSHWpre:
+ case AArch64::LDRSHWroW:
+ case AArch64::LDRSHWroX:
+ case AArch64::LDRSHWui:
+ case AArch64::LDRSHXpost:
+ case AArch64::LDRSHXpre:
+ case AArch64::LDRSHXroW:
+ case AArch64::LDRSHXroX:
+ case AArch64::LDRSHXui:
+ case AArch64::LDURHi:
+ case AArch64::LDURHHi:
+ case AArch64::LDURSHWi:
+ case AArch64::LDURSHXi:
+ case AArch64::LDTRHi:
+ case AArch64::LDTRSHWi:
+ case AArch64::LDTRSHXi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool isLDRW(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRWpost ||
- Inst.getOpcode() == AArch64::LDRWpre ||
- Inst.getOpcode() == AArch64::LDRWroW ||
- Inst.getOpcode() == AArch64::LDRWroX ||
- Inst.getOpcode() == AArch64::LDRWui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRWpost:
+ case AArch64::LDRWpre:
+ case AArch64::LDRWroW:
+ case AArch64::LDRWroX:
+ case AArch64::LDRWui:
+ case AArch64::LDRWl:
+ case AArch64::LDRSWl:
+ case AArch64::LDURWi:
+ case AArch64::LDRSWpost:
+ case AArch64::LDRSWpre:
+ case AArch64::LDRSWroW:
+ case AArch64::LDRSWroX:
+ case AArch64::LDRSWui:
+ case AArch64::LDURSWi:
+ case AArch64::LDTRWi:
+ case AArch64::LDTRSWi:
+ case AArch64::LDPWi:
+ case AArch64::LDPWpost:
+ case AArch64::LDPWpre:
+ case AArch64::LDPSWi:
+ case AArch64::LDPSWpost:
+ case AArch64::LDPSWpre:
+ case AArch64::LDNPWi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool isLDRX(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRXpost ||
- Inst.getOpcode() == AArch64::LDRXpre ||
- Inst.getOpcode() == AArch64::LDRXroW ||
- Inst.getOpcode() == AArch64::LDRXroX ||
- Inst.getOpcode() == AArch64::LDRXui);
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRXpost:
+ case AArch64::LDRXpre:
+ case AArch64::LDRXroW:
+ case AArch64::LDRXroX:
+ case AArch64::LDRXui:
+ case AArch64::LDRXl:
+ case AArch64::LDURXi:
+ case AArch64::LDTRXi:
+ case AArch64::LDNPXi:
+ case AArch64::LDPXi:
+ case AArch64::LDPXpost:
+ case AArch64::LDPXpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ bool isLDRS(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRSl:
+ case AArch64::LDRSui:
+ case AArch64::LDRSroW:
+ case AArch64::LDRSroX:
+ case AArch64::LDURSi:
+ case AArch64::LDPSi:
+ case AArch64::LDNPSi:
+ case AArch64::LDRSpre:
+ case AArch64::LDRSpost:
+ case AArch64::LDPSpost:
+ case AArch64::LDPSpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ bool isLDRD(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRDl:
+ case AArch64::LDRDui:
+ case AArch64::LDRDpre:
+ case AArch64::LDRDpost:
+ case AArch64::LDRDroW:
+ case AArch64::LDRDroX:
+ case AArch64::LDURDi:
+ case AArch64::LDPDi:
+ case AArch64::LDNPDi:
+ case AArch64::LDPDpost:
+ case AArch64::LDPDpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ bool isLDRQ(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ switch (opcode) {
+ case AArch64::LDRQui:
+ case AArch64::LDRQl:
+ case AArch64::LDRQpre:
+ case AArch64::LDRQpost:
+ case AArch64::LDRQroW:
+ case AArch64::LDRQroX:
+ case AArch64::LDURQi:
+ case AArch64::LDPQi:
+ case AArch64::LDNPQi:
+ case AArch64::LDPQpost:
+ case AArch64::LDPQpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
}
bool mayLoad(const MCInst &Inst) const override {
- return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
+ return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) ||
+ isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst);
}
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -340,8 +493,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
if (!Operand.isReg())
continue;
unsigned Reg = Operand.getReg();
- if (Reg == AArch64::SP || Reg == AArch64::WSP || Reg == AArch64::FP ||
- Reg == AArch64::W29)
+ if (Reg == AArch64::SP || Reg == AArch64::WSP)
return true;
}
return false;
@@ -1170,7 +1322,209 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.addOperand(MCOperand::createImm(0));
}
- bool mayStore(const MCInst &Inst) const override { return false; }
+ bool isStorePair(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isStorePairImmOffset = [&]() {
+ switch (opcode) {
+ case AArch64::STPWi:
+ case AArch64::STPXi:
+ case AArch64::STPSi:
+ case AArch64::STPDi:
+ case AArch64::STPQi:
+ case AArch64::STNPWi:
+ case AArch64::STNPXi:
+ case AArch64::STNPSi:
+ case AArch64::STNPDi:
+ case AArch64::STNPQi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStorePairPostIndex = [&]() {
+ switch (opcode) {
+ case AArch64::STPWpost:
+ case AArch64::STPXpost:
+ case AArch64::STPSpost:
+ case AArch64::STPDpost:
+ case AArch64::STPQpost:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStorePairPreIndex = [&]() {
+ switch (opcode) {
+ case AArch64::STPWpre:
+ case AArch64::STPXpre:
+ case AArch64::STPSpre:
+ case AArch64::STPDpre:
+ case AArch64::STPQpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ return isStorePairImmOffset() || isStorePairPostIndex() ||
+ isStorePairPreIndex();
+ }
+
+ bool isStoreReg(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isStoreRegUnscaleImm = [&]() {
+ switch (opcode) {
+ case AArch64::STURBi:
+ case AArch64::STURBBi:
+ case AArch64::STURHi:
+ case AArch64::STURHHi:
+ case AArch64::STURWi:
+ case AArch64::STURXi:
+ case AArch64::STURSi:
+ case AArch64::STURDi:
+ case AArch64::STURQi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStoreRegScaledImm = [&]() {
+ switch (opcode) {
+ case AArch64::STRBui:
+ case AArch64::STRBBui:
+ case AArch64::STRHui:
+ case AArch64::STRHHui:
+ case AArch64::STRWui:
+ case AArch64::STRXui:
+ case AArch64::STRSui:
+ case AArch64::STRDui:
+ case AArch64::STRQui:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStoreRegImmPostIndexed = [&]() {
+ switch (opcode) {
+ case AArch64::STRBpost:
+ case AArch64::STRBBpost:
+ case AArch64::STRHpost:
+ case AArch64::STRHHpost:
+ case AArch64::STRWpost:
+ case AArch64::STRXpost:
+ case AArch64::STRSpost:
+ case AArch64::STRDpost:
+ case AArch64::STRQpost:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStoreRegImmPreIndexed = [&]() {
+ switch (opcode) {
+ case AArch64::STRBpre:
+ case AArch64::STRBBpre:
+ case AArch64::STRHpre:
+ case AArch64::STRHHpre:
+ case AArch64::STRWpre:
+ case AArch64::STRXpre:
+ case AArch64::STRSpre:
+ case AArch64::STRDpre:
+ case AArch64::STRQpre:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStoreRegUnscaleUnpriv = [&]() {
+ switch (opcode) {
+ case AArch64::STTRBi:
+ case AArch64::STTRHi:
+ case AArch64::STTRWi:
+ case AArch64::STTRXi:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ auto isStoreRegTrunc = [&]() {
+ switch (opcode) {
+ case AArch64::STRBBroW:
+ case AArch64::STRBBroX:
+ case AArch64::STRBroW:
+ case AArch64::STRBroX:
+ case AArch64::STRDroW:
+ case AArch64::STRDroX:
+ case AArch64::STRHHroW:
+ case AArch64::STRHHroX:
+ case AArch64::STRHroW:
+ case AArch64::STRHroX:
+ case AArch64::STRQroW:
+ case AArch64::STRQroX:
+ case AArch64::STRSroW:
+ case AArch64::STRSroX:
+ case AArch64::STRWroW:
+ case AArch64::STRWroX:
+ case AArch64::STRXroW:
+ case AArch64::STRXroX:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ };
+
+ return isStoreRegUnscaleImm() || isStoreRegScaledImm() ||
+ isStoreRegImmPreIndexed() || isStoreRegImmPostIndexed() ||
+ isStoreRegUnscaleUnpriv() || isStoreRegTrunc();
+ }
+
+ bool mayStore(const MCInst &Inst) const override {
+ return isStorePair(Inst) || isStoreReg(Inst) ||
+ isAArch64ExclusiveStore(Inst);
+ }
+
+ bool isStoreToStack(const MCInst &Inst) const {
+ if (!mayStore(Inst))
+ return false;
+
+ for (const MCOperand &Operand : useOperands(Inst)) {
+ if (!Operand.isReg())
+ continue;
+
+ unsigned Reg = Operand.getReg();
+ if (Reg == AArch64::SP || Reg == AArch64::WSP)
+ return true;
+ }
+
+ return false;
+ }
void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,
bool IsTailCall) override {
More information about the llvm-commits
mailing list