115#define DEBUG_TYPE "aarch64-collect-loh"
118 "Number of simplifiable ADRP dominate by another");
119STATISTIC(NumADDToSTR,
"Number of simplifiable STR reachable by ADD");
120STATISTIC(NumLDRToSTR,
"Number of simplifiable STR reachable by LDR");
121STATISTIC(NumADDToLDR,
"Number of simplifiable LDR reachable by ADD");
122STATISTIC(NumLDRToLDR,
"Number of simplifiable LDR reachable by LDR");
123STATISTIC(NumADRPToLDR,
"Number of simplifiable LDR reachable by ADRP");
124STATISTIC(NumADRSimpleCandidate,
"Number of simplifiable ADRP + ADD");
126#define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
138 MachineFunctionProperties::Property::NoVRegs);
149char AArch64CollectLOH::ID = 0;
158 switch (
MI.getOperand(2).getType()) {
173 switch (
MI.getOpcode()) {
178 case AArch64::ADDXri:
179 return canAddBePartOfLOH(
MI);
180 case AArch64::LDRXui:
181 case AArch64::LDRWui:
183 switch (
MI.getOperand(2).getType()) {
195 switch (
MI.getOpcode()) {
198 case AArch64::STRBBui:
199 case AArch64::STRHHui:
200 case AArch64::STRBui:
201 case AArch64::STRHui:
202 case AArch64::STRWui:
203 case AArch64::STRXui:
204 case AArch64::STRSui:
205 case AArch64::STRDui:
206 case AArch64::STRQui:
212 MI.getOperand(0).getReg() !=
MI.getOperand(1).getReg();
219 switch (
MI.getOpcode()) {
222 case AArch64::LDRSBWui:
223 case AArch64::LDRSBXui:
224 case AArch64::LDRSHWui:
225 case AArch64::LDRSHXui:
226 case AArch64::LDRSWui:
227 case AArch64::LDRBui:
228 case AArch64::LDRHui:
229 case AArch64::LDRWui:
230 case AArch64::LDRXui:
231 case AArch64::LDRSui:
232 case AArch64::LDRDui:
233 case AArch64::LDRQui:
240 switch (
MI.getOpcode()) {
243 case AArch64::LDRSWui:
244 case AArch64::LDRWui:
245 case AArch64::LDRXui:
246 case AArch64::LDRSui:
247 case AArch64::LDRDui:
248 case AArch64::LDRQui:
257 static_assert(AArch64::X28 - AArch64::X0 + 3 ==
N_GPR_REGS,
"Number of GPRs");
258 static_assert(AArch64::W30 - AArch64::W0 + 1 ==
N_GPR_REGS,
"Number of GPRs");
259 if (AArch64::X0 <= Reg && Reg <= AArch64::X28)
260 return Reg - AArch64::X0;
261 if (AArch64::W0 <= Reg && Reg <= AArch64::W30)
262 return Reg - AArch64::W0;
265 if (Reg == AArch64::FP)
267 if (Reg == AArch64::LR)
290 if (
Info.MultiUsers ||
Info.OneUser) {
291 Info.IsCandidate =
false;
292 Info.MultiUsers =
true;
300 Info.IsCandidate =
true;
306 Info.IsCandidate =
true;
309 }
else if (
MI.getOpcode() == AArch64::ADDXri) {
311 Info.IsCandidate =
true;
313 }
else if ((
MI.getOpcode() == AArch64::LDRXui ||
314 MI.getOpcode() == AArch64::LDRWui) &&
317 Info.IsCandidate =
true;
324 Info.IsCandidate =
false;
325 Info.OneUser =
false;
326 Info.MultiUsers =
false;
327 Info.LastADRP =
nullptr;
337 if (&DefInfo != &OpInfo) {
346 if (
MI.getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(
MI)) {
359 assert((
MI.getOpcode() == AArch64::LDRXui ||
360 MI.getOpcode() == AArch64::LDRWui) &&
361 "Expect LDRXui or LDRWui");
363 "Expected GOT relocation");
382 if (
Info.LastADRP !=
nullptr) {
384 <<
'\t' <<
MI <<
'\t' << *
Info.LastADRP);
386 ++NumADRPSimpleCandidate;
390 if (
Info.IsCandidate) {
401 LOHInfo DefInfo = LOHInfos[OpIdx];
405 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
407 ++NumADRSimpleCandidate;
413 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
443 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
450 if (
Info.MI1 !=
nullptr) {
452 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
460 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
467 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
474 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
498 if (MO.isRegMask()) {
499 const uint32_t *RegMask = MO.getRegMask();
500 for (
MCPhysReg Reg : AArch64::GPR32RegClass)
502 for (
MCPhysReg Reg : AArch64::GPR64RegClass)
506 if (!MO.isReg() || !MO.isDef())
517 if (!MO.isReg() || !MO.readsReg())
536 LLVM_DEBUG(
dbgs() <<
"********** AArch64 Collect LOH **********\n"
537 <<
"Looking in function " << MF.
getName() <<
'\n');
543 memset(LOHInfos, 0,
sizeof(LOHInfos));
546 for (
const auto &LI : Succ->liveins()) {
549 LOHInfos[RegIdx].
OneUser =
true;
557 unsigned Opcode =
MI.getOpcode();
559 case AArch64::ADDXri:
560 case AArch64::LDRXui:
561 case AArch64::LDRWui:
565 assert(
Def.isReg() &&
Def.isDef() &&
"Expected reg def");
566 assert(
Op.isReg() &&
Op.isUse() &&
"Expected reg use");
569 if (DefIdx >= 0 && OpIdx >= 0 &&
592 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.
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
#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 '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.
This class represents an Operation in the Expression.
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.
NodeAddr< DefNode * > Def
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.