summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64.td5
-rw-r--r--llvm/lib/Target/AArch64/AArch64MacroFusion.cpp33
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.h2
3 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 7721e897060..7e510a1fbd6 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -120,6 +120,10 @@ def FeatureArithmeticCbzFusion : SubtargetFeature<
"arith-cbz-fusion", "HasArithmeticCbzFusion", "true",
"CPU fuses arithmetic + cbz/cbnz operations">;
+def FeatureFuseAddress : SubtargetFeature<
+ "fuse-address", "HasFuseAddress", "true",
+ "CPU fuses address generation and memory operations">;
+
def FeatureFuseAES : SubtargetFeature<
"fuse-aes", "HasFuseAES", "true",
"CPU fuses AES crypto operations">;
@@ -346,6 +350,7 @@ def ProcExynosM3 : SubtargetFeature<"exynosm3", "ARMProcFamily", "ExynosM3",
FeatureCrypto,
FeatureExynosCheapAsMoveHandling,
FeatureFPARMv8,
+ FeatureFuseAddress,
FeatureFuseAES,
FeatureFuseLiterals,
FeatureLSLFast,
diff --git a/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp b/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
index 6930c816b5a..2f58306f6c6 100644
--- a/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MacroFusion.cpp
@@ -150,6 +150,39 @@ static bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
SecondMI.getOperand(3).getImm() == 48);
}
+ if (ST.hasFuseAddress()) {
+ // Fuse address generation and loads and stores.
+ if ((FirstOpcode == AArch64::INSTRUCTION_LIST_END ||
+ FirstOpcode == AArch64::ADR ||
+ FirstOpcode == AArch64::ADRP) &&
+ ((SecondOpcode == AArch64::STRBBui ||
+ SecondOpcode == AArch64::STRBui ||
+ SecondOpcode == AArch64::STRDui ||
+ SecondOpcode == AArch64::STRHHui ||
+ SecondOpcode == AArch64::STRHui ||
+ SecondOpcode == AArch64::STRQui ||
+ SecondOpcode == AArch64::STRSui ||
+ SecondOpcode == AArch64::STRWui ||
+ SecondOpcode == AArch64::STRXui ||
+ SecondOpcode == AArch64::LDRBBui ||
+ SecondOpcode == AArch64::LDRBui ||
+ SecondOpcode == AArch64::LDRDui ||
+ SecondOpcode == AArch64::LDRHHui ||
+ SecondOpcode == AArch64::LDRHui ||
+ SecondOpcode == AArch64::LDRQui ||
+ SecondOpcode == AArch64::LDRSBWui ||
+ SecondOpcode == AArch64::LDRSBXui ||
+ SecondOpcode == AArch64::LDRSHWui ||
+ SecondOpcode == AArch64::LDRSHXui ||
+ SecondOpcode == AArch64::LDRSWui ||
+ SecondOpcode == AArch64::LDRSui ||
+ SecondOpcode == AArch64::LDRWui ||
+ SecondOpcode == AArch64::LDRXui) &&
+ (FirstOpcode != AArch64::ADR ||
+ SecondMI.getOperand(2).getImm() == 0)))
+ return true;
+ }
+
return false;
}
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 9b96bfa7f34..d06f8a1ae57 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -111,6 +111,7 @@ protected:
bool UseAlternateSExtLoadCVTF32Pattern = false;
bool HasArithmeticBccFusion = false;
bool HasArithmeticCbzFusion = false;
+ bool HasFuseAddress = false;
bool HasFuseAES = false;
bool HasFuseLiterals = false;
bool DisableLatencySchedHeuristic = false;
@@ -236,6 +237,7 @@ public:
}
bool hasArithmeticBccFusion() const { return HasArithmeticBccFusion; }
bool hasArithmeticCbzFusion() const { return HasArithmeticCbzFusion; }
+ bool hasFuseAddress() const { return HasFuseAddress; }
bool hasFuseAES() const { return HasFuseAES; }
bool hasFuseLiterals() const { return HasFuseLiterals; }
OpenPOWER on IntegriCloud