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)" 
  146char AArch64CollectLOH::ID = 0;
 
  155  switch (
MI.getOperand(2).getType()) {
 
  158  case MachineOperand::MO_GlobalAddress:
 
  159  case MachineOperand::MO_JumpTableIndex:
 
  160  case MachineOperand::MO_ConstantPoolIndex:
 
  161  case MachineOperand::MO_BlockAddress:
 
 
  170  switch (
MI.getOpcode()) {
 
  175  case AArch64::ADDXri:
 
  176    return canAddBePartOfLOH(
MI);
 
  177  case AArch64::LDRXui:
 
  178  case AArch64::LDRWui:
 
  180    switch (
MI.getOperand(2).getType()) {
 
 
  192  switch (
MI.getOpcode()) {
 
  195  case AArch64::STRBBui:
 
  196  case AArch64::STRHHui:
 
  197  case AArch64::STRBui:
 
  198  case AArch64::STRHui:
 
  199  case AArch64::STRWui:
 
  200  case AArch64::STRXui:
 
  201  case AArch64::STRSui:
 
  202  case AArch64::STRDui:
 
  203  case AArch64::STRQui:
 
  209           MI.getOperand(0).getReg() != 
MI.getOperand(1).getReg();
 
 
  216  switch (
MI.getOpcode()) {
 
  219  case AArch64::LDRSBWui:
 
  220  case AArch64::LDRSBXui:
 
  221  case AArch64::LDRSHWui:
 
  222  case AArch64::LDRSHXui:
 
  223  case AArch64::LDRSWui:
 
  224  case AArch64::LDRBui:
 
  225  case AArch64::LDRHui:
 
  226  case AArch64::LDRWui:
 
  227  case AArch64::LDRXui:
 
  228  case AArch64::LDRSui:
 
  229  case AArch64::LDRDui:
 
  230  case AArch64::LDRQui:
 
 
  237  switch (
MI.getOpcode()) {
 
  240  case AArch64::LDRSWui:
 
  241  case AArch64::LDRWui:
 
  242  case AArch64::LDRXui:
 
  243  case AArch64::LDRSui:
 
  244  case AArch64::LDRDui:
 
  245  case AArch64::LDRQui:
 
 
  254  auto It = 
First->getIterator();
 
  255  auto EndIt = 
First->getParent()->instr_end();
 
 
  265  static_assert(AArch64::X28 - AArch64::X0 + 3 == 
N_GPR_REGS, 
"Number of GPRs");
 
  266  static_assert(AArch64::W30 - AArch64::W0 + 1 == 
N_GPR_REGS, 
"Number of GPRs");
 
  267  if (AArch64::X0 <= 
Reg && 
Reg <= AArch64::X28)
 
  268    return Reg - AArch64::X0;
 
  269  if (AArch64::W0 <= 
Reg && 
Reg <= AArch64::W30)
 
  270    return Reg - AArch64::W0;
 
  273  if (
Reg == AArch64::FP)
 
  275  if (
Reg == AArch64::LR)
 
 
  301  if (
Info.MultiUsers || 
Info.OneUser) {
 
  302    Info.IsCandidate = false;
 
  303    Info.MultiUsers = true;
 
  311    Info.IsCandidate = 
true;
 
  317    Info.IsCandidate = 
true;
 
  320  } 
else if (
MI.getOpcode() == AArch64::ADDXri) {
 
  321    Info.Type = MCLOH_AdrpAdd;
 
  322    Info.IsCandidate = true;
 
  324  } 
else if ((
MI.getOpcode() == AArch64::LDRXui ||
 
  325              MI.getOpcode() == AArch64::LDRWui) &&
 
  327    Info.Type = MCLOH_AdrpLdrGot;
 
  328    Info.IsCandidate = true;
 
 
  335  Info.IsCandidate = 
false;
 
  336  Info.OneUser = 
false;
 
  337  Info.MultiUsers = 
false;
 
  338  Info.LastADRP = 
nullptr;
 
 
  348  if (&DefInfo != &OpInfo) {
 
  356  assert(OpInfo.IsCandidate && 
"Expect valid state");
 
  357  if (
MI.getOpcode() == AArch64::ADDXri && canAddBePartOfLOH(
MI)) {
 
  360      OpInfo.IsCandidate = 
true;
 
  365      OpInfo.IsCandidate = 
true;
 
  370    assert((
MI.getOpcode() == AArch64::LDRXui ||
 
  371            MI.getOpcode() == AArch64::LDRWui) &&
 
  372           "Expect LDRXui or LDRWui");
 
  374           "Expected GOT relocation");
 
  377      OpInfo.IsCandidate = 
true;
 
  382      OpInfo.IsCandidate = 
true;
 
 
  393  if (
Info.LastADRP != 
nullptr) {
 
  395                      << 
'\t' << 
MI << 
'\t' << *
Info.LastADRP);
 
  397    ++NumADRPSimpleCandidate;
 
  401  if (
Info.IsCandidate) {
 
  416                        << 
'\t' << 
MI << 
'\t' << *
Info.MI0);
 
  418      ++NumADRSimpleCandidate;
 
  424                          << 
'\t' << 
MI << 
'\t' << *
Info.MI0);
 
  449                        << 
'\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.MI1 << 
'\t' 
  481                        << 
'\t' << 
MI << 
'\t' << *
Info.MI0);
 
 
  505    if (MO.isRegMask()) {
 
  506      const uint32_t *RegMask = MO.getRegMask();
 
  513    if (!MO.isReg() || !MO.isDef())
 
  524    if (!MO.isReg() || !MO.readsReg())
 
  534    if (UsesSeen.
insert(Idx).second)
 
 
  539bool AArch64CollectLOH::runOnMachineFunction(MachineFunction &MF) {
 
  543  LLVM_DEBUG(
dbgs() << 
"********** AArch64 Collect LOH **********\n" 
  544                    << 
"Looking in function " << MF.
getName() << 
'\n');
 
  547  AArch64FunctionInfo &AFI = *MF.
getInfo<AArch64FunctionInfo>();
 
  548  for (
const MachineBasicBlock &
MBB : MF) {
 
  550    memset(LOHInfos, 0, 
sizeof(LOHInfos));
 
  553      for (
const auto &LI : Succ->liveins()) {
 
  556          LOHInfos[RegIdx].
OneUser = 
true;
 
  562    for (
const MachineInstr &
MI :
 
  564      unsigned Opcode = 
MI.getOpcode();
 
  566      case AArch64::ADDXri:
 
  567      case AArch64::LDRXui:
 
  568      case AArch64::LDRWui:
 
  570          const MachineOperand &
Def = 
MI.getOperand(0);
 
  571          const MachineOperand &
Op = 
MI.getOperand(1);
 
  572          assert(
Def.isReg() && 
Def.isDef() && 
"Expected reg def");
 
  573          assert(
Op.isReg() && 
Op.isUse() && 
"Expected reg use");
 
  576          if (DefIdx >= 0 && 
OpIdx >= 0 &&
 
  582        const MachineOperand &Op0 = 
MI.getOperand(0);
 
  599  return new AArch64CollectLOH();
 
 
static int mapRegToGPRIndex(MCRegister Reg)
Map register number to index from 0-30.
 
#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 bool areInstructionsConsecutive(const MachineInstr *First, const MachineInstr *Second)
Returns true if there are no non-debug instructions between First and Second.
 
static const unsigned N_GPR_REGS
Number of GPR registers tracked 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 bool supportLoadFromLiteral(const MachineInstr &MI)
Check whether the given instruction can load a literal.
 
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.
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
Analysis containing CSE Info
 
#define LLVM_PREFERRED_TYPE(T)
\macro LLVM_PREFERRED_TYPE Adjust type of bit-field in debug info.
 
MachineInstr unsigned OpIdx
 
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
 
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.
 
FunctionPass class - This class is used to implement most global optimizations.
 
Wrapper class representing physical registers. Should be passed by value.
 
reverse_instr_iterator instr_rbegin()
 
reverse_instr_iterator instr_rend()
 
iterator_range< succ_iterator > successors()
 
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.
 
Properties which a MachineFunction may have at a given point in time.
 
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 MachineOperand & getOperand(unsigned i) const
 
MachineOperand class - Representation of each machine instruction operand.
 
LLVM_ABI 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_GlobalAddress
Address of a global value.
 
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.
 
LLVM_ABI 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,...
 
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
 
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
 
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.
 
DWARFExpression::Operation Op
 
State tracked per register.
 
MCLOHType Type
"Best" type of LOH possible.
 
unsigned IsCandidate
Possible LOH candidate.
 
unsigned OneUser
Found exactly one user (yet).
 
const MachineInstr * LastADRP
Last ADRP in same register.
 
const MachineInstr * MI1
Second instruction involved in the LOH (if any).
 
const MachineInstr * MI0
First instruction involved in the LOH.
 
unsigned MultiUsers
Found multiple users.