LLVM 22.0.0git
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/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 <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 (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 95 of file ARMLoadStoreOptimizer.cpp.

Referenced by INITIALIZE_PASS().

◆ ARM_PREALLOC_LOAD_STORE_OPT_NAME

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

Definition at line 2132 of file ARMLoadStoreOptimizer.cpp.

Referenced by INITIALIZE_PASS_BEGIN().

◆ DEBUG_TYPE

#define DEBUG_TYPE   "arm-ldst-opt"

Definition at line 72 of file ARMLoadStoreOptimizer.cpp.

Function Documentation

◆ AdjustBaseAndOffset()

◆ ContainsReg()

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

Definition at line 614 of file ARMLoadStoreOptimizer.cpp.

References Reg.

◆ createDebugVariableFromMachineInstr()

DebugVariable createDebugVariableFromMachineInstr ( MachineInstr * MI)
static

Definition at line 2521 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ createPostIncLoadStore()

◆ findIncDecAfter()

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 1240 of file ARMLoadStoreOptimizer.cpp.

References isIncrementOrDecrement(), MBB, MBBI, llvm::Offset, Reg, and TRI.

◆ findIncDecBefore()

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 1220 of file ARMLoadStoreOptimizer.cpp.

References isIncrementOrDecrement(), MBB, MBBI, llvm::Offset, and Reg.

◆ forEachDbgRegOperand()

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

Definition at line 2491 of file ARMLoadStoreOptimizer.cpp.

References I, and MI.

Referenced by updateRegisterMapForDbgValueListAfterMove().

◆ getBaseOperandIndex()

int getBaseOperandIndex ( MachineInstr & MI)
static

Definition at line 2873 of file ARMLoadStoreOptimizer.cpp.

References MI.

Referenced by AdjustBaseAndOffset().

◆ getImmScale()

unsigned getImmScale ( unsigned Opc)
static

Definition at line 420 of file ARMLoadStoreOptimizer.cpp.

References llvm_unreachable, and Opc.

◆ getLoadStoreBaseOp()

const MachineOperand & getLoadStoreBaseOp ( const MachineInstr & MI)
static

Definition at line 245 of file ARMLoadStoreOptimizer.cpp.

References MI.

Referenced by mayCombineMisaligned().

◆ getLoadStoreMultipleOpcode()

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

◆ getLoadStoreMultipleSubMode()

ARM_AM::AMSubMode getLoadStoreMultipleSubMode ( unsigned Opcode)
static

◆ getLoadStoreRegOp()

const MachineOperand & getLoadStoreRegOp ( const MachineInstr & MI)
static

Definition at line 249 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ getLSMultipleTransferSize()

unsigned getLSMultipleTransferSize ( const MachineInstr * MI)
static

Definition at line 437 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ getMemoryOpOffset()

◆ getPostIndexedLoadStoreOpcode()

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

Definition at line 1389 of file ARMLoadStoreOptimizer.cpp.

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

Referenced by createPostIncLoadStore().

◆ getPreIndexedLoadStoreOpcode()

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

Definition at line 1364 of file ARMLoadStoreOptimizer.cpp.

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

◆ getUpdatingLSMultipleOpcode()

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 201 of file ARMLoadStoreOptimizer.cpp.

References ARM_LOAD_STORE_OPT_NAME, const, and MI.

◆ INITIALIZE_PASS_BEGIN()

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

◆ InsertLDR_STR()

◆ InstReorderLimit()

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

◆ isi32Load()

bool isi32Load ( unsigned Opc)
static

Definition at line 400 of file ARMLoadStoreOptimizer.cpp.

References isT1i32Load(), isT2i32Load(), and Opc.

Referenced by isLoadSingle(), and mayCombineMisaligned().

◆ isi32Store()

bool isi32Store ( unsigned Opc)
static

Definition at line 412 of file ARMLoadStoreOptimizer.cpp.

References isT1i32Store(), isT2i32Store(), and Opc.

Referenced by mayCombineMisaligned().

◆ isIncrementOrDecrement()

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 1188 of file ARMLoadStoreOptimizer.cpp.

References llvm::getInstrPredicate(), MI, and Reg.

Referenced by findIncDecAfter(), and findIncDecBefore().

◆ isLegalOrConvertableAddressImm()

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

◆ isLoadSingle()

bool isLoadSingle ( unsigned Opc)
static

Definition at line 416 of file ARMLoadStoreOptimizer.cpp.

References isi32Load(), and Opc.

◆ isMemoryOp()

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 1675 of file ARMLoadStoreOptimizer.cpp.

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

◆ isPostIndex()

bool isPostIndex ( MachineInstr & MI)
static

Definition at line 2938 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ isPreIndex()

bool isPreIndex ( MachineInstr & MI)
static

Definition at line 2960 of file ARMLoadStoreOptimizer.cpp.

References MI.

◆ IsSafeAndProfitableToMove()

◆ isT1i32Load()

bool isT1i32Load ( unsigned Opc)
static

Definition at line 392 of file ARMLoadStoreOptimizer.cpp.

References Opc.

Referenced by isi32Load().

◆ isT1i32Store()

bool isT1i32Store ( unsigned Opc)
static

Definition at line 404 of file ARMLoadStoreOptimizer.cpp.

References Opc.

Referenced by isi32Store().

◆ isT2i32Load()

bool isT2i32Load ( unsigned Opc)
static

Definition at line 396 of file ARMLoadStoreOptimizer.cpp.

References Opc.

Referenced by isi32Load().

◆ isT2i32Store()

bool isT2i32Store ( unsigned Opc)
static

Definition at line 408 of file ARMLoadStoreOptimizer.cpp.

References Opc.

Referenced by isi32Store().

◆ isValidLSDoubleOffset()

bool isValidLSDoubleOffset ( int Offset)
static

Definition at line 976 of file ARMLoadStoreOptimizer.cpp.

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

◆ mayCombineMisaligned()

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 985 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()

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

Definition at line 2508 of file ARMLoadStoreOptimizer.cpp.

References forEachDbgRegOperand(), and llvm::replace().

Variable Documentation

◆ ARM_PREALLOC_LOAD_STORE_OPT_NAME

arm prera ldst ARM_PREALLOC_LOAD_STORE_OPT_NAME

Definition at line 2188 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 2188 of file ARMLoadStoreOptimizer.cpp.

◆ opt

arm prera ldst opt

Definition at line 2187 of file ARMLoadStoreOptimizer.cpp.