LLVM 20.0.0git
Macros | Functions | Variables
ARMLoadStoreOptimizer.cpp File Reference
#include "ARM.h"
#include "ARMBaseInstrInfo.h"
#include "ARMBaseRegisterInfo.h"
#include "ARMISelLowering.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMSubtarget.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
#include "Utils/ARMBaseInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <iterator>
#include <limits>
#include <utility>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "arm-ldst-opt"
 
#define ARM_LOAD_STORE_OPT_NAME   "ARM load / store optimization pass"
 
#define ARM_PREALLOC_LOAD_STORE_OPT_NAME    "ARM pre- register allocation load / store optimization pass"
 

Functions

 STATISTIC (NumLDMGened, "Number of ldm instructions generated")
 
 STATISTIC (NumSTMGened, "Number of stm instructions generated")
 
 STATISTIC (NumVLDMGened, "Number of vldm instructions generated")
 
 STATISTIC (NumVSTMGened, "Number of vstm instructions generated")
 
 STATISTIC (NumLdStMoved, "Number of load / store instructions moved")
 
 STATISTIC (NumLDRDFormed,"Number of ldrd created before allocation")
 
 STATISTIC (NumSTRDFormed,"Number of strd created before allocation")
 
 STATISTIC (NumLDRD2LDM, "Number of ldrd instructions turned back into ldm")
 
 STATISTIC (NumSTRD2STM, "Number of strd instructions turned back into stm")
 
 STATISTIC (NumLDRD2LDR, "Number of ldrd instructions turned back into ldr's")
 
 STATISTIC (NumSTRD2STR, "Number of strd instructions turned back into str's")
 
 INITIALIZE_PASS (ARMLoadStoreOpt, "arm-ldst-opt", ARM_LOAD_STORE_OPT_NAME, false, false) static bool definesCPSR(const MachineInstr &MI)
 
static int getMemoryOpOffset (const MachineInstr &MI)
 
static const MachineOperandgetLoadStoreBaseOp (const MachineInstr &MI)
 
static const MachineOperandgetLoadStoreRegOp (const MachineInstr &MI)
 
static int getLoadStoreMultipleOpcode (unsigned Opcode, ARM_AM::AMSubMode Mode)
 
static ARM_AM::AMSubMode getLoadStoreMultipleSubMode (unsigned Opcode)
 
static bool isT1i32Load (unsigned Opc)
 
static bool isT2i32Load (unsigned Opc)
 
static bool isi32Load (unsigned Opc)
 
static bool isT1i32Store (unsigned Opc)
 
static bool isT2i32Store (unsigned Opc)
 
static bool isi32Store (unsigned Opc)
 
static bool isLoadSingle (unsigned Opc)
 
static unsigned getImmScale (unsigned Opc)
 
static unsigned getLSMultipleTransferSize (const MachineInstr *MI)
 
static bool ContainsReg (const ArrayRef< std::pair< unsigned, bool > > &Regs, unsigned Reg)
 
static bool isValidLSDoubleOffset (int Offset)
 
static bool mayCombineMisaligned (const TargetSubtargetInfo &STI, const MachineInstr &MI)
 Return true for loads/stores that can be combined to a double/multi operation without increasing the requirements for alignment.
 
static unsigned getUpdatingLSMultipleOpcode (unsigned Opc, ARM_AM::AMSubMode Mode)
 
static int isIncrementOrDecrement (const MachineInstr &MI, Register Reg, ARMCC::CondCodes Pred, Register PredReg)
 Check if the given instruction increments or decrements a register and return the amount it is incremented/decremented.
 
static MachineBasicBlock::iterator findIncDecBefore (MachineBasicBlock::iterator MBBI, Register Reg, ARMCC::CondCodes Pred, Register PredReg, int &Offset)
 Searches for an increment or decrement of Reg before MBBI.
 
static MachineBasicBlock::iterator findIncDecAfter (MachineBasicBlock::iterator MBBI, Register Reg, ARMCC::CondCodes Pred, Register PredReg, int &Offset, const TargetRegisterInfo *TRI)
 Searches for a increment or decrement of Reg after MBBI.
 
static unsigned getPreIndexedLoadStoreOpcode (unsigned Opc, ARM_AM::AddrOpc Mode)
 
static unsigned getPostIndexedLoadStoreOpcode (unsigned Opc, ARM_AM::AddrOpc Mode)
 
static bool isMemoryOp (const MachineInstr &MI)
 Returns true if instruction is a memory operation that this pass is capable of operating on.
 
static void InsertLDR_STR (MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int Offset, bool isDef, unsigned NewOpc, unsigned Reg, bool RegDeadKill, bool RegUndef, unsigned BaseReg, bool BaseKill, bool BaseUndef, ARMCC::CondCodes Pred, unsigned PredReg, const TargetInstrInfo *TII, MachineInstr *MI)
 
 INITIALIZE_PASS_BEGIN (ARMPreAllocLoadStoreOpt, "arm-prera-ldst-opt", ARM_PREALLOC_LOAD_STORE_OPT_NAME, false, false) INITIALIZE_PASS_END(ARMPreAllocLoadStoreOpt
 
arm prera ldst static false cl::opt< unsignedInstReorderLimit ("arm-prera-ldst-opt-reorder-limit", cl::init(8), cl::Hidden)
 
static bool IsSafeAndProfitableToMove (bool isLd, unsigned Base, MachineBasicBlock::iterator I, MachineBasicBlock::iterator E, SmallPtrSetImpl< MachineInstr * > &MemOps, SmallSet< unsigned, 4 > &MemRegs, const TargetRegisterInfo *TRI, AliasAnalysis *AA)
 
static void forEachDbgRegOperand (MachineInstr *MI, std::function< void(MachineOperand &)> Fn)
 
static void updateRegisterMapForDbgValueListAfterMove (SmallDenseMap< Register, SmallVector< MachineInstr * >, 8 > &RegisterMap, MachineInstr *DbgValueListInstr, MachineInstr *InstrToReplace)
 
static DebugVariable createDebugVariableFromMachineInstr (MachineInstr *MI)
 
static int getBaseOperandIndex (MachineInstr &MI)
 
static bool isPostIndex (MachineInstr &MI)
 
static bool isPreIndex (MachineInstr &MI)
 
static bool isLegalOrConvertableAddressImm (unsigned Opcode, int Imm, const TargetInstrInfo *TII, int &CodesizeEstimate)
 
static void AdjustBaseAndOffset (MachineInstr *MI, Register NewBaseReg, int Offset, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
 
static MachineInstrcreatePostIncLoadStore (MachineInstr *MI, int Offset, Register NewReg, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
 

Variables

static cl::opt< boolAssumeMisalignedLoadStores ("arm-assume-misaligned-load-store", cl::Hidden, cl::init(false), cl::desc("Be more conservative in ARM load/store opt"))
 This switch disables formation of double/multi instructions that could potentially lead to (new) alignment traps even with CCR.UNALIGN_TRP disabled.
 
arm prera ldst opt
 
arm prera ldst ARM_PREALLOC_LOAD_STORE_OPT_NAME
 
arm prera ldst false
 

Macro Definition Documentation

◆ ARM_LOAD_STORE_OPT_NAME

#define ARM_LOAD_STORE_OPT_NAME   "ARM load / store optimization pass"

Definition at line 97 of file ARMLoadStoreOptimizer.cpp.

◆ ARM_PREALLOC_LOAD_STORE_OPT_NAME

#define ARM_PREALLOC_LOAD_STORE_OPT_NAME    "ARM pre- register allocation load / store optimization pass"

Definition at line 2135 of file ARMLoadStoreOptimizer.cpp.

◆ DEBUG_TYPE

#define DEBUG_TYPE   "arm-ldst-opt"

Definition at line 74 of file ARMLoadStoreOptimizer.cpp.

Function Documentation

◆ AdjustBaseAndOffset()

static void AdjustBaseAndOffset ( MachineInstr MI,
Register  NewBaseReg,
int  Offset,
const TargetInstrInfo TII,
const TargetRegisterInfo TRI 
)
static

◆ ContainsReg()

static bool ContainsReg ( const ArrayRef< std::pair< unsigned, bool > > &  Regs,
unsigned  Reg 
)
static

Definition at line 617 of file ARMLoadStoreOptimizer.cpp.

◆ createDebugVariableFromMachineInstr()

static DebugVariable createDebugVariableFromMachineInstr ( MachineInstr MI)
static

Definition at line 2526 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ createPostIncLoadStore()

static MachineInstr * createPostIncLoadStore ( MachineInstr MI,
int  Offset,
Register  NewReg,
const TargetInstrInfo TII,
const TargetRegisterInfo TRI 
)
static

◆ findIncDecAfter()

static MachineBasicBlock::iterator findIncDecAfter ( MachineBasicBlock::iterator  MBBI,
Register  Reg,
ARMCC::CondCodes  Pred,
Register  PredReg,
int &  Offset,
const TargetRegisterInfo TRI 
)
static

Searches for a increment or decrement of Reg after MBBI.

Definition at line 1243 of file ARMLoadStoreOptimizer.cpp.

References llvm::MachineBasicBlock::end(), llvm::MachineBasicBlock::getParent(), isIncrementOrDecrement(), MBB, MBBI, llvm::Offset, and TRI.

◆ findIncDecBefore()

static MachineBasicBlock::iterator findIncDecBefore ( MachineBasicBlock::iterator  MBBI,
Register  Reg,
ARMCC::CondCodes  Pred,
Register  PredReg,
int &  Offset 
)
static

Searches for an increment or decrement of Reg before MBBI.

Definition at line 1223 of file ARMLoadStoreOptimizer.cpp.

References llvm::MachineBasicBlock::begin(), llvm::MachineBasicBlock::end(), llvm::MachineBasicBlock::getParent(), isIncrementOrDecrement(), MBB, MBBI, and llvm::Offset.

◆ forEachDbgRegOperand()

static void forEachDbgRegOperand ( MachineInstr MI,
std::function< void(MachineOperand &)>  Fn 
)
static

Definition at line 2494 of file ARMLoadStoreOptimizer.cpp.

References I, and MI.

Referenced by updateRegisterMapForDbgValueListAfterMove().

◆ getBaseOperandIndex()

static int getBaseOperandIndex ( MachineInstr MI)
static

Definition at line 2881 of file ARMLoadStoreOptimizer.cpp.

References MI.

Referenced by AdjustBaseAndOffset().

◆ getImmScale()

static unsigned getImmScale ( unsigned  Opc)
static

Definition at line 423 of file ARMLoadStoreOptimizer.cpp.

References llvm_unreachable.

◆ getLoadStoreBaseOp()

static const MachineOperand & getLoadStoreBaseOp ( const MachineInstr MI)
static

Definition at line 248 of file ARMLoadStoreOptimizer.cpp.

References MI.

Referenced by mayCombineMisaligned().

◆ getLoadStoreMultipleOpcode()

static int getLoadStoreMultipleOpcode ( unsigned  Opcode,
ARM_AM::AMSubMode  Mode 
)
static

◆ getLoadStoreMultipleSubMode()

static ARM_AM::AMSubMode getLoadStoreMultipleSubMode ( unsigned  Opcode)
static

◆ getLoadStoreRegOp()

static const MachineOperand & getLoadStoreRegOp ( const MachineInstr MI)
static

Definition at line 252 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ getLSMultipleTransferSize()

static unsigned getLSMultipleTransferSize ( const MachineInstr MI)
static

Definition at line 440 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ getMemoryOpOffset()

static int getMemoryOpOffset ( const MachineInstr MI)
static

◆ getPostIndexedLoadStoreOpcode()

static unsigned getPostIndexedLoadStoreOpcode ( unsigned  Opc,
ARM_AM::AddrOpc  Mode 
)
static

Definition at line 1392 of file ARMLoadStoreOptimizer.cpp.

References llvm::ARM_AM::add, and llvm_unreachable.

Referenced by createPostIncLoadStore().

◆ getPreIndexedLoadStoreOpcode()

static unsigned getPreIndexedLoadStoreOpcode ( unsigned  Opc,
ARM_AM::AddrOpc  Mode 
)
static

Definition at line 1367 of file ARMLoadStoreOptimizer.cpp.

References llvm::ARM_AM::add, and llvm_unreachable.

◆ getUpdatingLSMultipleOpcode()

static unsigned getUpdatingLSMultipleOpcode ( unsigned  Opc,
ARM_AM::AMSubMode  Mode 
)
static

◆ INITIALIZE_PASS()

INITIALIZE_PASS ( ARMLoadStoreOpt  ,
"arm-ldst-opt"  ,
ARM_LOAD_STORE_OPT_NAME  ,
false  ,
false   
) const &

Definition at line 204 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ INITIALIZE_PASS_BEGIN()

INITIALIZE_PASS_BEGIN ( ARMPreAllocLoadStoreOpt  ,
"arm-prera-ldst-opt"  ,
ARM_PREALLOC_LOAD_STORE_OPT_NAME  ,
false  ,
false   
)

◆ InsertLDR_STR()

static void InsertLDR_STR ( MachineBasicBlock MBB,
MachineBasicBlock::iterator MBBI,
int  Offset,
bool  isDef,
unsigned  NewOpc,
unsigned  Reg,
bool  RegDeadKill,
bool  RegUndef,
unsigned  BaseReg,
bool  BaseKill,
bool  BaseUndef,
ARMCC::CondCodes  Pred,
unsigned  PredReg,
const TargetInstrInfo TII,
MachineInstr MI 
)
static

◆ InstReorderLimit()

arm prera ldst static false cl::opt< unsigned > InstReorderLimit ( "arm-prera-ldst-opt-reorder-limit"  ,
cl::init(8)  ,
cl::Hidden   
)
static

◆ isi32Load()

static bool isi32Load ( unsigned  Opc)
static

Definition at line 403 of file ARMLoadStoreOptimizer.cpp.

References isT1i32Load(), and isT2i32Load().

Referenced by isLoadSingle(), and mayCombineMisaligned().

◆ isi32Store()

static bool isi32Store ( unsigned  Opc)
static

Definition at line 415 of file ARMLoadStoreOptimizer.cpp.

References isT1i32Store(), and isT2i32Store().

Referenced by mayCombineMisaligned().

◆ isIncrementOrDecrement()

static int isIncrementOrDecrement ( const MachineInstr MI,
Register  Reg,
ARMCC::CondCodes  Pred,
Register  PredReg 
)
static

Check if the given instruction increments or decrements a register and return the amount it is incremented/decremented.

Returns 0 if the CPSR flags generated by the instruction are possibly read as well.

Definition at line 1191 of file ARMLoadStoreOptimizer.cpp.

References llvm::getInstrPredicate(), and MI.

Referenced by findIncDecAfter(), and findIncDecBefore().

◆ isLegalOrConvertableAddressImm()

static bool isLegalOrConvertableAddressImm ( unsigned  Opcode,
int  Imm,
const TargetInstrInfo TII,
int &  CodesizeEstimate 
)
static

◆ isLoadSingle()

static bool isLoadSingle ( unsigned  Opc)
static

Definition at line 419 of file ARMLoadStoreOptimizer.cpp.

References isi32Load().

◆ isMemoryOp()

static bool isMemoryOp ( const MachineInstr MI)
static

Returns true if instruction is a memory operation that this pass is capable of operating on.

Definition at line 1678 of file ARMLoadStoreOptimizer.cpp.

References llvm::MachineMemOperand::getAlign(), llvm::MachineMemOperand::isAtomic(), llvm::MachineMemOperand::isVolatile(), and MI.

◆ isPostIndex()

static bool isPostIndex ( MachineInstr MI)
static

Definition at line 2946 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ isPreIndex()

static bool isPreIndex ( MachineInstr MI)
static

Definition at line 2968 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ IsSafeAndProfitableToMove()

static bool IsSafeAndProfitableToMove ( bool  isLd,
unsigned  Base,
MachineBasicBlock::iterator  I,
MachineBasicBlock::iterator  E,
SmallPtrSetImpl< MachineInstr * > &  MemOps,
SmallSet< unsigned, 4 > &  MemRegs,
const TargetRegisterInfo TRI,
AliasAnalysis AA 
)
static

◆ isT1i32Load()

static bool isT1i32Load ( unsigned  Opc)
static

Definition at line 395 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Load().

◆ isT1i32Store()

static bool isT1i32Store ( unsigned  Opc)
static

Definition at line 407 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Store().

◆ isT2i32Load()

static bool isT2i32Load ( unsigned  Opc)
static

Definition at line 399 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Load().

◆ isT2i32Store()

static bool isT2i32Store ( unsigned  Opc)
static

Definition at line 411 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Store().

◆ isValidLSDoubleOffset()

static bool isValidLSDoubleOffset ( int  Offset)
static

Definition at line 979 of file ARMLoadStoreOptimizer.cpp.

References llvm::abs(), and llvm::Offset.

◆ mayCombineMisaligned()

static bool mayCombineMisaligned ( const TargetSubtargetInfo STI,
const MachineInstr MI 
)
static

Return true for loads/stores that can be combined to a double/multi operation without increasing the requirements for alignment.

Definition at line 988 of file ARMLoadStoreOptimizer.cpp.

References llvm::TargetSubtargetInfo::getFrameLowering(), getLoadStoreBaseOp(), getReg(), llvm::TargetFrameLowering::getTransientStackAlign(), isi32Load(), isi32Store(), and MI.

◆ STATISTIC() [1/11]

STATISTIC ( NumLDMGened  ,
"Number of ldm instructions generated"   
)

◆ STATISTIC() [2/11]

STATISTIC ( NumLDRD2LDM  ,
"Number of ldrd instructions turned back into ldm"   
)

◆ STATISTIC() [3/11]

STATISTIC ( NumLDRD2LDR  ,
"Number of ldrd instructions turned back into ldr's"   
)

◆ STATISTIC() [4/11]

STATISTIC ( NumLDRDFormed  ,
"Number of ldrd created before allocation"   
)

◆ STATISTIC() [5/11]

STATISTIC ( NumLdStMoved  ,
"Number of load / store instructions moved"   
)

◆ STATISTIC() [6/11]

STATISTIC ( NumSTMGened  ,
"Number of stm instructions generated"   
)

◆ STATISTIC() [7/11]

STATISTIC ( NumSTRD2STM  ,
"Number of strd instructions turned back into stm"   
)

◆ STATISTIC() [8/11]

STATISTIC ( NumSTRD2STR  ,
"Number of strd instructions turned back into str's"   
)

◆ STATISTIC() [9/11]

STATISTIC ( NumSTRDFormed  ,
"Number of strd created before allocation"   
)

◆ STATISTIC() [10/11]

STATISTIC ( NumVLDMGened  ,
"Number of vldm instructions generated"   
)

◆ STATISTIC() [11/11]

STATISTIC ( NumVSTMGened  ,
"Number of vstm instructions generated"   
)

◆ updateRegisterMapForDbgValueListAfterMove()

static void updateRegisterMapForDbgValueListAfterMove ( SmallDenseMap< Register, SmallVector< MachineInstr * >, 8 > &  RegisterMap,
MachineInstr DbgValueListInstr,
MachineInstr InstrToReplace 
)
static

Definition at line 2511 of file ARMLoadStoreOptimizer.cpp.

References for(), forEachDbgRegOperand(), I, and if().

Variable Documentation

◆ ARM_PREALLOC_LOAD_STORE_OPT_NAME

arm prera ldst ARM_PREALLOC_LOAD_STORE_OPT_NAME

Definition at line 2191 of file ARMLoadStoreOptimizer.cpp.

◆ AssumeMisalignedLoadStores

cl::opt< bool > AssumeMisalignedLoadStores("arm-assume-misaligned-load-store", cl::Hidden, cl::init(false), cl::desc("Be more conservative in ARM load/store opt")) ( "arm-assume-misaligned-load-store"  ,
cl::Hidden  ,
cl::init(false)  ,
cl::desc("Be more conservative in ARM load/store opt")   
)
static

This switch disables formation of double/multi instructions that could potentially lead to (new) alignment traps even with CCR.UNALIGN_TRP disabled.

This can be used to create libraries that are robust even when users provoke undefined behaviour by supplying misaligned pointers.

See also
mayCombineMisaligned()

Referenced by InstReorderLimit().

◆ false

arm prera ldst false

Definition at line 2191 of file ARMLoadStoreOptimizer.cpp.

◆ opt

arm prera ldst opt