void initializeAArch64CollectLOHPass(PassRegistry &);
}
+#define AARCH64_COLLECT_LOH_NAME "AArch64 Collect Linker Optimization Hint (LOH)"
+
namespace {
struct AArch64CollectLOH : public MachineFunctionPass {
static char ID;
bool runOnMachineFunction(MachineFunction &MF) override;
const char *getPassName() const override {
- return "AArch64 Collect Linker Optimization Hint (LOH)";
+ return AARCH64_COLLECT_LOH_NAME;
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
char AArch64CollectLOH::ID = 0;
INITIALIZE_PASS_BEGIN(AArch64CollectLOH, "aarch64-collect-loh",
- "AArch64 Collect Linker Optimization Hint (LOH)", false,
- false)
+ AARCH64_COLLECT_LOH_NAME, false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_END(AArch64CollectLOH, "aarch64-collect-loh",
- "AArch64 Collect Linker Optimization Hint (LOH)", false,
- false)
+ AARCH64_COLLECT_LOH_NAME, false, false)
/// Given a couple (MBB, reg) get the corresponding set of instruction from
/// the given "sets".
/// definition. It also consider definitions of ADRP instructions as uses and
/// ignore other uses. The ADRPMode is used to collect the information for LHO
/// that involve ADRP operation only.
-static void initReachingDef(MachineFunction &MF,
+static void initReachingDef(const MachineFunction &MF,
InstrToInstrs *ColorOpToReachedUses,
BlockToInstrPerColor &Gen, BlockToRegSet &Kill,
BlockToSetOfInstrsPerColor &ReachableUses,
const MapRegToId &RegToId,
const MachineInstr *DummyOp, bool ADRPMode) {
- const TargetMachine &TM = MF.getTarget();
- const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
-
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
unsigned NbReg = RegToId.size();
- for (MachineBasicBlock &MBB : MF) {
+ for (const MachineBasicBlock &MBB : MF) {
auto &BBGen = Gen[&MBB];
BBGen = make_unique<const MachineInstr *[]>(NbReg);
- memset(BBGen.get(), 0, sizeof(const MachineInstr *) * NbReg);
+ std::fill(BBGen.get(), BBGen.get() + NbReg, nullptr);
BitVector &BBKillSet = Kill[&MBB];
BBKillSet.resize(NbReg);
const uint32_t *PreservedRegs = MO.getRegMask();
// Set generated regs.
- for (const auto Entry : RegToId) {
+ for (const auto &Entry : RegToId) {
unsigned Reg = Entry.second;
// Use the global register ID when querying APIs external to this
// pass.
for (MCRegAliasIterator AI(CurReg, TRI, true); AI.isValid(); ++AI) {
MapRegToId::const_iterator ItRegId = RegToId.find(*AI);
- assert(ItRegId != RegToId.end() &&
- "Sub-register of an "
- "involved register, not recorded as involved!");
+ // If this alias has not been recorded, then it is not interesting
+ // for the current analysis.
+ // We can end up in this situation because of tuple registers.
+ // E.g., Let say we are interested in S1. When we register
+ // S1, we will also register its aliases and in particular
+ // the tuple Q1_Q2.
+ // Now, when we encounter Q1_Q2, we will look through its aliases
+ // and will find that S2 is not registered.
+ if (ItRegId == RegToId.end())
+ continue;
+
BBKillSet.set(ItRegId->second);
BBGen[ItRegId->second] = &MI;
}
/// op.reachedUses
///
/// Out[bb] = Gen[bb] U (In[bb] - Kill[bb])
-static void reachingDefAlgorithm(MachineFunction &MF,
+static void reachingDefAlgorithm(const MachineFunction &MF,
InstrToInstrs *ColorOpToReachedUses,
BlockToSetOfInstrsPerColor &In,
BlockToSetOfInstrsPerColor &Out,
bool HasChanged;
do {
HasChanged = false;
- for (MachineBasicBlock &MBB : MF) {
+ for (const MachineBasicBlock &MBB : MF) {
unsigned CurReg;
for (CurReg = 0; CurReg < NbReg; ++CurReg) {
SetOfMachineInstr &BBInSet = getSet(In, MBB, CurReg, NbReg);
SetOfMachineInstr &BBOutSet = getSet(Out, MBB, CurReg, NbReg);
unsigned Size = BBOutSet.size();
// In[bb][color] = U Out[bb.predecessors][color]
- for (MachineBasicBlock *PredMBB : MBB.predecessors()) {
+ for (const MachineBasicBlock *PredMBB : MBB.predecessors()) {
SetOfMachineInstr &PredOutSet = getSet(Out, *PredMBB, CurReg, NbReg);
BBInSet.insert(PredOutSet.begin(), PredOutSet.end());
}
/// @p DummyOp.
/// \pre ColorOpToReachedUses is an array of at least number of registers of
/// InstrToInstrs.
-static void reachingDef(MachineFunction &MF,
+static void reachingDef(const MachineFunction &MF,
InstrToInstrs *ColorOpToReachedUses,
const MapRegToId &RegToId, bool ADRPMode = false,
const MachineInstr *DummyOp = nullptr) {
switch (Instr->getOpcode()) {
default:
return false;
+ case AArch64::STRBBui:
+ case AArch64::STRHHui:
case AArch64::STRBui:
case AArch64::STRHui:
case AArch64::STRWui:
bool IsL2Add = (ImmediateDefOpc == AArch64::ADDXri);
// If the chain is three instructions long and ldr is the second element,
// then this ldr must load form GOT, otherwise this is not a correct chain.
- if (L2 && !IsL2Add && L2->getOperand(2).getTargetFlags() != AArch64II::MO_GOT)
+ if (L2 && !IsL2Add &&
+ !(L2->getOperand(2).getTargetFlags() & AArch64II::MO_GOT))
continue;
SmallVector<const MachineInstr *, 3> Args;
MCLOHType Kind;
/// Look for every register defined by potential LOHs candidates.
/// Map these registers with dense id in @p RegToId and vice-versa in
/// @p IdToReg. @p IdToReg is populated only in DEBUG mode.
-static void collectInvolvedReg(MachineFunction &MF, MapRegToId &RegToId,
+static void collectInvolvedReg(const MachineFunction &MF, MapRegToId &RegToId,
MapIdToReg &IdToReg,
const TargetRegisterInfo *TRI) {
unsigned CurRegId = 0;
DEBUG(dbgs() << "** Collect Involved Register\n");
for (const auto &MBB : MF) {
for (const MachineInstr &MI : MBB) {
- if (!canDefBePartOfLOH(&MI))
+ if (!canDefBePartOfLOH(&MI) &&
+ !isCandidateLoad(&MI) && !isCandidateStore(&MI))
continue;
// Process defs
}
bool AArch64CollectLOH::runOnMachineFunction(MachineFunction &MF) {
- const TargetMachine &TM = MF.getTarget();
- const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
const MachineDominatorTree *MDT = &getAnalysis<MachineDominatorTree>();
MapRegToId RegToId;
MachineInstr *DummyOp = nullptr;
if (BasicBlockScopeOnly) {
- const AArch64InstrInfo *TII = static_cast<const AArch64InstrInfo *>(
- TM.getSubtargetImpl()->getInstrInfo());
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
// For local analysis, create a dummy operation to record uses that are not
// local.
DummyOp = MF.CreateMachineInstr(TII->get(AArch64::COPY), DebugLoc());