[llvm] [BOLT][AArch64] Add isPush & isPop (PR #120713)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 20 02:33:40 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Alexey Moksyakov (yavtuk)
<details>
<summary>Changes</summary>
This functionality is needed for inliner pass and also for correct dyno stats.
Needed for [PR](https://github.com/llvm/llvm-project/pull/120187)
---
Full diff: https://github.com/llvm/llvm-project/pull/120713.diff
1 Files Affected:
- (modified) bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp (+405-4)
``````````diff
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 7e08e5c81d26ff..610309602771c0 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -133,6 +133,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
public:
using MCPlusBuilder::MCPlusBuilder;
+ bool isPush(const MCInst &Inst) const override {
+ return isStoreToStack(Inst);
+ };
+
+ bool isPop(const MCInst &Inst) const override {
+ return isLoadFromStack(Inst);
+ };
+
bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
CompFuncTy Comp) const override {
const auto &AArch64ExprA = cast<AArch64MCExpr>(A);
@@ -214,11 +222,16 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
bool isLDRB(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRBBpost ||
+ return (Inst.getOpcode() == AArch64::LDRBpost ||
+ Inst.getOpcode() == AArch64::LDRBBpost ||
Inst.getOpcode() == AArch64::LDRBBpre ||
Inst.getOpcode() == AArch64::LDRBBroW ||
+ Inst.getOpcode() == AArch64::LDRBroW ||
+ Inst.getOpcode() == AArch64::LDRBroX ||
Inst.getOpcode() == AArch64::LDRBBroX ||
Inst.getOpcode() == AArch64::LDRBBui ||
+ Inst.getOpcode() == AArch64::LDRBui ||
+ Inst.getOpcode() == AArch64::LDRBpre ||
Inst.getOpcode() == AArch64::LDRSBWpost ||
Inst.getOpcode() == AArch64::LDRSBWpre ||
Inst.getOpcode() == AArch64::LDRSBWroW ||
@@ -232,11 +245,16 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
}
bool isLDRH(const MCInst &Inst) const {
- return (Inst.getOpcode() == AArch64::LDRHHpost ||
+ return (Inst.getOpcode() == AArch64::LDRHpost ||
+ Inst.getOpcode() == AArch64::LDRHHpost ||
Inst.getOpcode() == AArch64::LDRHHpre ||
+ Inst.getOpcode() == AArch64::LDRHroW ||
Inst.getOpcode() == AArch64::LDRHHroW ||
+ Inst.getOpcode() == AArch64::LDRHroX ||
Inst.getOpcode() == AArch64::LDRHHroX ||
Inst.getOpcode() == AArch64::LDRHHui ||
+ Inst.getOpcode() == AArch64::LDRHui ||
+ Inst.getOpcode() == AArch64::LDRHpre ||
Inst.getOpcode() == AArch64::LDRSHWpost ||
Inst.getOpcode() == AArch64::LDRSHWpre ||
Inst.getOpcode() == AArch64::LDRSHWroW ||
@@ -265,8 +283,150 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.getOpcode() == AArch64::LDRXui);
}
+ bool isLDRS(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRSui ||
+ Inst.getOpcode() == AArch64::LDRSWui ||
+ Inst.getOpcode() == AArch64::LDRSWpre ||
+ Inst.getOpcode() == AArch64::LDRSpre ||
+ Inst.getOpcode() == AArch64::LDRSpost ||
+ Inst.getOpcode() == AArch64::LDRSWpost ||
+ Inst.getOpcode() == AArch64::LDRSWroW ||
+ Inst.getOpcode() == AArch64::LDRSWroX ||
+ Inst.getOpcode() == AArch64::LDRSroW ||
+ Inst.getOpcode() == AArch64::LDRSroX);
+ }
+
+ bool isLDRD(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRDui ||
+ Inst.getOpcode() == AArch64::LDRDpre ||
+ Inst.getOpcode() == AArch64::LDRDpost ||
+ Inst.getOpcode() == AArch64::LDRDroW ||
+ Inst.getOpcode() == AArch64::LDRDroX);
+ }
+
+ bool isLDRQ(const MCInst &Inst) const {
+ return (Inst.getOpcode() == AArch64::LDRQui ||
+ Inst.getOpcode() == AArch64::LDRQpre ||
+ Inst.getOpcode() == AArch64::LDRQpost ||
+ Inst.getOpcode() == AArch64::LDRQroW ||
+ Inst.getOpcode() == AArch64::LDRQroX);
+ }
+
+ bool isLoadPair(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isLoadPairImmOffset = [&]() {
+ bool isLoadPair = false;
+ switch (opcode) {
+ case AArch64::LDPWi:
+ case AArch64::LDPXi:
+ case AArch64::LDPSi:
+ case AArch64::LDPSWi:
+ case AArch64::LDPDi:
+ case AArch64::LDPQi:
+ case AArch64::LDNPWi:
+ case AArch64::LDNPXi:
+ case AArch64::LDNPSi:
+ case AArch64::LDNPDi:
+ case AArch64::LDNPQi:
+ isLoadPair = true;
+ break;
+ default:
+ break;
+ }
+ return isLoadPair;
+ };
+
+ auto isLoadPairPostIndex = [&]() {
+ bool isLoadPair = false;
+ switch (opcode) {
+ case AArch64::LDPWpost:
+ case AArch64::LDPXpost:
+ case AArch64::LDPSpost:
+ case AArch64::LDPSWpost:
+ case AArch64::LDPDpost:
+ case AArch64::LDPQpost:
+ isLoadPair = true;
+ break;
+ default:
+ break;
+ }
+ return isLoadPair;
+ };
+
+ auto isLoadPairPreIndex = [&]() {
+ bool isLoadPair = false;
+ switch (opcode) {
+ case AArch64::LDPWpre:
+ case AArch64::LDPXpre:
+ case AArch64::LDPSpre:
+ case AArch64::LDPSWpre:
+ case AArch64::LDPDpre:
+ case AArch64::LDPQpre:
+ isLoadPair = true;
+ break;
+ default:
+ break;
+ }
+ return isLoadPair;
+ };
+
+ return isLoadPairImmOffset() || isLoadPairPostIndex() ||
+ isLoadPairPreIndex();
+ }
+
+ bool isLoadRegUnscaleImm(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isLoad = false;
+ switch (opcode) {
+ case AArch64::LDURBi:
+ case AArch64::LDURBBi:
+ case AArch64::LDURHi:
+ case AArch64::LDURHHi:
+ case AArch64::LDURWi:
+ case AArch64::LDURXi:
+ case AArch64::LDURSi:
+ case AArch64::LDURDi:
+ case AArch64::LDURQi:
+ case AArch64::LDURSBWi:
+ case AArch64::LDURSBXi:
+ case AArch64::LDURSHWi:
+ case AArch64::LDURSHXi:
+ case AArch64::LDURSWi:
+ isLoad = true;
+ break;
+ default:
+ break;
+ }
+ return isLoad;
+ }
+
+ bool isLoadRegUnscaleUnpriv(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isLoad = false;
+ switch (opcode) {
+ case AArch64::LDTRBi:
+ case AArch64::LDTRHi:
+ case AArch64::LDTRWi:
+ case AArch64::LDTRXi:
+ case AArch64::LDTRSBWi:
+ case AArch64::LDTRSHWi:
+ case AArch64::LDTRSBXi:
+ case AArch64::LDTRSHXi:
+ case AArch64::LDTRSWi:
+ isLoad = true;
+ break;
+ default:
+ break;
+ }
+ return isLoad;
+ }
+
bool mayLoad(const MCInst &Inst) const override {
- return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst);
+ return isLoadPair(Inst) || isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) ||
+ isLDRX(Inst) || isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst) ||
+ isLoadRegUnscaleImm(Inst) || isLoadRegUnscaleUnpriv(Inst) ||
+ isPrefetch(Inst);
}
bool isAArch64ExclusiveLoad(const MCInst &Inst) const override {
@@ -1140,7 +1300,248 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
Inst.addOperand(MCOperand::createImm(0));
}
- bool mayStore(const MCInst &Inst) const override { return false; }
+ bool isPrefetch(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isNeedle = false;
+ switch (opcode) {
+ case AArch64::PRFMl:
+ case AArch64::PRFMui:
+ case AArch64::PRFUMi:
+ case AArch64::PRFMroW:
+ case AArch64::PRFMroX:
+ isNeedle = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isNeedle;
+ };
+
+ bool isStorePair(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+
+ auto isStorePairImmOffset = [&]() {
+ bool isStorePair = false;
+ 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:
+ isStorePair = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStorePair;
+ };
+
+ auto isStorePairPostIndex = [&]() {
+ bool isStorePair = false;
+ switch (opcode) {
+ case AArch64::STPWpost:
+ case AArch64::STPXpost:
+ case AArch64::STPSpost:
+ case AArch64::STPDpost:
+ case AArch64::STPQpost:
+ isStorePair = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStorePair;
+ };
+
+ auto isStorePairPreIndex = [&]() {
+ bool isStorePair = false;
+ switch (opcode) {
+ case AArch64::STPWpre:
+ case AArch64::STPXpre:
+ case AArch64::STPSpre:
+ case AArch64::STPDpre:
+ case AArch64::STPQpre:
+ isStorePair = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStorePair;
+ };
+
+ return isStorePairImmOffset() || isStorePairPostIndex() ||
+ isStorePairPreIndex();
+ }
+
+ bool isStoreReg(const MCInst &Inst) const {
+ const unsigned opcode = Inst.getOpcode();
+ bool isStore = false;
+
+ 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:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ 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:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ 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:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ 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:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ auto isStoreRegUnscaleUnpriv = [&]() {
+ switch (opcode) {
+ case AArch64::STTRBi:
+ case AArch64::STTRHi:
+ case AArch64::STTRWi:
+ case AArch64::STTRXi:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ 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:
+ isStore = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return isStore;
+ };
+
+ return isStoreRegUnscaleImm() || isStoreRegScaledImm() ||
+ isStoreRegImmPreIndexed() || isStoreRegImmPostIndexed() ||
+ isStoreRegUnscaleUnpriv() || isPrefetch(Inst) || 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 || Reg == AArch64::FP ||
+ Reg == AArch64::W29)
+ return true;
+ }
+ return false;
+ }
void createDirectCall(MCInst &Inst, const MCSymbol *Target, MCContext *Ctx,
bool IsTailCall) override {
``````````
</details>
https://github.com/llvm/llvm-project/pull/120713
More information about the llvm-commits
mailing list