15#define GET_INSTRMAP_INFO 
   32#define OPTADDRMODE_DESC "ARC load/store address mode" 
   33#define OPTADDRMODE_NAME "arc-addr-mode" 
   34#define DEBUG_TYPE "arc-addr-mode" 
   41#define DUMP_BEFORE() ((ArcKillAddrMode & 0x0001) != 0) 
   42#define DUMP_AFTER() ((ArcKillAddrMode & 0x0002) != 0) 
   43#define VIEW_BEFORE() ((ArcKillAddrMode & 0x0004) != 0) 
   44#define VIEW_AFTER() ((ArcKillAddrMode & 0x0008) != 0) 
   45#define KILL_PASS() ((ArcKillAddrMode & 0x0010) != 0) 
   60  void getAnalysisUsage(AnalysisUsage &AU)
 const override {
 
   67  bool runOnMachineFunction(MachineFunction &MF) 
override;
 
   70  const ARCSubtarget *AST = 
nullptr;
 
   71  const ARCInstrInfo *AII = 
nullptr;
 
   72  MachineRegisterInfo *MRI = 
nullptr;
 
   73  MachineDominatorTree *MDT = 
nullptr;
 
   77  MachineInstr *tryToCombine(MachineInstr &Ldst);
 
   80  bool noUseOfAddBeforeLoadOrStore(
const MachineInstr *
Add,
 
   81                                   const MachineInstr *Ldst);
 
   85  bool canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To);
 
   95  MachineInstr *canJoinInstructions(MachineInstr *Ldst, MachineInstr *
Add,
 
   96                                    SmallVectorImpl<MachineInstr *> *
Uses);
 
  101                      MachineOperand &Incr, 
unsigned BaseReg);
 
  111  void changeToAddrMode(MachineInstr &Ldst, 
unsigned NewOpcode,
 
  112                        unsigned NewBase, MachineOperand &NewOffset);
 
  114  bool processBasicBlock(MachineBasicBlock &
MBB);
 
  119char ARCOptAddrMode::ID = 0;
 
  136  switch (
MI.getOpcode()) {
 
  141    assert(
MI.getOperand(2).isImm() && 
"Expected immediate operand");
 
  142    Amount = Sign * 
MI.getOperand(2).getImm();
 
 
  163        assert(InstBB != 
MBB && 
"Instruction found in empty MBB");
 
 
  182  unsigned BasePos, OffPos;
 
  183  if (!
TII->getBaseAndOffsetPosition(
MI, BasePos, OffPos))
 
 
  192bool ARCOptAddrMode::noUseOfAddBeforeLoadOrStore(
const MachineInstr *
Add,
 
  198MachineInstr *ARCOptAddrMode::tryToCombine(MachineInstr &Ldst) {
 
  201  unsigned BasePos, OffsetPos;
 
  212  assert(
Base.isReg() && 
"Base operand must be register");
 
  219  if (!Register::isVirtualRegister(
B)) {
 
  225  if (
Offset.getImm() != 0) {
 
  230  for (
auto &
Add : 
MRI->use_nodbg_instructions(
B)) {
 
  237    SmallVector<MachineInstr *, 8> 
Uses;
 
  238    MachineInstr *MoveTo = canJoinInstructions(&Ldst, &
Add, &
Uses);
 
  243    if (!canFixPastUses(
Uses, 
Add.getOperand(2), 
B))
 
  248               dbgs() << 
"[ABAW] Instructions " << *
First << 
" and " << *
Last 
  254    if (MoveTo == &
Add) {
 
  261    fixPastUses(
Uses, 
B, Incr);
 
  263    int NewOpcode = ARC::getPostIncOpcode(Ldst.
getOpcode());
 
  264    assert(NewOpcode > 0 && 
"No postincrement form found");
 
  265    unsigned NewBaseReg = 
Add.getOperand(0).getReg();
 
  266    changeToAddrMode(Ldst, NewOpcode, NewBaseReg, 
Add.getOperand(2));
 
  267    Add.eraseFromParent();
 
  275ARCOptAddrMode::canJoinInstructions(MachineInstr *Ldst, MachineInstr *
Add,
 
  276                                    SmallVectorImpl<MachineInstr *> *
Uses) {
 
  277  assert(Ldst && 
Add && 
"NULL instruction passed");
 
  280  MachineInstr *
Last = Ldst;
 
  288  unsigned BasePos, OffPos;
 
  293        << 
"[canJoinInstructions] Cannot determine base/offset position\n");
 
  307    if (
Add->getOperand(0).getReg() == StReg || BaseReg == StReg) {
 
  308      LLVM_DEBUG(
dbgs() << 
"[canJoinInstructions] Store uses result of Add\n");
 
  313  SmallVector<MachineInstr *, 4> UsesAfterLdst;
 
  314  SmallVector<MachineInstr *, 4> UsesAfterAdd;
 
  315  for (MachineInstr &
MI : 
MRI->use_nodbg_instructions(BaseReg)) {
 
  326  MachineInstr *
Result = 
nullptr;
 
  333    if (noUseOfAddBeforeLoadOrStore(
First, 
Last)) {
 
  335      LLVM_DEBUG(
dbgs() << 
"[canJoinInstructions] Can sink Add down to Ldst\n");
 
  336    } 
else if (canHoistLoadStoreTo(Ldst, 
Add)) {
 
  338      LLVM_DEBUG(
dbgs() << 
"[canJoinInstructions] Can hoist Ldst to Add\n");
 
  345    LLVM_DEBUG(
dbgs() << 
"[canJoinInstructions] Can hoist Add to Ldst\n");
 
  348    *
Uses = (
Result == Ldst) ? UsesAfterLdst : UsesAfterAdd;
 
  353                                    MachineOperand &Incr, 
unsigned BaseReg) {
 
  355  assert(Incr.
isImm() && 
"Expected immediate increment");
 
  356  int64_t NewOffset = Incr.
getImm();
 
  357  for (MachineInstr *
MI : 
Uses) {
 
  366    LLVM_DEBUG(
dbgs() << 
"Instruction cannot handle displacement " << -NewOffset
 
  374                                 unsigned NewBase, int64_t NewOffset) {
 
  376  for (MachineInstr *
MI : 
Uses) {
 
  378    unsigned BasePos, OffPos;
 
  382             "New offset won't fit into ADD instr");
 
  386      MachineOperand &MO = 
MI->getOperand(OffPos);
 
  387      assert(MO.
isImm() && 
"expected immediate operand");
 
  390             "New offset won't fit into LD/ST");
 
  394    MI->getOperand(BasePos).setReg(NewBase);
 
  395    MI->getOperand(OffPos).setImm(NewOffset);
 
  399bool ARCOptAddrMode::canHoistLoadStoreTo(MachineInstr *Ldst, MachineInstr *To) {
 
  406  for (; 
MI != ME && 
MI != End; ++
MI) {
 
  407    if (
MI->isDebugValue())
 
  409    if (
MI->mayStore() || 
MI->isCall() || 
MI->isInlineAsm() ||
 
  410        MI->hasUnmodeledSideEffects())
 
  412    if (IsStore && 
MI->mayLoad())
 
  417    if (!
O.isReg() || !
O.isUse())
 
  419    MachineInstr *OpDef = 
MRI->getVRegDef(
O.getReg());
 
  420    if (!OpDef || !MDT->
dominates(OpDef, To))
 
  451void ARCOptAddrMode::changeToAddrMode(MachineInstr &Ldst, 
unsigned NewOpcode,
 
  453                                      MachineOperand &NewOffset) {
 
  455  unsigned BasePos, OffPos;
 
  478bool ARCOptAddrMode::processBasicBlock(MachineBasicBlock &
MBB) {
 
  481    if (
MI->isDebugValue())
 
  483    if (!
MI->mayLoad() && !
MI->mayStore())
 
  485    if (ARC::getPostIncOpcode(
MI->getOpcode()) < 0)
 
  487    MachineInstr *Res = tryToCombine(*
MI);
 
  497bool ARCOptAddrMode::runOnMachineFunction(MachineFunction &MF) {
 
  501#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 
  511  MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
 
  517#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isLoadStoreThatCanHandleDisplacement(const TargetInstrInfo *TII, const MachineInstr &MI, int64_t Disp)
static bool dominatesAllUsesOf(const MachineInstr *MI, unsigned VReg, MachineDominatorTree *MDT, MachineRegisterInfo *MRI)
static bool isValidIncrementOffset(int64_t Off)
static false bool isValidLoadStoreOffset(int64_t Off)
static bool isAddConstantOp(const MachineInstr &MI, int64_t &Amount)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Remove Loads Into Fake Uses
virtual bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
const ARCInstrInfo * getInstrInfo() const override
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBundleIterator< const MachineInstr > const_iterator
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
void viewCFG() const
viewCFG - This function is meant for use from the debugger.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
LLVM_ABI MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
mop_range explicit_operands()
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
void push_back(const T &Elt)
TargetInstrInfo - Interface to description of machine instruction set.
A Use represents the edge between a Value definition and its users.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Value * getOperand(unsigned i) const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
void initializeARCOptAddrModePass(PassRegistry &)
static cl::opt< unsigned > ArcKillAddrMode("arc-kill-addr-mode", cl::init(0), cl::ReallyHidden)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
ArrayRef(const T &OneElt) -> ArrayRef< T >
FunctionPass * createARCOptAddrMode()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.