Go to the documentation of this file.
117 using namespace llvm;
119 #define DEBUG_TYPE "aarch64-collect-loh"
122 "Number of simplifiable ADRP dominate by another");
123 STATISTIC(NumADDToSTR,
"Number of simplifiable STR reachable by ADD");
124 STATISTIC(NumLDRToSTR,
"Number of simplifiable STR reachable by LDR");
125 STATISTIC(NumADDToLDR,
"Number of simplifiable LDR reachable by ADD");
126 STATISTIC(NumLDRToLDR,
"Number of simplifiable LDR reachable by LDR");
127 STATISTIC(NumADRPToLDR,
"Number of simplifiable LDR reachable by ADRP");
128 STATISTIC(NumADRSimpleCandidate,
"Number of simplifiable ADRP + ADD");
130 #define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
162 switch (
MI.getOperand(2).getType()) {
177 switch (
MI.getOpcode()) {
182 case AArch64::ADDXri:
183 return canAddBePartOfLOH(
MI);
184 case AArch64::LDRXui:
185 case AArch64::LDRWui:
187 switch (
MI.getOperand(2).getType()) {
199 switch (
MI.getOpcode()) {
202 case AArch64::STRBBui:
203 case AArch64::STRHHui:
204 case AArch64::STRBui:
205 case AArch64::STRHui:
206 case AArch64::STRWui:
207 case AArch64::STRXui:
208 case AArch64::STRSui:
209 case AArch64::STRDui:
210 case AArch64::STRQui:
215 return MI.getOperandNo(&MO) == 1 &&
216 MI.getOperand(0).getReg() !=
MI.getOperand(1).getReg();
223 switch (
MI.getOpcode()) {
226 case AArch64::LDRSBWui:
227 case AArch64::LDRSBXui:
228 case AArch64::LDRSHWui:
229 case AArch64::LDRSHXui:
230 case AArch64::LDRSWui:
231 case AArch64::LDRBui:
232 case AArch64::LDRHui:
233 case AArch64::LDRWui:
234 case AArch64::LDRXui:
235 case AArch64::LDRSui:
236 case AArch64::LDRDui:
237 case AArch64::LDRQui:
244 switch (
MI.getOpcode()) {
247 case AArch64::LDRSWui:
248 case AArch64::LDRWui:
249 case AArch64::LDRXui:
250 case AArch64::LDRSui:
251 case AArch64::LDRDui:
252 case AArch64::LDRQui:
261 static_assert(AArch64::X28 - AArch64::X0 + 3 ==
N_GPR_REGS,
"Number of GPRs");
262 static_assert(AArch64::W30 - AArch64::W0 + 1 ==
N_GPR_REGS,
"Number of GPRs");
263 if (AArch64::X0 <=
Reg &&
Reg <= AArch64::X28)
264 return Reg - AArch64::X0;
265 if (AArch64::W0 <=
Reg &&
Reg <= AArch64::W30)
266 return Reg - AArch64::W0;
269 if (
Reg == AArch64::FP)
271 if (
Reg == AArch64::LR)
294 if (
Info.MultiUsers ||
Info.OneUser) {
295 Info.IsCandidate =
false;
296 Info.MultiUsers =
true;
304 Info.IsCandidate =
true;
310 Info.IsCandidate =
true;
313 }
else if (
MI.getOpcode() == AArch64::ADDXri) {
315 Info.IsCandidate =
true;
317 }
else if ((
MI.getOpcode() == AArch64::LDRXui ||
318 MI.getOpcode() == AArch64::LDRWui) &&
321 Info.IsCandidate =
true;
328 Info.IsCandidate =
false;
329 Info.OneUser =
false;
330 Info.MultiUsers =
false;
331 Info.LastADRP =
nullptr;
341 if (&DefInfo != &OpInfo) {
350 if (
MI.getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(
MI)) {
363 assert((
MI.getOpcode() == AArch64::LDRXui ||
364 MI.getOpcode() == AArch64::LDRWui) &&
365 "Expect LDRXui or LDRWui");
367 "Expected GOT relocation");
386 if (
Info.LastADRP !=
nullptr) {
388 <<
'\t' <<
MI <<
'\t' << *
Info.LastADRP);
390 ++NumADRPSimpleCandidate;
394 if (
Info.IsCandidate) {
405 LOHInfo DefInfo = LOHInfos[OpIdx];
409 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
411 ++NumADRSimpleCandidate;
417 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
447 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
454 if (
Info.MI1 !=
nullptr) {
456 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
464 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
471 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
478 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
502 if (MO.isRegMask()) {
503 const uint32_t *RegMask = MO.getRegMask();
510 if (!MO.isReg() || !MO.isDef())
521 if (!MO.isReg() || !MO.readsReg())
531 if (UsesSeen.
insert(Idx).second)
540 LLVM_DEBUG(
dbgs() <<
"********** AArch64 Collect LOH **********\n"
541 <<
"Looking in function " << MF.
getName() <<
'\n');
547 memset(LOHInfos, 0,
sizeof(LOHInfos));
550 for (
const auto &LI : Succ->liveins()) {
553 LOHInfos[RegIdx].
OneUser =
true;
561 unsigned Opcode =
MI.getOpcode();
563 case AArch64::ADDXri:
564 case AArch64::LDRXui:
565 case AArch64::LDRWui:
569 assert(
Def.isReg() &&
Def.isDef() &&
"Expected reg def");
570 assert(
Op.isReg() &&
Op.isUse() &&
"Expected reg use");
573 if (DefIdx >= 0 && OpIdx >= 0 &&
596 return new AArch64CollectLOH();
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
static bool canDefBePartOfLOH(const MachineInstr &MI)
Answer the following question: Can Def be one of the definition involved in a part of a LOH?
@ MO_BlockAddress
Address of a basic block.
This is an optimization pass for GlobalISel generic memory operations.
static bool supportLoadFromLiteral(const MachineInstr &MI)
Check whether the given instruction can load a litteral.
MCLOHType
Linker Optimization Hint Type.
static bool isCandidateLoad(const MachineInstr &MI)
Check whether the given instruction can be the end of a LOH chain involving a load.
@ MCLOH_AdrpAddLdr
Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
Reg
All possible values of the reg field in the ModR/M byte.
static int mapRegToGPRIndex(MCPhysReg Reg)
Map register number to index from 0-30.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Properties which a MachineFunction may have at a given point in time.
@ MCLOH_AdrpLdrGotLdr
Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
static const unsigned N_GPR_REGS
Number of GPR registers traked by mapRegToGPRIndex()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static bool handleMiddleInst(const MachineInstr &MI, LOHInfo &DefInfo, LOHInfo &OpInfo)
Update state Info given that MI is possibly the middle instruction of an LOH involving 3 instructions...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ MO_GlobalAddress
Address of a global value.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineOperand & getOperand(unsigned i) const
static bool isCandidateStore(const MachineInstr &MI, const MachineOperand &MO)
Check whether the given instruction can the end of a LOH chain involving a store.
Represent the analysis usage information of a pass.
MachineOperand class - Representation of each machine instruction operand.
MachineFunctionProperties & set(Property P)
const MachineInstr * MI0
First instruction involved in the LOH.
STATISTIC(NumFunctions, "Total number of functions")
Analysis containing CSE Info
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
reverse_instr_iterator instr_rend()
Representation of each machine instruction.
INITIALIZE_PASS(AArch64CollectLOH, "aarch64-collect-loh", AARCH64_COLLECT_LOH_NAME, false, false) static bool canAddBePartOfLOH(const MachineInstr &MI)
reverse_instr_iterator instr_rbegin()
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
static void handleRegMaskClobber(const uint32_t *RegMask, MCPhysReg Reg, LOHInfo *LOHInfos)
static void handleClobber(LOHInfo &Info)
Update state Info given the tracked register is clobbered.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Register getReg() const
getReg - Returns the register number.
@ MCLOH_AdrpAddStr
Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI, LOHInfo &Info, LOHInfo *LOHInfos)
Update state when seeing and ADRP instruction.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
MachineInstrBundleIterator< MachineInstr > iterator
iterator_range< succ_iterator > successors()
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
self_iterator getIterator()
const MachineBasicBlock * getParent() const
MCLOHType Type
"Best" type of LOH possible.
const MachineInstr * MI1
Second instruction involved in the LOH (if any).
Function & getFunction()
Return the LLVM function that this machine code represents.
void setPreservesAll()
Set by analyses that do not transform their input at all.
@ MCLOH_AdrpAdrp
Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
bool OneUser
Found exactly one user (yet).
FunctionPass * createAArch64CollectLOHPass()
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
@ MCLOH_AdrpAdd
Adrp _v@PAGE -> Add _v@PAGEOFF.
static void handleUse(const MachineInstr &MI, const MachineOperand &MO, LOHInfo &Info)
Update state Info given MI uses the tracked register.
#define AARCH64_COLLECT_LOH_NAME
@ MCLOH_AdrpLdr
Adrp _v@PAGE -> Ldr _v@PAGEOFF.
@ MCLOH_AdrpLdrGotStr
Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
State tracked per register.
bool MultiUsers
Found multiple users.
FunctionPass class - This class is used to implement most global optimizations.
@ MCLOH_AdrpLdrGot
Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
const MachineInstr * LastADRP
Last ADRP in same register.
bool IsCandidate
Possible LOH candidate.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
void addLOHDirective(MCLOHType Kind, MILOHArgs Args)
Add a LOH directive of this Kind and this Args.
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
static void handleNormalInst(const MachineInstr &MI, LOHInfo *LOHInfos)
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.