[llvm] [Hexagon] Add GlobalArrayAlignment pass (PR #205293)
Abinaya Saravanan via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 24 01:05:54 PDT 2026
================
@@ -0,0 +1,114 @@
+//===- HexagonAlignGlobalArrays.cpp - Align Global Arrays -----------------===//
+//
+// 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 increases the alignment of global integer arrays (char, short,
+// int), including multi-dimensional arrays, to an 8-byte boundary. This is
+// done to make their alignment compatible with GCC. The pass is disabled by
+// default and can be enabled with -hexagon-align-global-arrays.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Hexagon.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "hexagon-global-array-alignment"
+
+static cl::opt<bool> EnableGlobalArrayAlignment(
+ "hexagon-align-global-arrays",
+ cl::desc("Align global integer arrays to an 8-byte boundary"),
+ cl::init(false), cl::Hidden);
+
+static cl::opt<bool> DisableHexAlignOptByteHalf(
+ "hexagon-disable-align-opt-byte-half",
+ cl::desc("Disable optimizing byte and half-word array alignment when "
+ "optimizing for size"),
+ cl::Hidden);
+
+namespace {
+
+class HexagonAlignGlobalArrays : public ModulePass {
+ bool OptForSize;
+
+public:
+ static char ID;
+
+ explicit HexagonAlignGlobalArrays(bool Os = false)
+ : ModulePass(ID), OptForSize(Os) {}
+
+ StringRef getPassName() const override {
+ return "Hexagon Global Array Alignment";
+ }
+
+ bool runOnModule(Module &M) override;
+};
+
+} // end anonymous namespace
+
+char HexagonAlignGlobalArrays::ID = 0;
+
+INITIALIZE_PASS(HexagonAlignGlobalArrays, "hexagon-global-array-alignment",
+ "Align Global Arrays to 8-byte", false, false)
+
+ModulePass *llvm::createHexagonAlignGlobalArrays(bool Os) {
+ return new HexagonAlignGlobalArrays(Os);
+}
+
+// Get the underlying element type of an array. This is useful if the array is
+// multi-dimensional.
+static Type *getUnderlyingArrayElmTy(Type *Ty) {
+ // Ty is guaranteed to be an array type.
+ Type *ElTy = cast<ArrayType>(Ty)->getElementType();
+ if (ElTy->isArrayTy())
+ ElTy = getUnderlyingArrayElmTy(ElTy);
+ return ElTy;
+}
+
+bool HexagonAlignGlobalArrays::runOnModule(Module &M) {
+ if (!EnableGlobalArrayAlignment)
+ return false;
+
+ bool Changed = false;
+ const DataLayout &DL = M.getDataLayout();
+
+ for (GlobalVariable &GV : M.globals()) {
+ Type *VT = GV.getValueType();
+
+ // Compute the current alignment, falling back to the ABI alignment.
+ MaybeAlign GVAlign = GV.getAlign();
+ if (!GVAlign && VT->isSized())
+ GVAlign = DL.getABITypeAlign(VT);
+
+ // Align global integer arrays (char, short, int) to an 8-byte boundary.
+ // This makes their alignment compatible with GCC. Chars and shorts keep
+ // their native alignment if not explicitly aligned to a larger size.
+ if (VT->isArrayTy()) {
+ Type *ElTy = getUnderlyingArrayElmTy(VT);
+ if (ElTy->isIntegerTy()) {
+ if (OptForSize && GVAlign && *GVAlign <= Align(2) &&
+ !DisableHexAlignOptByteHalf) {
+ ; // Do nothing.
+ } else {
+ MaybeAlign NewAlign = std::max(GVAlign.valueOrOne(), Align(8));
+ if (NewAlign != GVAlign) {
+ GV.setAlignment(NewAlign);
+ Changed = true;
+ }
+ }
+ }
+ }
+
+ LLVM_DEBUG(dbgs() << GV << '\n');
----------------
quic-asaravan wrote:
nit: Can it be guarded with Changed=true to differentiate between modified/unmodified?
https://github.com/llvm/llvm-project/pull/205293
More information about the llvm-commits
mailing list