LLVM 24.0.0git
HexagonAlignGlobalArrays.cpp
Go to the documentation of this file.
1//===- HexagonAlignGlobalArrays.cpp - Align Global Arrays -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass increases the alignment of global integer arrays (char, short,
10// int), including multi-dimensional arrays, to an 8-byte boundary. This gives
11// their base address a wider alignment, which is beneficial for the wide
12// (double-word) loads and stores available on Hexagon.
13//
14// When optimizing to reduce .rodata size, byte and half-word arrays already at
15// an alignment of two bytes or less are left at their natural alignment; only
16// word arrays are promoted. This size behavior can be turned off with
17// -hexagon-disable-align-opt-byte-half.
18//
19// The pass is enabled by default and can be disabled with
20// -hexagon-disable-global-array-align.
21//
22//===----------------------------------------------------------------------===//
23
24#include "Hexagon.h"
25#include "llvm/IR/Module.h"
26#include "llvm/Pass.h"
28#include "llvm/Support/Debug.h"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "hexagon-global-array-alignment"
33
35 "hexagon-disable-global-array-align",
36 cl::desc("Disable aligning global integer arrays to an 8-byte boundary"),
37 cl::init(false), cl::Hidden);
38
40 "hexagon-disable-align-opt-byte-half",
41 cl::desc("Disable keeping byte and half-word arrays at their natural "
42 "alignment when reducing .rodata size"),
44
45namespace {
46
47class HexagonAlignGlobalArrays : public ModulePass {
48 bool ReduceRodataSize;
49
50public:
51 static char ID;
52
53 explicit HexagonAlignGlobalArrays(bool ReduceRodataSize = false)
54 : ModulePass(ID), ReduceRodataSize(ReduceRodataSize) {}
55
56 StringRef getPassName() const override {
57 return "Hexagon Global Array Alignment";
58 }
59
60 bool runOnModule(Module &M) override;
61};
62
63} // end anonymous namespace
64
65char HexagonAlignGlobalArrays::ID = 0;
66
67INITIALIZE_PASS(HexagonAlignGlobalArrays, "hexagon-global-array-alignment",
68 "Align Global Arrays to 8-byte", false, false)
69
70ModulePass *llvm::createHexagonAlignGlobalArrays(bool ReduceRodataSize) {
71 return new HexagonAlignGlobalArrays(ReduceRodataSize);
72}
73
74// Get the underlying element type of an array. This is useful if the array is
75// multi-dimensional.
77 // Ty is guaranteed to be an array type.
78 Type *ElTy = cast<ArrayType>(Ty)->getElementType();
79 while (ElTy->isArrayTy())
80 ElTy = cast<ArrayType>(ElTy)->getElementType();
81 return ElTy;
82}
83
84bool HexagonAlignGlobalArrays::runOnModule(Module &M) {
86 return false;
87
88 bool Changed = false;
89 const DataLayout &DL = M.getDataLayout();
90
91 for (GlobalVariable &GV : M.globals()) {
92 Type *VT = GV.getValueType();
93 if (!VT->isArrayTy())
94 continue;
95
96 Type *ElTy = getUnderlyingArrayElmTy(VT);
97 if (!ElTy->isIntegerTy())
98 continue;
99
100 // Skip globals whose alignment cannot be safely raised, e.g. declarations,
101 // weak/interposable definitions, and section-pinned globals.
102 if (!GV.canIncreaseAlignment())
103 continue;
104
105 // Compute the current alignment, falling back to the ABI alignment.
106 MaybeAlign GVAlign = GV.getAlign();
107 if (!GVAlign && VT->isSized())
108 GVAlign = DL.getABITypeAlign(VT);
109
110 // Align integer arrays to an 8-byte boundary. When reducing .rodata size,
111 // leave byte and half-word arrays that are already at an alignment of two
112 // bytes or less at their natural alignment; word arrays are still promoted.
113 if (!ReduceRodataSize || !GVAlign || *GVAlign > Align(2) ||
115 MaybeAlign NewAlign = std::max(GVAlign.valueOrOne(), Align(8));
116 if (NewAlign != GVAlign) {
117 GV.setAlignment(NewAlign);
118 Changed = true;
119 LLVM_DEBUG(dbgs() << GV << '\n');
120 }
121 }
122 }
123
124 return Changed;
125}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< bool > DisableGlobalArrayAlignment("hexagon-disable-global-array-align", cl::desc("Disable aligning 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 keeping byte and half-word arrays at their natural " "alignment when reducing .rodata size"), cl::Hidden)
static Type * getUnderlyingArrayElmTy(Type *Ty)
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
#define LLVM_DEBUG(...)
Definition Debug.h:119
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:255
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition Type.h:279
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition Type.h:326
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
Changed
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
ModulePass * createHexagonAlignGlobalArrays(bool ReduceRodataSize)
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130