LLVM  14.0.0git
AArch64StorePairSuppress.cpp
Go to the documentation of this file.
1 //===--- AArch64StorePairSuppress.cpp --- Suppress store pair formation ---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass identifies floating point stores that should not be combined into
10 // store pairs. Later we may do the same for floating point loads.
11 // ===---------------------------------------------------------------------===//
12 
13 #include "AArch64InstrInfo.h"
20 #include "llvm/Support/Debug.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "aarch64-stp-suppress"
26 
27 #define STPSUPPRESS_PASS_NAME "AArch64 Store Pair Suppression"
28 
29 namespace {
30 class AArch64StorePairSuppress : public MachineFunctionPass {
31  const AArch64InstrInfo *TII;
32  const TargetRegisterInfo *TRI;
33  const MachineRegisterInfo *MRI;
34  TargetSchedModel SchedModel;
35  MachineTraceMetrics *Traces;
37 
38 public:
39  static char ID;
40  AArch64StorePairSuppress() : MachineFunctionPass(ID) {
42  }
43 
44  StringRef getPassName() const override { return STPSUPPRESS_PASS_NAME; }
45 
46  bool runOnMachineFunction(MachineFunction &F) override;
47 
48 private:
49  bool shouldAddSTPToBlock(const MachineBasicBlock *BB);
50 
51  bool isNarrowFPStore(const MachineInstr &MI);
52 
53  void getAnalysisUsage(AnalysisUsage &AU) const override {
54  AU.setPreservesCFG();
58  }
59 };
61 } // anonymous
62 
63 INITIALIZE_PASS(AArch64StorePairSuppress, "aarch64-stp-suppress",
64  STPSUPPRESS_PASS_NAME, false, false)
65 
67  return new AArch64StorePairSuppress();
68 }
69 
70 /// Return true if an STP can be added to this block without increasing the
71 /// critical resource height. STP is good to form in Ld/St limited blocks and
72 /// bad to form in float-point limited blocks. This is true independent of the
73 /// critical path. If the critical path is longer than the resource height, the
74 /// extra vector ops can limit physreg renaming. Otherwise, it could simply
75 /// oversaturate the vector units.
76 bool AArch64StorePairSuppress::shouldAddSTPToBlock(const MachineBasicBlock *BB) {
77  if (!MinInstr)
78  MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
79 
80  MachineTraceMetrics::Trace BBTrace = MinInstr->getTrace(BB);
81  unsigned ResLength = BBTrace.getResourceLength();
82 
83  // Get the machine model's scheduling class for STPQi.
84  // Bypass TargetSchedule's SchedClass resolution since we only have an opcode.
85  unsigned SCIdx = TII->get(AArch64::STPDi).getSchedClass();
86  const MCSchedClassDesc *SCDesc =
87  SchedModel.getMCSchedModel()->getSchedClassDesc(SCIdx);
88 
89  // If a subtarget does not define resources for STPQi, bail here.
90  if (SCDesc->isValid() && !SCDesc->isVariant()) {
91  unsigned ResLenWithSTP = BBTrace.getResourceLength(None, SCDesc);
92  if (ResLenWithSTP > ResLength) {
93  LLVM_DEBUG(dbgs() << " Suppress STP in BB: " << BB->getNumber()
94  << " resources " << ResLength << " -> " << ResLenWithSTP
95  << "\n");
96  return false;
97  }
98  }
99  return true;
100 }
101 
102 /// Return true if this is a floating-point store smaller than the V reg. On
103 /// cyclone, these require a vector shuffle before storing a pair.
104 /// Ideally we would call getMatchingPairOpcode() and have the machine model
105 /// tell us if it's profitable with no cpu knowledge here.
106 ///
107 /// FIXME: We plan to develop a decent Target abstraction for simple loads and
108 /// stores. Until then use a nasty switch similar to AArch64LoadStoreOptimizer.
109 bool AArch64StorePairSuppress::isNarrowFPStore(const MachineInstr &MI) {
110  switch (MI.getOpcode()) {
111  default:
112  return false;
113  case AArch64::STRSui:
114  case AArch64::STRDui:
115  case AArch64::STURSi:
116  case AArch64::STURDi:
117  return true;
118  }
119 }
120 
121 bool AArch64StorePairSuppress::runOnMachineFunction(MachineFunction &MF) {
122  if (skipFunction(MF.getFunction()) || MF.getFunction().hasOptSize())
123  return false;
124 
125  const TargetSubtargetInfo &ST = MF.getSubtarget();
126  TII = static_cast<const AArch64InstrInfo *>(ST.getInstrInfo());
127  TRI = ST.getRegisterInfo();
128  MRI = &MF.getRegInfo();
129  SchedModel.init(&ST);
130  Traces = &getAnalysis<MachineTraceMetrics>();
131  MinInstr = nullptr;
132 
133  LLVM_DEBUG(dbgs() << "*** " << getPassName() << ": " << MF.getName() << '\n');
134 
135  if (!SchedModel.hasInstrSchedModel()) {
136  LLVM_DEBUG(dbgs() << " Skipping pass: no machine model present.\n");
137  return false;
138  }
139 
140  // Check for a sequence of stores to the same base address. We don't need to
141  // precisely determine whether a store pair can be formed. But we do want to
142  // filter out most situations where we can't form store pairs to avoid
143  // computing trace metrics in those cases.
144  for (auto &MBB : MF) {
145  bool SuppressSTP = false;
146  unsigned PrevBaseReg = 0;
147  for (auto &MI : MBB) {
148  if (!isNarrowFPStore(MI))
149  continue;
150  const MachineOperand *BaseOp;
151  int64_t Offset;
152  bool OffsetIsScalable;
153  if (TII->getMemOperandWithOffset(MI, BaseOp, Offset, OffsetIsScalable,
154  TRI) &&
155  BaseOp->isReg()) {
156  Register BaseReg = BaseOp->getReg();
157  if (PrevBaseReg == BaseReg) {
158  // If this block can take STPs, skip ahead to the next block.
159  if (!SuppressSTP && shouldAddSTPToBlock(MI.getParent()))
160  break;
161  // Otherwise, continue unpairing the stores in this block.
162  LLVM_DEBUG(dbgs() << "Unpairing store " << MI << "\n");
163  SuppressSTP = true;
164  TII->suppressLdStPair(MI);
165  }
166  PrevBaseReg = BaseReg;
167  } else
168  PrevBaseReg = 0;
169  }
170  }
171  // This pass just sets some internal MachineMemOperand flags. It can't really
172  // invalidate anything.
173  return false;
174 }
INITIALIZE_PASS
INITIALIZE_PASS(AArch64StorePairSuppress, "aarch64-stp-suppress", STPSUPPRESS_PASS_NAME, false, false) FunctionPass *llvm
Definition: AArch64StorePairSuppress.cpp:63
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
MachineInstr.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::MachineTraceMetrics::TS_MinInstrCount
@ TS_MinInstrCount
Select the trace through a block that has the fewest instructions.
Definition: MachineTraceMetrics.h:379
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
TargetInstrInfo.h
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MCSchedClassDesc::isValid
bool isValid() const
Definition: MCSchedule.h:127
F
#define F(x, y, z)
Definition: MD5.cpp:56
MachineTraceMetrics.h
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:644
AArch64InstrInfo.h
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
llvm::AArch64InstrInfo
Definition: AArch64InstrInfo.h:38
llvm::initializeAArch64StorePairSuppressPass
void initializeAArch64StorePairSuppressPass(PassRegistry &)
llvm::MCSchedClassDesc
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition: MCSchedule.h:109
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::createAArch64StorePairSuppressPass
FunctionPass * createAArch64StorePairSuppressPass()
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MachineTraceMetrics::Trace
A trace represents a plausible sequence of executed basic blocks that passes through the current basi...
Definition: MachineTraceMetrics.h:255
STPSUPPRESS_PASS_NAME
#define STPSUPPRESS_PASS_NAME
Definition: AArch64StorePairSuppress.cpp:27
llvm::None
const NoneType None
Definition: None.h:23
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
TargetSchedule.h
llvm::TargetSchedModel
Provide an instruction scheduling machine model to CodeGen passes.
Definition: TargetSchedule.h:30
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
MachineFunctionPass.h
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:542
llvm::MachineTraceMetrics::Trace::getResourceLength
unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks=None, ArrayRef< const MCSchedClassDesc * > ExtraInstrs=None, ArrayRef< const MCSchedClassDesc * > RemoveInstrs=None) const
Return the resource length of the trace.
Definition: MachineTraceMetrics.cpp:1224
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition: TargetSubtargetInfo.h:59
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::Function::hasOptSize
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
Definition: Function.h:661
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineTraceMetrics::Ensemble
A trace ensemble is a collection of traces selected using the same strategy, for example 'minimum res...
Definition: MachineTraceMetrics.h:321
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:600
llvm::MCSchedClassDesc::isVariant
bool isVariant() const
Definition: MCSchedule.h:130
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
raw_ostream.h
MachineFunction.h
llvm::MachineTraceMetrics
Definition: MachineTraceMetrics.h:87
Debug.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38