121 using namespace llvm;
123 #define DEBUG_TYPE "aarch64-collect-loh"
126 "Number of simplifiable ADRP dominate by another");
127 STATISTIC(NumADDToSTR,
"Number of simplifiable STR reachable by ADD");
128 STATISTIC(NumLDRToSTR,
"Number of simplifiable STR reachable by LDR");
129 STATISTIC(NumADDToLDR,
"Number of simplifiable LDR reachable by ADD");
130 STATISTIC(NumLDRToLDR,
"Number of simplifiable LDR reachable by LDR");
131 STATISTIC(NumADRPToLDR,
"Number of simplifiable LDR reachable by ADRP");
132 STATISTIC(NumADRSimpleCandidate,
"Number of simplifiable ADRP + ADD");
134 #define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
166 switch (MI.getOperand(2).getType()) {
186 case AArch64::ADDXri:
187 return canAddBePartOfLOH(MI);
188 case AArch64::LDRXui:
205 case AArch64::STRBBui:
206 case AArch64::STRHHui:
207 case AArch64::STRBui:
208 case AArch64::STRHui:
209 case AArch64::STRWui:
210 case AArch64::STRXui:
211 case AArch64::STRSui:
212 case AArch64::STRDui:
213 case AArch64::STRQui:
229 case AArch64::LDRSBWui:
230 case AArch64::LDRSBXui:
231 case AArch64::LDRSHWui:
232 case AArch64::LDRSHXui:
233 case AArch64::LDRSWui:
234 case AArch64::LDRBui:
235 case AArch64::LDRHui:
236 case AArch64::LDRWui:
237 case AArch64::LDRXui:
238 case AArch64::LDRSui:
239 case AArch64::LDRDui:
240 case AArch64::LDRQui:
250 case AArch64::LDRSWui:
251 case AArch64::LDRWui:
252 case AArch64::LDRXui:
253 case AArch64::LDRSui:
254 case AArch64::LDRDui:
255 case AArch64::LDRQui:
264 static_assert(AArch64::X28 - AArch64::X0 + 3 ==
N_GPR_REGS,
"Number of GPRs");
265 static_assert(AArch64::W30 - AArch64::W0 + 1 ==
N_GPR_REGS,
"Number of GPRs");
266 if (AArch64::X0 <= Reg && Reg <= AArch64::X28)
267 return Reg - AArch64::X0;
268 if (AArch64::W0 <= Reg && Reg <= AArch64::W30)
269 return Reg - AArch64::W0;
272 if (Reg == AArch64::FP)
274 if (Reg == AArch64::LR)
284 bool IsCandidate : 1;
316 }
else if (MI.
getOpcode() == AArch64::ADDXri) {
320 }
else if (MI.
getOpcode() == AArch64::LDRXui &&
343 if (&DefInfo != &OpInfo) {
352 if (MI.
getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(MI)) {
367 "Expected GOT relocation");
387 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpAdrp:\n" <<
'\t' << MI <<
'\t'
390 ++NumADRPSimpleCandidate;
397 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpAdd:\n" <<
'\t' << MI <<
'\t'
400 ++NumADRSimpleCandidate;
404 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpLdr:\n" <<
'\t' << MI <<
'\t'
411 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpAddLdr:\n" <<
'\t' << MI <<
'\t'
412 << *Info.
MI1 <<
'\t' << *Info.
MI0);
417 if (Info.
MI1 !=
nullptr) {
418 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpAddStr:\n" <<
'\t' << MI <<
'\t'
419 << *Info.
MI1 <<
'\t' << *Info.
MI0);
425 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpLdrGotLdr:\n" <<
'\t' << MI <<
'\t'
426 << *Info.
MI1 <<
'\t' << *Info.
MI0);
431 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpLdrGotStr:\n" <<
'\t' << MI <<
'\t'
432 << *Info.
MI1 <<
'\t' << *Info.
MI0);
437 DEBUG(
dbgs() <<
"Adding MCLOH_AdrpLdrGot:\n" <<
'\t' << MI <<
'\t'
462 if (MO.isRegMask()) {
463 const uint32_t *RegMask = MO.getRegMask();
470 if (!MO.isReg() || !MO.isDef())
479 if (!MO.isReg() || !MO.readsReg())
492 DEBUG(
dbgs() <<
"********** AArch64 Collect LOH **********\n"
493 <<
"Looking in function " << MF.
getName() <<
'\n');
499 memset(LOHInfos, 0,
sizeof(LOHInfos));
502 for (
const auto &LI : Succ->liveins()) {
505 LOHInfos[RegIdx].OneUser =
true;
512 unsigned Opcode =
MI.getOpcode();
514 case AArch64::ADDXri:
515 case AArch64::LDRXui:
523 if (DefIdx >= 0 && OpIdx >= 0 &&
546 return new AArch64CollectLOH();
static void handleNormalInst(const MachineInstr &MI, LOHInfo *LOHInfos)
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
STATISTIC(NumFunctions,"Total number of functions")
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
Address of indexed Jump Table for switch.
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
const MachineInstr * LastADRP
Last ADRP in same register.
Adrp _v -> Add _v -> Ldr.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
iterator_range< succ_iterator > successors()
FunctionPass * createAArch64CollectLOHPass()
Adrp _v -> Ldr _v -> Ldr.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
static bool isCandidateLoad(const MachineInstr &MI)
Check whether the given instruction can be the end of a LOH chain involving a load.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
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.
static const unsigned N_GPR_REGS
Number of GPR registers traked by mapRegToGPRIndex()
State tracked per register.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
static bool isCandidateStore(const MachineInstr &MI, const MachineOperand &MO)
Check whether the given instruction can the end of a LOH chain involving a store. ...
reverse_iterator rbegin()
static void handleRegMaskClobber(const uint32_t *RegMask, MCPhysReg Reg, LOHInfo *LOHInfos)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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...
Address of a global value.
unsigned getTargetFlags() const
The instances of the Type class are immutable: once they are created, they are never changed...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
bool MultiUsers
Found multiple users.
bool OneUser
Found exactly one user (yet).
Represent the analysis usage information of a pass.
MCLOHType
Linker Optimization Hint Type.
Address of a basic block.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static void handleClobber(LOHInfo &Info)
Update state Info given the tracked register is clobbered.
Adrp _v -> Add _v -> Str.
MachineOperand class - Representation of each machine instruction operand.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool IsCandidate
Possible LOH candidate.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
static void handleUse(const MachineInstr &MI, const MachineOperand &MO, LOHInfo &Info)
Update state Info given MI uses the tracked register.
MCLOHType Type
"Best" type of LOH possible.
INITIALIZE_PASS(AArch64CollectLOH,"aarch64-collect-loh", AARCH64_COLLECT_LOH_NAME, false, false) static bool canAddBePartOfLOH(const MachineInstr &MI)
Adrp xY, _v1 -> Adrp xY, _v2.
Adrp _v -> Ldr _v -> Str.
static bool canDefBePartOfLOH(const MachineInstr &MI)
Answer the following question: Can Def be one of the definition involved in a part of a LOH...
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineInstr * MI0
First instruction involved in the LOH.
void addLOHDirective(MCLOHType Kind, MILOHArgs Args)
Add a LOH directive of this Kind and this Args.
static bool supportLoadFromLiteral(const MachineInstr &MI)
Check whether the given instruction can load a litteral.
const MachineInstr * MI1
Second instruction involved in the LOH (if any).
StringRef - Represent a constant reference to a string, i.e.
static void handleADRP(const MachineInstr &MI, AArch64FunctionInfo &AFI, LOHInfo &Info)
Update state when seeing and ADRP instruction.
Address of indexed Constant in Constant Pool.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
#define AARCH64_COLLECT_LOH_NAME
Properties which a MachineFunction may have at a given point in time.