113#define DEBUG_TYPE "aarch64-collect-loh"
116 "Number of simplifiable ADRP dominate by another");
117STATISTIC(NumADDToSTR,
"Number of simplifiable STR reachable by ADD");
118STATISTIC(NumLDRToSTR,
"Number of simplifiable STR reachable by LDR");
119STATISTIC(NumADDToLDR,
"Number of simplifiable LDR reachable by ADD");
120STATISTIC(NumLDRToLDR,
"Number of simplifiable LDR reachable by LDR");
121STATISTIC(NumADRPToLDR,
"Number of simplifiable LDR reachable by ADRP");
122STATISTIC(NumADRSimpleCandidate,
"Number of simplifiable ADRP + ADD");
124#define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
136 MachineFunctionProperties::Property::NoVRegs);
147char AArch64CollectLOH::ID = 0;
156 switch (
MI.getOperand(2).getType()) {
171 switch (
MI.getOpcode()) {
176 case AArch64::ADDXri:
177 return canAddBePartOfLOH(
MI);
178 case AArch64::LDRXui:
179 case AArch64::LDRWui:
181 switch (
MI.getOperand(2).getType()) {
193 switch (
MI.getOpcode()) {
196 case AArch64::STRBBui:
197 case AArch64::STRHHui:
198 case AArch64::STRBui:
199 case AArch64::STRHui:
200 case AArch64::STRWui:
201 case AArch64::STRXui:
202 case AArch64::STRSui:
203 case AArch64::STRDui:
204 case AArch64::STRQui:
210 MI.getOperand(0).getReg() !=
MI.getOperand(1).getReg();
217 switch (
MI.getOpcode()) {
220 case AArch64::LDRSBWui:
221 case AArch64::LDRSBXui:
222 case AArch64::LDRSHWui:
223 case AArch64::LDRSHXui:
224 case AArch64::LDRSWui:
225 case AArch64::LDRBui:
226 case AArch64::LDRHui:
227 case AArch64::LDRWui:
228 case AArch64::LDRXui:
229 case AArch64::LDRSui:
230 case AArch64::LDRDui:
231 case AArch64::LDRQui:
238 switch (
MI.getOpcode()) {
241 case AArch64::LDRSWui:
242 case AArch64::LDRWui:
243 case AArch64::LDRXui:
244 case AArch64::LDRSui:
245 case AArch64::LDRDui:
246 case AArch64::LDRQui:
255 static_assert(AArch64::X28 - AArch64::X0 + 3 ==
N_GPR_REGS,
"Number of GPRs");
256 static_assert(AArch64::W30 - AArch64::W0 + 1 ==
N_GPR_REGS,
"Number of GPRs");
257 if (AArch64::X0 <= Reg && Reg <= AArch64::X28)
258 return Reg - AArch64::X0;
259 if (AArch64::W0 <= Reg && Reg <= AArch64::W30)
260 return Reg - AArch64::W0;
263 if (Reg == AArch64::FP)
265 if (Reg == AArch64::LR)
288 if (
Info.MultiUsers ||
Info.OneUser) {
289 Info.IsCandidate =
false;
290 Info.MultiUsers =
true;
298 Info.IsCandidate =
true;
304 Info.IsCandidate =
true;
307 }
else if (
MI.getOpcode() == AArch64::ADDXri) {
309 Info.IsCandidate =
true;
311 }
else if ((
MI.getOpcode() == AArch64::LDRXui ||
312 MI.getOpcode() == AArch64::LDRWui) &&
315 Info.IsCandidate =
true;
322 Info.IsCandidate =
false;
323 Info.OneUser =
false;
324 Info.MultiUsers =
false;
325 Info.LastADRP =
nullptr;
335 if (&DefInfo != &OpInfo) {
344 if (
MI.getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(
MI)) {
357 assert((
MI.getOpcode() == AArch64::LDRXui ||
358 MI.getOpcode() == AArch64::LDRWui) &&
359 "Expect LDRXui or LDRWui");
361 "Expected GOT relocation");
380 if (
Info.LastADRP !=
nullptr) {
382 <<
'\t' <<
MI <<
'\t' << *
Info.LastADRP);
384 ++NumADRPSimpleCandidate;
388 if (
Info.IsCandidate) {
399 LOHInfo DefInfo = LOHInfos[OpIdx];
403 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
405 ++NumADRSimpleCandidate;
411 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
441 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
448 if (
Info.MI1 !=
nullptr) {
450 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
458 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
465 <<
'\t' <<
MI <<
'\t' << *
Info.MI1 <<
'\t'
472 <<
'\t' <<
MI <<
'\t' << *
Info.MI0);
496 if (MO.isRegMask()) {
497 const uint32_t *RegMask = MO.getRegMask();
498 for (
MCPhysReg Reg : AArch64::GPR32RegClass)
500 for (
MCPhysReg Reg : AArch64::GPR64RegClass)
504 if (!MO.isReg() || !MO.isDef())
515 if (!MO.isReg() || !MO.readsReg())
534 LLVM_DEBUG(
dbgs() <<
"********** AArch64 Collect LOH **********\n"
535 <<
"Looking in function " << MF.
getName() <<
'\n');
541 memset(LOHInfos, 0,
sizeof(LOHInfos));
544 for (
const auto &LI : Succ->liveins()) {
547 LOHInfos[RegIdx].
OneUser =
true;
555 unsigned Opcode =
MI.getOpcode();
557 case AArch64::ADDXri:
558 case AArch64::LDRXui:
559 case AArch64::LDRWui:
563 assert(
Def.isReg() &&
Def.isDef() &&
"Expected reg def");
564 assert(
Op.isReg() &&
Op.isUse() &&
"Expected reg use");
567 if (DefIdx >= 0 && OpIdx >= 0 &&
590 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.