[llvm] [AArch64] New pass for code layout optimizations. (PR #184434)
Jon Roelofs via llvm-commits
llvm-commits at lists.llvm.org
Fri May 8 11:10:35 PDT 2026
================
@@ -0,0 +1,260 @@
+//===-- AArch64CodeLayoutOpt.cpp - Code Layout Optimizations --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass runs after instruction scheduling and employs code layout
+// optimizations for certain patterns.
+//
+// Option -aarch64-code-layout-opt selects instruction pairs to optimize:
+// cmp-csel: Enable CMP/CMN-CSEL code layout optimization
+// fcmp-fcsel: Enable FCMP-FCSEL code layout optimization
+//
+// The initial implementation induces function alignment when a supported
+// pattern is detected, and possibly instruction-alignment when a pair would
+// straddle cache-lines.
+//===----------------------------------------------------------------------===//
+
+#include "AArch64.h"
+#include "AArch64InstrInfo.h"
+#include "AArch64Subtarget.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "aarch64-code-layout-opt"
+#define DBG(...) LLVM_DEBUG(dbgs() << DEBUG_TYPE ": " << __VA_ARGS__)
+#define AARCH64_CODE_LAYOUT_OPT_NAME "AArch64 Code Layout Optimization"
+
+enum CodeLayoutOpt {
+ CmpCsel, // Align CMP/CMN-CSEL pairs
+ FcmpFcsel, // Align FCMP-FCSEL pairs
+};
+
+static cl::bits<CodeLayoutOpt> EnableCodeAlignment(
+ "aarch64-code-layout-opt", cl::Hidden, cl::CommaSeparated,
+ cl::desc("Enable code alignment optimization for instruction pairs"),
+ cl::values(
+ clEnumValN(CmpCsel, "cmp-csel", "CMP/CMN-CSEL pair alignment (32-bit)"),
+ clEnumValN(FcmpFcsel, "fcmp-fcsel", "FCMP-FCSEL pair alignment")));
+
+static cl::opt<unsigned> FunctionAlignBytes(
+ "aarch64-code-layout-opt-align-functions", cl::Hidden,
+ cl::desc("Function alignment in bytes for code layout optimization "
+ "(must be a power of 2)"),
+ cl::init(64), cl::callback([](const unsigned &Val) {
+ if (!isPowerOf2_32(Val))
+ report_fatal_error(
+ "aarch64-code-layout-opt-align must be a power of 2");
+ }));
+
+STATISTIC(NumFunctionsAligned,
+ "Number of functions with aligned (to 64-bytes by default)");
+STATISTIC(NumCmpCselPairsDetected,
+ "Number of CMP/CMN-CSEL pairs detected for alignment");
+STATISTIC(NumFcmpFcselPairsDetected,
+ "Number of FCMP-FCSEL pairs detected for alignment");
+
+namespace {
+
+class AArch64CodeLayoutOpt : public MachineFunctionPass {
+public:
+ static char ID;
+ AArch64CodeLayoutOpt() : MachineFunctionPass(ID) {}
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnMachineFunction(MachineFunction &MF) override;
+ StringRef getPassName() const override {
+ return AARCH64_CODE_LAYOUT_OPT_NAME;
+ }
+
+private:
+ const AArch64InstrInfo *TII = nullptr;
+
+ // Returns true if MBB contains at least one layout-sensitive pattern.
+ bool detectLayoutSensitivePattern(MachineBasicBlock *MBB);
+
+ // Emit .p2align before MI. Splits the block if MI is not at its start.
+ void emitP2Align(MachineInstr &MI, Align DesiredAlign,
+ unsigned MaxSkipBytes = 4);
+
+ bool optimizeForCodeLayout(MachineFunction &MF);
+};
+
+} // end anonymous namespace
+
+char AArch64CodeLayoutOpt::ID = 0;
+
+INITIALIZE_PASS(AArch64CodeLayoutOpt, "aarch64-code-layout-opt",
+ AARCH64_CODE_LAYOUT_OPT_NAME, false, false)
+
+void AArch64CodeLayoutOpt::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+FunctionPass *llvm::createAArch64CodeLayoutOptPass() {
+ return new AArch64CodeLayoutOpt();
+}
+
+/// Returns true if Opc is a floating-point comparison (FCMP/FCMPE).
+static bool isFloatingPointCompare(unsigned Opc) {
+ switch (Opc) {
+ case AArch64::FCMPSrr:
+ case AArch64::FCMPDrr:
+ case AArch64::FCMPESrr:
+ case AArch64::FCMPEDrr:
+ case AArch64::FCMPHrr:
+ case AArch64::FCMPEHrr:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/// Returns true if Opc is a floating-point conditional select (FCSEL).
----------------
jroelofs wrote:
```suggestion
/// \returns true iff Opc is a floating-point conditional select (FCSEL).
```
https://github.com/llvm/llvm-project/pull/184434
More information about the llvm-commits
mailing list