119#define DEBUG_TYPE "aarch64-collect-loh"
122 "Number of simplifiable ADRP dominate by another");
123STATISTIC(NumADDToSTR,
"Number of simplifiable STR reachable by ADD");
124STATISTIC(NumLDRToSTR,
"Number of simplifiable STR reachable by LDR");
125STATISTIC(NumADDToLDR,
"Number of simplifiable LDR reachable by ADD");
126STATISTIC(NumLDRToLDR,
"Number of simplifiable LDR reachable by LDR");
127STATISTIC(NumADRPToLDR,
"Number of simplifiable LDR reachable by ADRP");
128STATISTIC(NumADRSimpleCandidate,
"Number of simplifiable ADRP + ADD");
130#define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
142 MachineFunctionProperties::Property::NoVRegs);
153char AArch64CollectLOH::ID = 0;
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:
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();
504 for (
MCPhysReg Reg : AArch64::GPR32RegClass)
506 for (
MCPhysReg Reg : AArch64::GPR64RegClass)
510 if (!MO.isReg() || !MO.isDef())
521 if (!MO.isReg() || !MO.readsReg())
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();
#define AARCH64_COLLECT_LOH_NAME
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...
static const unsigned N_GPR_REGS
Number of GPR registers traked by mapRegToGPRIndex()
static bool isCandidateStore(const MachineInstr &MI, const MachineOperand &MO)
Check whether the given instruction can the end of a LOH chain involving a store.
static int mapRegToGPRIndex(MCPhysReg Reg)
Map register number to index from 0-30.
static bool supportLoadFromLiteral(const MachineInstr &MI)
Check whether the given instruction can load a litteral.
static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI, LOHInfo &Info, LOHInfo *LOHInfos)
Update state when seeing and ADRP instruction.
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.
static bool canDefBePartOfLOH(const MachineInstr &MI)
Answer the following question: Can Def be one of the definition involved in a part of a LOH?
static void handleNormalInst(const MachineInstr &MI, LOHInfo *LOHInfos)
static void handleUse(const MachineInstr &MI, const MachineOperand &MO, LOHInfo &Info)
Update state Info given MI uses the tracked register.
static bool isCandidateLoad(const MachineInstr &MI)
Check whether the given instruction can be the end of a LOH chain involving a load.
This file implements the BitVector class.
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file implements a map that provides insertion order iteration.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
void addLOHDirective(MCLOHType Kind, MILOHArgs Args)
Add a LOH directive of this Kind and this Args.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
FunctionPass class - This class is used to implement most global optimizations.
reverse_instr_iterator instr_rbegin()
reverse_instr_iterator instr_rend()
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
StringRef - Represent a constant reference to a string, i.e.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createAArch64CollectLOHPass()
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
MCLOHType
Linker Optimization Hint Type.
@ MCLOH_AdrpAddLdr
Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
@ MCLOH_AdrpLdrGotStr
Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
@ MCLOH_AdrpLdrGotLdr
Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
@ MCLOH_AdrpLdrGot
Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
@ MCLOH_AdrpLdr
Adrp _v@PAGE -> Ldr _v@PAGEOFF.
@ MCLOH_AdrpAdd
Adrp _v@PAGE -> Add _v@PAGEOFF.
@ MCLOH_AdrpAddStr
Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
@ MCLOH_AdrpAdrp
Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
State tracked per register.
MCLOHType Type
"Best" type of LOH possible.
bool OneUser
Found exactly one user (yet).
bool MultiUsers
Found multiple users.
const MachineInstr * LastADRP
Last ADRP in same register.
bool IsCandidate
Possible LOH candidate.
const MachineInstr * MI1
Second instruction involved in the LOH (if any).
const MachineInstr * MI0
First instruction involved in the LOH.