LLVM  6.0.0svn
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/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/LivePhysRegs.h"
#include "llvm/CodeGen/MachineBasicBlock.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/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Type.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 "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.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. More...
 
static unsigned getUpdatingLSMultipleOpcode (unsigned Opc, ARM_AM::AMSubMode Mode)
 
static int isIncrementOrDecrement (const MachineInstr &MI, unsigned Reg, ARMCC::CondCodes Pred, unsigned PredReg)
 Check if the given instruction increments or decrements a register and return the amount it is incremented/decremented. More...
 
static MachineBasicBlock::iterator findIncDecBefore (MachineBasicBlock::iterator MBBI, unsigned Reg, ARMCC::CondCodes Pred, unsigned PredReg, int &Offset)
 Searches for an increment or decrement of Reg before MBBI. More...
 
static MachineBasicBlock::iterator findIncDecAfter (MachineBasicBlock::iterator MBBI, unsigned Reg, ARMCC::CondCodes Pred, unsigned PredReg, int &Offset)
 Searches for a increment or decrement of Reg after MBBI. More...
 
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. More...
 
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)
 
 INITIALIZE_PASS (ARMPreAllocLoadStoreOpt, "arm-prera-ldst-opt", ARM_PREALLOC_LOAD_STORE_OPT_NAME, false, false) bool ARMPreAllocLoadStoreOpt
 
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)
 

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. More...
 

Macro Definition Documentation

◆ ARM_LOAD_STORE_OPT_NAME

#define ARM_LOAD_STORE_OPT_NAME   "ARM load / store optimization pass"

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

◆ DEBUG_TYPE

#define DEBUG_TYPE   "arm-ldst-opt"

Definition at line 71 of file ARMLoadStoreOptimizer.cpp.

Function Documentation

◆ ContainsReg()

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

Definition at line 611 of file ARMLoadStoreOptimizer.cpp.

References llvm::ARM_AM::add, llvm::MachineInstrBuilder::add(), llvm::MachineInstrBuilder::addImm(), llvm::MachineInstrBuilder::addReg(), llvm::ARMCC::AL, assert(), llvm::MachineBasicBlock::begin(), llvm::BuildMI(), llvm::MachineBasicBlock::computeRegisterLiveness(), llvm::condCodeOp(), llvm::detail::DenseSetImpl< ValueT, MapTy, ValueInfoT >::count(), llvm::ARM_AM::da, llvm::ARM_AM::db, llvm::RegState::Define, llvm::SmallVectorBase::empty(), llvm::MachineBasicBlock::erase(), first, llvm::MachineInstr::getDebugLoc(), llvm::getDefRegState(), llvm::MachineInstrBuilder::getInstr(), llvm::getInstrPredicate(), llvm::getKillRegState(), getLoadStoreBaseOp(), getLoadStoreMultipleOpcode(), getLoadStoreRegOp(), getMemoryOpOffset(), llvm::MachineInstr::getOpcode(), llvm::MachineInstr::getParent(), llvm::MachineBasicBlock::getParent(), llvm::MachineOperand::getReg(), llvm::ARM_AM::ia, llvm::ARM_AM::ib, llvm::MachineInstr::implicit_operands(), llvm::RegState::ImplicitDefine, llvm::detail::DenseSetImpl< ValueT, MapTy, ValueInfoT >::insert(), llvm::is_contained(), llvm::isARMLowRegister(), llvm::MachineOperand::isDead(), llvm::MachineOperand::isDef(), isi32Load(), isi32Store(), llvm::MachineOperand::isImplicit(), llvm::MachineOperand::isKill(), isLoadSingle(), llvm::MachineOperand::isReg(), llvm::MachineInstr::killsRegister(), llvm::MachineBasicBlock::LQR_Dead, llvm::make_range(), MI, Mode, llvm::predOps(), llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), llvm::SmallVectorTemplateBase< T, isPodLike >::push_back(), llvm::MachineInstr::readsRegister(), Regs, second, llvm::t1CondCodeOp(), TII, and llvm::MachineInstr::uses().

◆ findIncDecAfter()

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

◆ findIncDecBefore()

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

Searches for an increment or decrement of Reg before MBBI.

Definition at line 1190 of file ARMLoadStoreOptimizer.cpp.

References llvm::MachineBasicBlock::begin(), llvm::MachineBasicBlock::end(), and isIncrementOrDecrement().

Referenced by findIncDecAfter(), and getPostIndexedLoadStoreOpcode().

◆ getImmScale()

static unsigned getImmScale ( unsigned  Opc)
static

Definition at line 418 of file ARMLoadStoreOptimizer.cpp.

References llvm_unreachable.

Referenced by getLSMultipleTransferSize().

◆ getLoadStoreBaseOp()

static const MachineOperand& getLoadStoreBaseOp ( const MachineInstr MI)
static

◆ 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

◆ getLSMultipleTransferSize()

static unsigned getLSMultipleTransferSize ( const MachineInstr MI)
static

◆ getMemoryOpOffset()

static int getMemoryOpOffset ( const MachineInstr MI)
static

◆ getPostIndexedLoadStoreOpcode()

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

◆ getPreIndexedLoadStoreOpcode()

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

Definition at line 1312 of file ARMLoadStoreOptimizer.cpp.

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

Referenced by getPostIndexedLoadStoreOpcode().

◆ getUpdatingLSMultipleOpcode()

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

◆ INITIALIZE_PASS() [1/2]

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

Definition at line 199 of file ARMLoadStoreOptimizer.cpp.

◆ INITIALIZE_PASS() [2/2]

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

Definition at line 2034 of file ARMLoadStoreOptimizer.cpp.

References AssumeMisalignedLoadStores, Modified, MRI, and TII.

◆ 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 
)
static

Definition at line 1591 of file ARMLoadStoreOptimizer.cpp.

References llvm::ARM_AM::add, llvm::MachineInstrBuilder::addImm(), llvm::MachineInstrBuilder::addReg(), llvm::ARMCC::AL, Allocator, assert(), llvm::MachineBasicBlock::begin(), llvm::MachineFunction::begin(), llvm::BuildMI(), llvm::MachineInstr::copyImplicitOps(), E, llvm::MachineBasicBlock::empty(), llvm::MachineBasicBlock::end(), llvm::MachineFunction::end(), llvm::MachineBasicBlock::erase(), llvm::MCInstrInfo::get(), llvm::MachineFrameInfo::getCalleeSavedInfo(), llvm::getDeadRegState(), llvm::getDefRegState(), llvm::MachineBasicBlock::getFirstTerminator(), llvm::MachineFunction::getFrameInfo(), llvm::MachineFunction::getFunction(), llvm::MachineFunction::getInfo(), llvm::getInstrPredicate(), llvm::getKillRegState(), llvm::MachineBasicBlock::getLastNonDebugInstr(), getLoadStoreBaseOp(), getMemoryOpOffset(), llvm::MachineInstr::getNumOperands(), llvm::MachineInstr::getOpcode(), llvm::MachineInstr::getOperand(), llvm::MachineBasicBlock::getParent(), llvm::MachineOperand::getReg(), llvm::MachineFunction::getSubtarget(), llvm::ARMSubtarget::getTargetLowering(), llvm::getUndefRegState(), I, llvm::MachineFrameInfo::isCalleeSavedInfoValid(), llvm::MachineOperand::isDead(), llvm::MachineOperand::isKill(), isLoadSingle(), isMemoryOp(), llvm::MachineOperand::isUndef(), llvm::RegState::Kill, llvm_unreachable, MI, Modified, llvm::predOps(), llvm::MachineInstr::setDesc(), llvm::MachineOperand::setReg(), llvm::parallel::sort(), and TII.

◆ isi32Load()

static bool isi32Load ( unsigned  Opc)
static

◆ isi32Store()

static bool isi32Store ( unsigned  Opc)
static

◆ isIncrementOrDecrement()

static int isIncrementOrDecrement ( const MachineInstr MI,
unsigned  Reg,
ARMCC::CondCodes  Pred,
unsigned  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 1160 of file ARMLoadStoreOptimizer.cpp.

References llvm::MachineOperand::getImm(), llvm::getInstrPredicate(), llvm::MachineInstr::getOpcode(), llvm::MachineInstr::getOperand(), and llvm::MachineOperand::getReg().

Referenced by findIncDecAfter(), and findIncDecBefore().

◆ isLoadSingle()

static bool isLoadSingle ( unsigned  Opc)
static

◆ isMemoryOp()

static bool isMemoryOp ( const MachineInstr MI)
static

◆ 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

Definition at line 2056 of file ARMLoadStoreOptimizer.cpp.

References llvm::ARM_AM::add, llvm::MachineInstrBuilder::addImm(), llvm::MachineInstrBuilder::addReg(), llvm::ARMCC::AL, llvm::AMDGPU::HSAMD::Kernel::Arg::Key::Align, assert(), llvm::SmallVectorTemplateCommon< T, typename >::back(), llvm::SmallVectorTemplateCommon< T, typename >::begin(), llvm::MachineBasicBlock::begin(), llvm::BuildMI(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::clear(), llvm::SmallVectorImpl< T >::clear(), llvm::SmallSet< T, N, C >::count(), llvm::SmallPtrSetImpl< PtrType >::count(), llvm::dbgs(), DEBUG, llvm::RegState::Define, E, llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::end(), llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::MachineBasicBlock::end(), llvm::MachineBasicBlock::erase(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::find(), getAlignment(), llvm::ARM_AM::getAM3Opc(), llvm::Function::getContext(), llvm::MachineInstr::getDebugLoc(), llvm::Function::getFunction(), llvm::getInstrPredicate(), llvm::Type::getInt64Ty(), getLoadStoreMultipleOpcode(), getLSMultipleTransferSize(), getMemoryOpOffset(), llvm::MachineInstr::getOpcode(), llvm::MachineInstr::getOperand(), llvm::MachineOperand::getReg(), getReg(), llvm::MachineInstr::hasOneMemOperand(), llvm::ARM_AM::ia, llvm::SmallSet< T, N, C >::insert(), llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::MachineInstr::isCall(), llvm::MachineInstr::isDebugValue(), llvm::MachineOperand::isDef(), isLoadSingle(), isMemoryOp(), llvm::MachineOperand::isReg(), llvm::MachineInstr::isTerminator(), isVolatile(), llvm::MachineInstr::memoperands_begin(), llvm::MachineInstr::mergeMemRefsWith(), MRI, llvm::SmallVectorTemplateBase< T, isPodLike >::pop_back(), llvm::SmallVectorTemplateBase< T, isPodLike >::push_back(), llvm::ARMRI::RegPairEven, llvm::ARMRI::RegPairOdd, llvm::TargetRegisterInfo::regsOverlap(), llvm::MachineInstrBuilder::setMemRefs(), llvm::SmallSet< T, N, C >::size(), llvm::DenseMapBase< DenseMap< KeyT, ValueT, KeyInfoT, BucketT >, KeyT, ValueT, KeyInfoT, BucketT >::size(), llvm::SmallVectorTemplateCommon< T, typename >::size(), llvm::parallel::sort(), llvm::MachineBasicBlock::splice(), llvm::ARM_AM::sub, and TII.

◆ isT1i32Load()

static bool isT1i32Load ( unsigned  Opc)
static

Definition at line 390 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Load().

◆ isT1i32Store()

static bool isT1i32Store ( unsigned  Opc)
static

Definition at line 402 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Store().

◆ isT2i32Load()

static bool isT2i32Load ( unsigned  Opc)
static

Definition at line 394 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Load().

◆ isT2i32Store()

static bool isT2i32Store ( unsigned  Opc)
static

Definition at line 406 of file ARMLoadStoreOptimizer.cpp.

Referenced by isi32Store().

◆ isValidLSDoubleOffset()

static bool isValidLSDoubleOffset ( int  Offset)
static

Definition at line 962 of file ARMLoadStoreOptimizer.cpp.

References llvm::abs().

Referenced by mayCombineMisaligned().

◆ mayCombineMisaligned()

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

◆ STATISTIC() [1/11]

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

◆ STATISTIC() [2/11]

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

◆ STATISTIC() [3/11]

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

◆ STATISTIC() [4/11]

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

◆ STATISTIC() [5/11]

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

◆ STATISTIC() [6/11]

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

◆ STATISTIC() [7/11]

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

◆ STATISTIC() [8/11]

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

◆ STATISTIC() [9/11]

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

◆ STATISTIC() [10/11]

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

◆ STATISTIC() [11/11]

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

Variable Documentation

◆ 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"))
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 INITIALIZE_PASS(), and mayCombineMisaligned().