LLVM  6.0.0svn
Macros | Functions
AArch64ISelDAGToDAG.cpp File Reference
#include "AArch64TargetMachine.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "AArch64GenDAGISel.inc"
Include dependency graph for AArch64ISelDAGToDAG.cpp:

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "aarch64-isel"
 

Functions

static bool isIntImmediate (const SDNode *N, uint64_t &Imm)
 isIntImmediate - This method tests to see if the node is a constant operand. More...
 
static bool isIntImmediate (SDValue N, uint64_t &Imm)
 
static bool isOpcWithIntImmediate (const SDNode *N, unsigned Opc, uint64_t &Imm)
 
static AArch64_AM::ShiftExtendType getShiftTypeForNode (SDValue N)
 getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value. More...
 
static bool isWorthFoldingSHL (SDValue V)
 Determine whether it is worth it to fold SHL into the addressing mode. More...
 
static AArch64_AM::ShiftExtendType getExtendTypeForNode (SDValue N, bool IsLoadStore=false)
 getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value. More...
 
static bool checkHighLaneIndex (SDNode *DL, SDValue &LaneOp, int &LaneIdx)
 
static bool checkV64LaneV128 (SDValue Op0, SDValue Op1, SDValue &StdOp, SDValue &LaneOp, int &LaneIdx)
 
static SDValue narrowIfNeeded (SelectionDAG *CurDAG, SDValue N)
 Instructions that accept extend modifiers like UXTW expect the register being extended to be a GPR32, but the incoming DAG might be acting on a GPR64 (either via SEXT_INREG or AND). More...
 
static bool isWorthFoldingADDlow (SDValue N)
 If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD instruction from it anyway and there's no point in folding it into the mem op. More...
 
static SDValue Widen (SelectionDAG *CurDAG, SDValue N)
 
static bool isPreferredADD (int64_t ImmOff)
 
static SDValue NarrowVector (SDValue V128Reg, SelectionDAG &DAG)
 NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 register class. More...
 
static bool isBitfieldExtractOpFromAnd (SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB, unsigned NumberOfIgnoredLowBits, bool BiggerPattern)
 
static bool isBitfieldExtractOpFromSExtInReg (SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms)
 
static bool isSeveralBitsExtractOpFromShr (SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &LSB, unsigned &MSB)
 
static bool isBitfieldExtractOpFromShr (SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, bool BiggerPattern)
 
static bool isBitfieldExtractOp (SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, SDValue &Opd0, unsigned &Immr, unsigned &Imms, unsigned NumberOfIgnoredLowBits=0, bool BiggerPattern=false)
 
static bool isBitfieldDstMask (uint64_t DstMask, const APInt &BitsToBeInserted, unsigned NumberOfIgnoredHighBits, EVT VT)
 Does DstMask form a complementary pair with the mask provided by BitsToBeInserted, suitable for use in a BFI instruction. More...
 
static void getUsefulBits (SDValue Op, APInt &UsefulBits, unsigned Depth=0)
 
static void getUsefulBitsFromAndWithImmediate (SDValue Op, APInt &UsefulBits, unsigned Depth)
 
static void getUsefulBitsFromBitfieldMoveOpd (SDValue Op, APInt &UsefulBits, uint64_t Imm, uint64_t MSB, unsigned Depth)
 
static void getUsefulBitsFromUBFM (SDValue Op, APInt &UsefulBits, unsigned Depth)
 
static void getUsefulBitsFromOrWithShiftedReg (SDValue Op, APInt &UsefulBits, unsigned Depth)
 
static void getUsefulBitsFromBFM (SDValue Op, SDValue Orig, APInt &UsefulBits, unsigned Depth)
 
static void getUsefulBitsForUse (SDNode *UserNode, APInt &UsefulBits, SDValue Orig, unsigned Depth)
 
static SDValue getLeftShift (SelectionDAG *CurDAG, SDValue Op, int ShlAmount)
 Create a machine node performing a notional SHL of Op by ShlAmount. More...
 
static bool isBitfieldPositioningOp (SelectionDAG *CurDAG, SDValue Op, bool BiggerPattern, SDValue &Src, int &ShiftAmount, int &MaskWidth)
 Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL, N), Mask)". More...
 
static bool isShiftedMask (uint64_t Mask, EVT VT)
 
static bool tryBitfieldInsertOpFromOrAndImm (SDNode *N, SelectionDAG *CurDAG)
 
static bool tryBitfieldInsertOpFromOr (SDNode *N, const APInt &UsefulBits, SelectionDAG *CurDAG)
 
static int getIntOperandFromRegisterString (StringRef RegString)
 

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "aarch64-isel"

Definition at line 29 of file AArch64ISelDAGToDAG.cpp.

Function Documentation

◆ checkHighLaneIndex()

static bool checkHighLaneIndex ( SDNode DL,
SDValue LaneOp,
int &  LaneIdx 
)
static

◆ checkV64LaneV128()

static bool checkV64LaneV128 ( SDValue  Op0,
SDValue  Op1,
SDValue StdOp,
SDValue LaneOp,
int &  LaneIdx 
)
static

◆ getExtendTypeForNode()

static AArch64_AM::ShiftExtendType getExtendTypeForNode ( SDValue  N,
bool  IsLoadStore = false 
)
static

◆ getIntOperandFromRegisterString()

static int getIntOperandFromRegisterString ( StringRef  RegString)
static

Definition at line 2487 of file AArch64ISelDAGToDAG.cpp.

References llvm::ISD::ADD, llvm::ISD::AND, assert(), llvm::ISD::ATOMIC_CMP_SWAP, llvm::ISD::Constant, llvm::dbgs(), DEBUG, llvm::SDNode::dump(), llvm::SDNode::dumpr(), llvm::dyn_cast(), llvm::AArch64SysReg::SysReg::Encoding, llvm::errs(), llvm::ISD::EXTRACT_VECTOR_ELT, llvm::tgtok::Field, llvm::ISD::FrameIndex, llvm::MDNodeSDNode::getMD(), llvm::SDValue::getNode(), llvm::SDNode::getNumOperands(), llvm::SDNode::getOpcode(), llvm::SDNode::getOperand(), llvm::MDNode::getOperand(), llvm::TargetLoweringBase::getPointerTy(), llvm::AArch64_AM::getShifterImm(), llvm::SDNode::getSimpleValueType(), llvm::EVT::getSizeInBits(), llvm::SDValue::getValueType(), llvm::SDNode::getValueType(), llvm::EVT::getVectorElementType(), llvm::ConstantSDNode::getZExtValue(), llvm::MVT::i16, llvm::MVT::i32, llvm::MVT::i64, llvm::MVT::i8, llvm::ISD::INTRINSIC_VOID, llvm::ISD::INTRINSIC_W_CHAIN, llvm::ISD::INTRINSIC_WO_CHAIN, llvm::SDNode::isMachineOpcode(), llvm::ConstantSDNode::isNullValue(), llvm::AArch64ISD::LD1DUPpost, llvm::AArch64ISD::LD1LANEpost, llvm::AArch64ISD::LD1x2post, llvm::AArch64ISD::LD1x3post, llvm::AArch64ISD::LD1x4post, llvm::AArch64ISD::LD2DUPpost, llvm::AArch64ISD::LD2LANEpost, llvm::AArch64ISD::LD2post, llvm::AArch64ISD::LD3DUPpost, llvm::AArch64ISD::LD3LANEpost, llvm::AArch64ISD::LD3post, llvm::AArch64ISD::LD4DUPpost, llvm::AArch64ISD::LD4LANEpost, llvm::AArch64ISD::LD4post, llvm_unreachable, llvm::ISD::LOAD, llvm::AArch64SysReg::lookupSysRegByName(), llvm::AArch64_AM::LSL, N, llvm::ISD::OR, llvm::MVT::Other, llvm::AArch64SysReg::parseGenericRegister(), llvm::ISD::READ_REGISTER, llvm::MCID::Select, llvm::SDNode::setNodeId(), llvm::ISD::SIGN_EXTEND, llvm::ISD::SIGN_EXTEND_INREG, llvm::SmallVectorTemplateCommon< T >::size(), llvm::StringRef::split(), llvm::ISD::SRA, llvm::ISD::SRL, llvm::AArch64ISD::ST1x2post, llvm::AArch64ISD::ST1x3post, llvm::AArch64ISD::ST1x4post, llvm::AArch64ISD::ST2LANEpost, llvm::AArch64ISD::ST2post, llvm::AArch64ISD::ST3LANEpost, llvm::AArch64ISD::ST3post, llvm::AArch64ISD::ST4LANEpost, llvm::AArch64ISD::ST4post, SubReg, llvm::MVT::v16i8, llvm::MVT::v1f64, llvm::MVT::v1i64, llvm::MVT::v2f32, llvm::MVT::v2f64, llvm::MVT::v2i32, llvm::MVT::v2i64, llvm::MVT::v4f16, llvm::MVT::v4f32, llvm::MVT::v4i16, llvm::MVT::v4i32, llvm::MVT::v8f16, llvm::MVT::v8i16, llvm::MVT::v8i8, and llvm::ISD::WRITE_REGISTER.

◆ getLeftShift()

static SDValue getLeftShift ( SelectionDAG CurDAG,
SDValue  Op,
int  ShlAmount 
)
static

Create a machine node performing a notional SHL of Op by ShlAmount.

If ShlAmount is negative, do a (logical) right-shift instead. If ShlAmount is 0, return Op unchanged.

Definition at line 2050 of file AArch64ISelDAGToDAG.cpp.

References assert(), llvm::SelectionDAG::getMachineNode(), llvm::EVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), and llvm::SDValue::getValueType().

Referenced by isBitfieldPositioningOp().

◆ getShiftTypeForNode()

static AArch64_AM::ShiftExtendType getShiftTypeForNode ( SDValue  N)
static

◆ getUsefulBits()

static void getUsefulBits ( SDValue  Op,
APInt UsefulBits,
unsigned  Depth = 0 
)
static

◆ getUsefulBitsForUse()

static void getUsefulBitsForUse ( SDNode UserNode,
APInt UsefulBits,
SDValue  Orig,
unsigned  Depth 
)
static

◆ getUsefulBitsFromAndWithImmediate()

static void getUsefulBitsFromAndWithImmediate ( SDValue  Op,
APInt UsefulBits,
unsigned  Depth 
)
static

◆ getUsefulBitsFromBFM()

static void getUsefulBitsFromBFM ( SDValue  Op,
SDValue  Orig,
APInt UsefulBits,
unsigned  Depth 
)
static

◆ getUsefulBitsFromBitfieldMoveOpd()

static void getUsefulBitsFromBitfieldMoveOpd ( SDValue  Op,
APInt UsefulBits,
uint64_t  Imm,
uint64_t  MSB,
unsigned  Depth 
)
static

◆ getUsefulBitsFromOrWithShiftedReg()

static void getUsefulBitsFromOrWithShiftedReg ( SDValue  Op,
APInt UsefulBits,
unsigned  Depth 
)
static

◆ getUsefulBitsFromUBFM()

static void getUsefulBitsFromUBFM ( SDValue  Op,
APInt UsefulBits,
unsigned  Depth 
)
static

◆ isBitfieldDstMask()

static bool isBitfieldDstMask ( uint64_t  DstMask,
const APInt BitsToBeInserted,
unsigned  NumberOfIgnoredHighBits,
EVT  VT 
)
static

Does DstMask form a complementary pair with the mask provided by BitsToBeInserted, suitable for use in a BFI instruction.

Roughly speaking, this asks whether DstMask zeroes precisely those bits that will be set by the other half.

Definition at line 1816 of file AArch64ISelDAGToDAG.cpp.

References assert(), llvm::Depth, llvm::EVT::getSizeInBits(), getUsefulBits(), llvm::MVT::i32, llvm::MVT::i64, and llvm::APInt::zextOrTrunc().

Referenced by tryBitfieldInsertOpFromOr().

◆ isBitfieldExtractOp()

static bool isBitfieldExtractOp ( SelectionDAG CurDAG,
SDNode N,
unsigned Opc,
SDValue Opd0,
unsigned Immr,
unsigned Imms,
unsigned  NumberOfIgnoredLowBits = 0,
bool  BiggerPattern = false 
)
static

◆ isBitfieldExtractOpFromAnd()

static bool isBitfieldExtractOpFromAnd ( SelectionDAG CurDAG,
SDNode N,
unsigned Opc,
SDValue Opd0,
unsigned LSB,
unsigned MSB,
unsigned  NumberOfIgnoredLowBits,
bool  BiggerPattern 
)
static

◆ isBitfieldExtractOpFromSExtInReg()

static bool isBitfieldExtractOpFromSExtInReg ( SDNode N,
unsigned Opc,
SDValue Opd0,
unsigned Immr,
unsigned Imms 
)
static

◆ isBitfieldExtractOpFromShr()

static bool isBitfieldExtractOpFromShr ( SDNode N,
unsigned Opc,
SDValue Opd0,
unsigned Immr,
unsigned Imms,
bool  BiggerPattern 
)
static

◆ isBitfieldPositioningOp()

static bool isBitfieldPositioningOp ( SelectionDAG CurDAG,
SDValue  Op,
bool  BiggerPattern,
SDValue Src,
int &  ShiftAmount,
int &  MaskWidth 
)
static

◆ isIntImmediate() [1/2]

static bool isIntImmediate ( const SDNode N,
uint64_t &  Imm 
)
static

isIntImmediate - This method tests to see if the node is a constant operand.

If so Imm will receive the 32-bit value.

Definition at line 211 of file AArch64ISelDAGToDAG.cpp.

References C.

Referenced by isBitfieldExtractOpFromShr(), isIntImmediate(), isOpcWithIntImmediate(), and isSeveralBitsExtractOpFromShr().

◆ isIntImmediate() [2/2]

static bool isIntImmediate ( SDValue  N,
uint64_t &  Imm 
)
static

Definition at line 221 of file AArch64ISelDAGToDAG.cpp.

References llvm::SDValue::getNode(), and isIntImmediate().

◆ isOpcWithIntImmediate()

static bool isOpcWithIntImmediate ( const SDNode N,
unsigned  Opc,
uint64_t &  Imm 
)
static

◆ isPreferredADD()

static bool isPreferredADD ( int64_t  ImmOff)
static

◆ isSeveralBitsExtractOpFromShr()

static bool isSeveralBitsExtractOpFromShr ( SDNode N,
unsigned Opc,
SDValue Opd0,
unsigned LSB,
unsigned MSB 
)
static

◆ isShiftedMask()

static bool isShiftedMask ( uint64_t  Mask,
EVT  VT 
)
static

◆ isWorthFoldingADDlow()

static bool isWorthFoldingADDlow ( SDValue  N)
static

If there's a use of this ADDlow that's not itself a load/store then we'll need to create a real ADD instruction from it anyway and there's no point in folding it into the mem op.

Theoretically, it shouldn't matter, but there's a single pseudo-instruction for an ADRP/ADD pair so over-aggressive folding leads to duplicated ADRP instructions.

Definition at line 662 of file AArch64ISelDAGToDAG.cpp.

References llvm::AArch64ISD::ADDlow, llvm::ISD::ATOMIC_LOAD, llvm::ISD::ATOMIC_STORE, llvm::dyn_cast(), llvm::ISD::FrameIndex, llvm::DataLayout::getABITypeAlignment(), llvm::GlobalValue::getAlignment(), llvm::GlobalAddressSDNode::getGlobal(), llvm::SDValue::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::TargetLoweringBase::getPointerTy(), llvm::GlobalValue::getValueType(), llvm::MVT::i64, llvm::Type::isSized(), llvm::isStrongerThanMonotonic(), llvm::ISD::LOAD, llvm::Log2_32(), N, llvm::AMDGPU::HSAMD::Kernel::Arg::Key::Size, llvm::ISD::STORE, and llvm::SDNode::uses().

◆ isWorthFoldingSHL()

static bool isWorthFoldingSHL ( SDValue  V)
static

◆ narrowIfNeeded()

static SDValue narrowIfNeeded ( SelectionDAG CurDAG,
SDValue  N 
)
static

◆ NarrowVector()

static SDValue NarrowVector ( SDValue  V128Reg,
SelectionDAG DAG 
)
static

◆ tryBitfieldInsertOpFromOr()

static bool tryBitfieldInsertOpFromOr ( SDNode N,
const APInt UsefulBits,
SelectionDAG CurDAG 
)
static

◆ tryBitfieldInsertOpFromOrAndImm()

static bool tryBitfieldInsertOpFromOrAndImm ( SDNode N,
SelectionDAG CurDAG 
)
static

◆ Widen()

static SDValue Widen ( SelectionDAG CurDAG,
SDValue  N 
)
static