LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros | Functions | Variables
AArch64ISelLowering.cpp File Reference
#include "AArch64.h"
#include "AArch64ISelLowering.h"
#include "AArch64MachineFunctionInfo.h"
#include "AArch64TargetMachine.h"
#include "AArch64TargetObjectFile.h"
#include "Utils/AArch64BaseInfo.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/CallingConv.h"
#include "AArch64GenCallingConv.inc"
Include dependency graph for AArch64ISelLowering.cpp:

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "aarch64-isel"
 

Functions

static TargetLoweringObjectFilecreateTLOF (AArch64TargetMachine &TM)
 
static void getExclusiveOperation (unsigned Size, AtomicOrdering Ord, unsigned &LdrOpc, unsigned &StrOpc)
 
static bool CC_AArch64NoMoreRegs (unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
 
static A64CC::CondCodes IntCCToA64CC (ISD::CondCode CC)
 
static A64CC::CondCodes FPCCToA64CC (ISD::CondCode CC, A64CC::CondCodes &Alternative)
 
static SDValue LowerVectorSETCC (SDValue Op, SelectionDAG &DAG)
 
static bool isNeonModifiedImm (uint64_t SplatBits, uint64_t SplatUndef, unsigned SplatBitSize, SelectionDAG &DAG, bool is128Bits, NeonModImmType type, EVT &VT, unsigned &Imm, unsigned &OpCmode)
 
static SDValue PerformANDCombine (SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
 
static int32_t getLSBForBFI (SelectionDAG &DAG, SDLoc DL, EVT VT, SDValue &MaskedVal, uint64_t Mask)
 
static bool findMaskedBFI (SDValue N, SDValue &BFI, uint64_t &Mask, bool &Extended)
 
static SDValue tryCombineToBFI (SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget)
 
static SDValue tryCombineToLargerBFI (SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget)
 
static bool findEXTRHalf (SDValue N, SDValue &Src, uint32_t &ShiftAmount, bool &FromHi)
 
static SDValue tryCombineToEXTR (SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
 
static SDValue PerformORCombine (SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget)
 Target-specific dag combine xforms for ISD::OR. More...
 
static SDValue PerformSRACombine (SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
 Target-specific dag combine xforms for ISD::SRA. More...
 
static bool getVShiftImm (SDValue Op, unsigned ElementBits, int64_t &Cnt)
 
static bool isVShiftLImm (SDValue Op, EVT VT, int64_t &Cnt)
 
static bool isVShiftRImm (SDValue Op, EVT VT, int64_t &Cnt)
 
static SDValue PerformShiftCombine (SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *ST)
 Checks for immediate versions of vector shifts and lowers them. More...
 
static SDValue PerformIntrinsicCombine (SDNode *N, SelectionDAG &DAG)
 ARM-specific DAG combining for intrinsics. More...
 
static SDValue CombineBaseUpdate (SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
 
static SDValue CombineVLDDUP (SDNode *N, TargetLowering::DAGCombinerInfo &DCI)
 
static bool isREVMask (ArrayRef< int > M, EVT VT, unsigned BlockSize)
 
static unsigned isPermuteMask (ArrayRef< int > M, EVT VT)
 

Variables

static const uint16_t AArch64FPRArgRegs []
 
static const unsigned NumFPRArgRegs = llvm::array_lengthof(AArch64FPRArgRegs)
 
static const uint16_t AArch64ArgRegs []
 
static const unsigned NumArgRegs = llvm::array_lengthof(AArch64ArgRegs)
 

Macro Definition Documentation

#define DEBUG_TYPE   "aarch64-isel"

Definition at line 15 of file AArch64ISelLowering.cpp.

Function Documentation

static bool CC_AArch64NoMoreRegs ( unsigned  ValNo,
MVT  ValVT,
MVT  LocVT,
CCValAssign::LocInfo  LocInfo,
ISD::ArgFlagsTy  ArgFlags,
CCState State 
)
static
static SDValue CombineBaseUpdate ( SDNode N,
TargetLowering::DAGCombinerInfo DCI 
)
static

Target-specific DAG combine function for NEON load/store intrinsics to merge base address updates.

Definition at line 3551 of file AArch64ISelLowering.cpp.

References llvm::Intrinsic::aarch64_neon_vld1x2, llvm::Intrinsic::aarch64_neon_vld1x3, llvm::Intrinsic::aarch64_neon_vld1x4, llvm::Intrinsic::aarch64_neon_vst1x2, llvm::Intrinsic::aarch64_neon_vst1x3, llvm::Intrinsic::aarch64_neon_vst1x4, llvm::ISD::ADD, llvm::Intrinsic::arm_neon_vld1, llvm::Intrinsic::arm_neon_vld2, llvm::Intrinsic::arm_neon_vld2lane, llvm::Intrinsic::arm_neon_vld3, llvm::Intrinsic::arm_neon_vld3lane, llvm::Intrinsic::arm_neon_vld4, llvm::Intrinsic::arm_neon_vld4lane, llvm::Intrinsic::arm_neon_vst1, llvm::Intrinsic::arm_neon_vst2, llvm::Intrinsic::arm_neon_vst2lane, llvm::Intrinsic::arm_neon_vst3, llvm::Intrinsic::arm_neon_vst3lane, llvm::Intrinsic::arm_neon_vst4, llvm::Intrinsic::arm_neon_vst4lane, llvm::TargetLowering::DAGCombinerInfo::CombineTo(), llvm::TargetLowering::DAGCombinerInfo::DAG, llvm::SmallVectorTemplateCommon< T >::data(), llvm::SelectionDAG::getMemIntrinsicNode(), llvm::MemSDNode::getMemOperand(), llvm::MemSDNode::getMemoryVT(), llvm::SDValue::getNode(), llvm::SDNode::getNumOperands(), llvm::SDNode::getOpcode(), llvm::SDNode::getOperand(), llvm::SDValue::getResNo(), llvm::EVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), llvm::SDValue::getValueType(), llvm::SDNode::getValueType(), llvm::EVT::getVectorNumElements(), llvm::SelectionDAG::getVTList(), llvm::MVT::i32, llvm::MVT::i64, llvm::ISD::INTRINSIC_VOID, llvm::ISD::INTRINSIC_W_CHAIN, llvm::TargetLowering::DAGCombinerInfo::isBeforeLegalize(), llvm::TargetLowering::DAGCombinerInfo::isCalledByLegalizer(), llvm::SDNode::isPredecessorOf(), llvm_unreachable, N, llvm::AArch64ISD::NEON_LD1_UPD, llvm::AArch64ISD::NEON_LD1x2_UPD, llvm::AArch64ISD::NEON_LD1x3_UPD, llvm::AArch64ISD::NEON_LD1x4_UPD, llvm::AArch64ISD::NEON_LD2_UPD, llvm::AArch64ISD::NEON_LD2DUP, llvm::AArch64ISD::NEON_LD2DUP_UPD, llvm::AArch64ISD::NEON_LD2LN_UPD, llvm::AArch64ISD::NEON_LD3_UPD, llvm::AArch64ISD::NEON_LD3DUP, llvm::AArch64ISD::NEON_LD3DUP_UPD, llvm::AArch64ISD::NEON_LD3LN_UPD, llvm::AArch64ISD::NEON_LD4_UPD, llvm::AArch64ISD::NEON_LD4DUP, llvm::AArch64ISD::NEON_LD4DUP_UPD, llvm::AArch64ISD::NEON_LD4LN_UPD, llvm::AArch64ISD::NEON_ST1_UPD, llvm::AArch64ISD::NEON_ST1x2_UPD, llvm::AArch64ISD::NEON_ST1x3_UPD, llvm::AArch64ISD::NEON_ST1x4_UPD, llvm::AArch64ISD::NEON_ST2_UPD, llvm::AArch64ISD::NEON_ST2LN_UPD, llvm::AArch64ISD::NEON_ST3_UPD, llvm::AArch64ISD::NEON_ST3LN_UPD, llvm::AArch64ISD::NEON_ST4_UPD, llvm::AArch64ISD::NEON_ST4LN_UPD, llvm::MVT::Other, llvm::SmallVectorTemplateBase< T, isPodLike< T >::value >::push_back(), llvm::SmallVectorTemplateCommon< T >::size(), llvm::SDNode::use_begin(), and llvm::SDNode::use_end().

Referenced by llvm::AArch64TargetLowering::PerformDAGCombine().

static SDValue CombineVLDDUP ( SDNode N,
TargetLowering::DAGCombinerInfo DCI 
)
static
static TargetLoweringObjectFile* createTLOF ( AArch64TargetMachine TM)
static
static bool findEXTRHalf ( SDValue  N,
SDValue Src,
uint32_t &  ShiftAmount,
bool FromHi 
)
static

An EXTR instruction is made up of two shifts, ORed together. This helper searches for and classifies those shifts.

Definition at line 3271 of file AArch64ISelLowering.cpp.

References llvm::SDNode::getConstantOperandVal(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::SDNode::getOperand(), llvm::ISD::SHL, and llvm::ISD::SRL.

Referenced by tryCombineToEXTR().

static bool findMaskedBFI ( SDValue  N,
SDValue BFI,
uint64_t &  Mask,
bool Extended 
)
static

Searches from N for an existing AArch64ISD::BFI node, possibly surrounded by a mask and an extension. Returns true if a BFI was found and provides information on its surroundings.

Definition at line 3101 of file AArch64ISelLowering.cpp.

References llvm::ISD::AND, llvm::AArch64ISD::BFI, llvm::SDNode::getConstantOperandVal(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::EVT::getSizeInBits(), llvm::SDValue::getValueType(), N, and llvm::ISD::ZERO_EXTEND.

Referenced by tryCombineToLargerBFI().

static A64CC::CondCodes FPCCToA64CC ( ISD::CondCode  CC,
A64CC::CondCodes Alternative 
)
static
static void getExclusiveOperation ( unsigned  Size,
AtomicOrdering  Ord,
unsigned LdrOpc,
unsigned StrOpc 
)
static
static int32_t getLSBForBFI ( SelectionDAG DAG,
SDLoc  DL,
EVT  VT,
SDValue MaskedVal,
uint64_t  Mask 
)
static

For a true bitfield insert, the bits getting into that contiguous mask should come from the low part of an existing value: they must be formed from a compatible SHL operation (unless they're already low). This function checks that condition and returns the least-significant bit that's intended. If the operation not a field preparation, -1 is returned.

Definition at line 3057 of file AArch64ISelLowering.cpp.

References llvm::countTrailingZeros(), llvm::SelectionDAG::getConstant(), llvm::SDValue::getConstantOperandVal(), llvm::SelectionDAG::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::MVT::i64, llvm::isShiftedMask_64(), llvm::ISD::SHL, and llvm::ISD::SRL.

Referenced by tryCombineToBFI().

static bool getVShiftImm ( SDValue  Op,
unsigned  ElementBits,
int64_t &  Cnt 
)
static

Check if this is a valid build_vector for the immediate operand of a vector shift operation, where all the elements of the build_vector must have the same constant integer value.

Definition at line 3442 of file AArch64ISelLowering.cpp.

References llvm::ISD::BITCAST, llvm::dyn_cast(), llvm::SDValue::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::APInt::getSExtValue(), and llvm::BuildVectorSDNode::isConstantSplat().

Referenced by isVShiftLImm(), and isVShiftRImm().

static A64CC::CondCodes IntCCToA64CC ( ISD::CondCode  CC)
static
static bool isNeonModifiedImm ( uint64_t  SplatBits,
uint64_t  SplatUndef,
unsigned  SplatBitSize,
SelectionDAG DAG,
bool  is128Bits,
NeonModImmType  type,
EVT VT,
unsigned Imm,
unsigned OpCmode 
)
static

Check if the specified splat value corresponds to a valid vector constant for a Neon instruction with a "modified immediate" operand (e.g., MOVI). If so, return the encoded 8-bit immediate and the OpCmode instruction fields values.

Definition at line 2877 of file AArch64ISelLowering.cpp.

References llvm::X86II::ImmMask, llvm_unreachable, llvm::Neon_Mov_Imm, llvm::MVT::v16i8, llvm::MVT::v1i64, llvm::MVT::v2i32, llvm::MVT::v2i64, llvm::MVT::v4i16, llvm::MVT::v4i32, llvm::MVT::v8i16, and llvm::MVT::v8i8.

Referenced by llvm::AArch64TargetLowering::LowerBUILD_VECTOR().

static unsigned isPermuteMask ( ArrayRef< int >  M,
EVT  VT 
)
static
static bool isREVMask ( ArrayRef< int >  M,
EVT  VT,
unsigned  BlockSize 
)
static

isREVMask - Check if a vector shuffle corresponds to a REV instruction with the specified blocksize. (The order of the elements within each block of the vector is reversed.)

Definition at line 4076 of file AArch64ISelLowering.cpp.

References llvm::EVT::getSizeInBits(), llvm::EVT::getVectorElementType(), and llvm::EVT::getVectorNumElements().

Referenced by llvm::AArch64TargetLowering::LowerVECTOR_SHUFFLE().

static bool isVShiftLImm ( SDValue  Op,
EVT  VT,
int64_t &  Cnt 
)
static

Check if this is a valid build_vector for the immediate operand of a vector shift left operation. That value must be in the range: 0 <= Value < ElementBits

Definition at line 3461 of file AArch64ISelLowering.cpp.

References llvm::EVT::getSizeInBits(), llvm::EVT::getVectorElementType(), getVShiftImm(), and llvm::EVT::isVector().

Referenced by PerformIntrinsicCombine(), and PerformShiftCombine().

static bool isVShiftRImm ( SDValue  Op,
EVT  VT,
int64_t &  Cnt 
)
static

Check if this is a valid build_vector for the immediate operand of a vector shift right operation. The value must be in the range: 1 <= Value <= ElementBits

Definition at line 3472 of file AArch64ISelLowering.cpp.

References llvm::EVT::getSizeInBits(), llvm::EVT::getVectorElementType(), getVShiftImm(), and llvm::EVT::isVector().

Referenced by PerformShiftCombine().

static SDValue LowerVectorSETCC ( SDValue  Op,
SelectionDAG DAG 
)
static
static SDValue PerformANDCombine ( SDNode N,
TargetLowering::DAGCombinerInfo DCI 
)
static
static SDValue PerformIntrinsicCombine ( SDNode N,
SelectionDAG DAG 
)
static
static SDValue PerformORCombine ( SDNode N,
TargetLowering::DAGCombinerInfo DCI,
const AArch64Subtarget Subtarget 
)
static
static SDValue PerformShiftCombine ( SDNode N,
TargetLowering::DAGCombinerInfo DCI,
const AArch64Subtarget ST 
)
static
static SDValue PerformSRACombine ( SDNode N,
TargetLowering::DAGCombinerInfo DCI 
)
static
static SDValue tryCombineToBFI ( SDNode N,
TargetLowering::DAGCombinerInfo DCI,
const AArch64Subtarget Subtarget 
)
static

Try to combine a subtree (rooted at an OR) into a "masked BFI" node, which is roughly equivalent to (and (BFI ...), mask). This form is used because it can often be further combined with a larger mask. Ultimately, we want mask to be 2^32-1 or 2^64-1 so the AND can be skipped.

Definition at line 3129 of file AArch64ISelLowering.cpp.

References llvm::ISD::AND, llvm::AArch64ISD::BFI, llvm::CountPopulation_64(), llvm::TargetLowering::DAGCombinerInfo::DAG, llvm::SelectionDAG::getConstant(), llvm::SDNode::getConstantOperandVal(), getLSBForBFI(), llvm::SelectionDAG::getNode(), llvm::SDValue::getOpcode(), llvm::SDNode::getOpcode(), llvm::SDValue::getOperand(), llvm::SDNode::getOperand(), llvm::EVT::getSizeInBits(), llvm::SDNode::getValueType(), llvm::MVT::i64, llvm::ISD::OR, and std::swap().

Referenced by PerformORCombine().

static SDValue tryCombineToEXTR ( SDNode N,
TargetLowering::DAGCombinerInfo DCI 
)
static

EXTR instruction extracts a contiguous chunk of bits from two existing registers viewed as a high/low pair. This function looks for the pattern: (or (shl VAL1, N), (srl VAL2, #RegWidth-N)) and replaces it with an EXTR. Can't quite be done in TableGen because the two immediates aren't independent.

Definition at line 3293 of file AArch64ISelLowering.cpp.

References llvm::TargetLowering::DAGCombinerInfo::DAG, llvm::AArch64ISD::EXTR, findEXTRHalf(), llvm::SelectionDAG::getConstant(), llvm::SelectionDAG::getNode(), llvm::SDNode::getOpcode(), llvm::SDNode::getOperand(), llvm::EVT::getSizeInBits(), llvm::SDNode::getValueType(), llvm::MVT::i32, llvm::MVT::i64, llvm::ISD::OR, and std::swap().

Referenced by PerformORCombine().

static SDValue tryCombineToLargerBFI ( SDNode N,
TargetLowering::DAGCombinerInfo DCI,
const AArch64Subtarget Subtarget 
)
static

Search for the bitwise combining (with careful masks) of a MaskedBFI and its original input. This is surprisingly common because SROA splits things up into i8 chunks, so the originally detected MaskedBFI may actually only act on the low (say) byte of a word. This is then orred into the rest of the word afterwards.

Basic input: (or (and OLDFIELD, MASK1), (MaskedBFI MASK2, OLDFIELD, ...)).

If MASK1 and MASK2 are compatible, we can fold the whole thing into the MaskedBFI. We can also deal with a certain amount of extend/truncate being involved.

Definition at line 3210 of file AArch64ISelLowering.cpp.

References llvm::ISD::AND, llvm::ISD::ANY_EXTEND, llvm::AArch64ISD::BFI, llvm::TargetLowering::DAGCombinerInfo::DAG, findMaskedBFI(), llvm::SelectionDAG::getConstant(), llvm::SDNode::getConstantOperandVal(), llvm::SelectionDAG::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::SDNode::getOperand(), llvm::EVT::getSizeInBits(), llvm::SDValue::getValueType(), llvm::SDNode::getValueType(), llvm::MVT::i32, and llvm::MVT::i64.

Referenced by PerformORCombine().

Variable Documentation

const uint16_t AArch64ArgRegs[]
static
Initial value:
= {
AArch64::X0, AArch64::X1, AArch64::X2, AArch64::X3,
AArch64::X4, AArch64::X5, AArch64::X6, AArch64::X7
}

Definition at line 1001 of file AArch64ISelLowering.cpp.

Referenced by CC_AArch64NoMoreRegs(), and llvm::AArch64TargetLowering::SaveVarArgRegisters().

const uint16_t AArch64FPRArgRegs[]
static
Initial value:
= {
AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3,
AArch64::Q4, AArch64::Q5, AArch64::Q6, AArch64::Q7
}

Definition at line 995 of file AArch64ISelLowering.cpp.

Referenced by llvm::AArch64TargetLowering::SaveVarArgRegisters().

const unsigned NumArgRegs = llvm::array_lengthof(AArch64ArgRegs)
static
const unsigned NumFPRArgRegs = llvm::array_lengthof(AArch64FPRArgRegs)
static