LLVM
15.0.0git
|
#include "AArch64MachineFunctionInfo.h"
#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/IR/IntrinsicsAArch64.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"
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) |
static SDNode * | extractSubReg (SelectionDAG *DAG, EVT VT, SDValue V) |
static SDNode * | insertSubReg (SelectionDAG *DAG, EVT VT, SDValue V) |
static EVT | getPackedVectorTypeFromPredicateType (LLVMContext &Ctx, EVT PredVT, unsigned NumVec) |
When PredVT is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent scalable vector of integers MVT::nx<M>xi<bits> s.t. More... | |
static EVT | getMemVTFromNode (LLVMContext &Ctx, SDNode *Root) |
Return the EVT of the data associated to a memory operation in Root . More... | |
#define DEBUG_TYPE "aarch64-isel" |
Definition at line 30 of file AArch64ISelDAGToDAG.cpp.
Definition at line 640 of file AArch64ISelDAGToDAG.cpp.
References DL, llvm::AArch64ISD::DUPLANE16, llvm::AArch64ISD::DUPLANE32, llvm::ISD::EXTRACT_SUBVECTOR, llvm::SDValue::getNode(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), llvm::ConstantSDNode::getSExtValue(), and llvm::ISD::INSERT_SUBVECTOR.
Referenced by checkV64LaneV128().
|
static |
Definition at line 663 of file AArch64ISelDAGToDAG.cpp.
References checkHighLaneIndex(), llvm::SDValue::getNode(), and std::swap().
|
static |
Definition at line 3387 of file AArch64ISelDAGToDAG.cpp.
References assert(), DL, llvm::TypeSize::getKnownMinSize(), llvm::SelectionDAG::getMachineNode(), llvm::EVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), llvm::SDValue::getValueType(), llvm::MVT::i32, llvm::MVT::i64, llvm::EVT::isFixedLengthVector(), llvm::EVT::isScalableVector(), SubReg, and llvm::AArch64::SVEBitsPerBlock.
|
static |
getExtendTypeForNode - Translate an extend node to the corresponding ExtendType value.
Definition at line 588 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::AND, llvm::ISD::ANY_EXTEND, assert(), llvm::ConstantSDNode::getZExtValue(), llvm::MVT::i16, llvm::MVT::i32, llvm::MVT::i64, llvm::MVT::i8, llvm::AArch64_AM::InvalidShiftExtend, N, llvm::ISD::SIGN_EXTEND, llvm::ISD::SIGN_EXTEND_INREG, llvm::AArch64_AM::SXTB, llvm::AArch64_AM::SXTH, llvm::AArch64_AM::SXTW, llvm::AArch64_AM::UXTB, llvm::AArch64_AM::UXTH, llvm::AArch64_AM::UXTW, and llvm::ISD::ZERO_EXTEND.
Definition at line 2967 of file AArch64ISelDAGToDAG.cpp.
References assert(), and llvm::StringRef::split().
|
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 2399 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::BitWidth, llvm::SelectionDAG::getMachineNode(), llvm::EVT::getSizeInBits(), and llvm::SelectionDAG::getTargetConstant().
Referenced by isBitfieldPositioningOp().
|
static |
Return the EVT of the data associated to a memory operation in Root
.
If such EVT cannot be retrived, it returns an invalid EVT.
Definition at line 5041 of file AArch64ISelDAGToDAG.cpp.
References llvm::SDNode::getOpcode(), llvm::SDNode::getOperand(), getPackedVectorTypeFromPredicateType(), llvm::SDNode::getValueType(), llvm::ISD::INTRINSIC_VOID, llvm::AArch64ISD::LD1_MERGE_ZERO, llvm::AArch64ISD::LD1S_MERGE_ZERO, llvm::AArch64ISD::LDNF1_MERGE_ZERO, llvm::AArch64ISD::LDNF1S_MERGE_ZERO, llvm::AArch64ISD::ST1_PRED, llvm::AArch64ISD::SVE_LD2_MERGE_ZERO, llvm::AArch64ISD::SVE_LD3_MERGE_ZERO, and llvm::AArch64ISD::SVE_LD4_MERGE_ZERO.
|
static |
When PredVT
is a scalable vector predicate in the form MVT::nx<M>xi1, it builds the correspondent scalable vector of integers MVT::nx<M>xi<bits> s.t.
M x bits = 128. When targeting structured vectors (NumVec >1), the output data type is MVT::nx<M*NumVec>xi<bits> s.t. M x bits = 128. If the input PredVT is not in the form MVT::nx<M>xi1, it returns an invalid EVT.
Definition at line 5021 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::EVT::getIntegerVT(), llvm::EVT::getVectorElementCount(), llvm::EVT::getVectorElementType(), llvm::EVT::getVectorVT(), llvm::MVT::i1, llvm::EVT::isScalableVector(), llvm::MVT::nxv16i1, llvm::MVT::nxv2i1, llvm::MVT::nxv4i1, llvm::MVT::nxv8i1, and llvm::AArch64::SVEBitsPerBlock.
Referenced by getMemVTFromNode().
|
static |
getShiftTypeForNode - Translate a shift node to the corresponding ShiftType value.
Definition at line 496 of file AArch64ISelDAGToDAG.cpp.
References llvm::AArch64_AM::ASR, llvm::AArch64_AM::InvalidShiftExtend, llvm::AArch64_AM::LSL, llvm::AArch64_AM::LSR, N, llvm::AArch64_AM::ROR, llvm::ISD::ROTR, llvm::ISD::SHL, llvm::ISD::SRA, and llvm::ISD::SRL.
Definition at line 2372 of file AArch64ISelDAGToDAG.cpp.
References llvm::Depth, llvm::APInt::flipAllBits(), llvm::APInt::getBitWidth(), and llvm::SelectionDAG::MaxRecursionDepth.
Referenced by getUsefulBitsFromAndWithImmediate(), getUsefulBitsFromBFM(), getUsefulBitsFromBitfieldMoveOpd(), and getUsefulBitsFromOrWithShiftedReg().
|
static |
Definition at line 2324 of file AArch64ISelDAGToDAG.cpp.
References llvm::Depth, llvm::APInt::getBitWidth(), llvm::SDNode::getMachineOpcode(), llvm::SDNode::getOperand(), getUsefulBitsFromAndWithImmediate(), getUsefulBitsFromBFM(), getUsefulBitsFromOrWithShiftedReg(), getUsefulBitsFromUBFM(), and llvm::SDNode::isMachineOpcode().
|
static |
Definition at line 2195 of file AArch64ISelDAGToDAG.cpp.
References llvm::AArch64_AM::decodeLogicalImmediate(), llvm::Depth, llvm::APInt::getBitWidth(), and getUsefulBits().
Referenced by getUsefulBitsForUse().
|
static |
Definition at line 2269 of file AArch64ISelDAGToDAG.cpp.
References llvm::Depth, llvm::APInt::flipAllBits(), llvm::APInt::getBitWidth(), getUsefulBits(), and llvm::BitmaskEnumDetail::Mask().
Referenced by getUsefulBitsForUse().
|
static |
Definition at line 2204 of file AArch64ISelDAGToDAG.cpp.
References llvm::Depth, llvm::APInt::getBitWidth(), getUsefulBits(), and llvm::APInt::lshrInPlace().
Referenced by getUsefulBitsFromUBFM().
|
static |
Definition at line 2241 of file AArch64ISelDAGToDAG.cpp.
References llvm::Depth, llvm::AArch64_AM::getShiftType(), llvm::AArch64_AM::getShiftValue(), getUsefulBits(), llvm::AArch64_AM::LSL, llvm::AArch64_AM::LSR, and llvm::BitmaskEnumDetail::Mask().
Referenced by getUsefulBitsForUse().
Definition at line 2231 of file AArch64ISelDAGToDAG.cpp.
References llvm::Depth, and getUsefulBitsFromBitfieldMoveOpd().
Referenced by getUsefulBitsForUse().
|
static |
Definition at line 3414 of file AArch64ISelDAGToDAG.cpp.
References assert(), DL, llvm::TypeSize::getKnownMinSize(), llvm::SelectionDAG::getMachineNode(), llvm::EVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), llvm::SDValue::getValueType(), llvm::MVT::i32, llvm::MVT::i64, llvm::EVT::isFixedLengthVector(), llvm::EVT::isScalableVector(), SubReg, and llvm::AArch64::SVEBitsPerBlock.
|
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 2165 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::BitWidth, llvm::EVT::getSizeInBits(), llvm::MVT::i32, llvm::MVT::i64, and llvm::APInt::zextOrTrunc().
Referenced by tryBitfieldInsertOpFromOr().
|
static |
Definition at line 2092 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::AND, llvm::MVT::i32, llvm::MVT::i64, isBitfieldExtractOpFromAnd(), isBitfieldExtractOpFromSExtInReg(), isBitfieldExtractOpFromShr(), N, llvm::ISD::SIGN_EXTEND_INREG, llvm::ISD::SRA, and llvm::ISD::SRL.
Referenced by tryBitfieldInsertOpFromOr().
|
static |
Definition at line 1800 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::AND, llvm::ISD::ANY_EXTEND, assert(), llvm::dbgs(), llvm::SDValue::getNode(), llvm::SDNode::getOpcode(), llvm::SDValue::getOperand(), llvm::SDNode::getOperand(), llvm::EVT::getSizeInBits(), llvm::SDNode::getValueType(), llvm::MVT::i32, llvm::MVT::i64, isOpcWithIntImmediate(), LLVM_DEBUG, N, llvm::ISD::SRL, llvm::ISD::TRUNCATE, and Widen().
Referenced by isBitfieldExtractOp().
|
static |
Definition at line 1893 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::BitWidth, llvm::EVT::getSizeInBits(), llvm::MVT::i32, llvm::MVT::i64, isOpcWithIntImmediate(), N, llvm::ISD::SIGN_EXTEND_INREG, llvm::ISD::SRA, llvm::ISD::SRL, and llvm::ISD::TRUNCATE.
Referenced by isBitfieldExtractOp().
|
static |
Definition at line 1972 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::dbgs(), llvm::EVT::getSizeInBits(), llvm::SDValue::getValueType(), llvm::SDNode::getValueType(), llvm::MVT::i32, llvm::MVT::i64, isIntImmediate(), isOpcWithIntImmediate(), isSeveralBitsExtractOpFromShr(), LLVM_DEBUG, N, llvm::ISD::SHL, llvm::ISD::SRA, llvm::ISD::SRL, and llvm::ISD::TRUNCATE.
Referenced by isBitfieldExtractOp().
|
static |
Does this tree qualify as an attempt to move a bitfield into position, essentially "(and (shl VAL, N), Mask)".
Definition at line 2429 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::AND, assert(), llvm::BitWidth, llvm::SelectionDAG::computeKnownBits(), llvm::countTrailingOnes(), llvm::countTrailingZeros(), getLeftShift(), llvm::EVT::getSizeInBits(), isOpcWithIntImmediate(), llvm::isShiftedMask_64(), llvm::ISD::SHL, and llvm::KnownBits::Zero.
Referenced by tryBitfieldInsertOpFromOr().
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 383 of file AArch64ISelDAGToDAG.cpp.
References N.
Referenced by isBitfieldExtractOpFromShr(), isIntImmediate(), isOpcWithIntImmediate(), and isSeveralBitsExtractOpFromShr().
Definition at line 393 of file AArch64ISelDAGToDAG.cpp.
References isIntImmediate(), and N.
Definition at line 400 of file AArch64ISelDAGToDAG.cpp.
References isIntImmediate(), and N.
Referenced by isBitfieldExtractOpFromAnd(), isBitfieldExtractOpFromSExtInReg(), isBitfieldExtractOpFromShr(), isBitfieldPositioningOp(), isSeveralBitsExtractOpFromShr(), tryBitfieldInsertOpFromOr(), and tryBitfieldInsertOpFromOrAndImm().
|
static |
Definition at line 1140 of file AArch64ISelDAGToDAG.cpp.
|
static |
Definition at line 1926 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::AND, llvm::countLeadingOnes(), llvm::MVT::i32, isIntImmediate(), llvm::isMask_64(), isOpcWithIntImmediate(), N, and llvm::ISD::SRL.
Referenced by isBitfieldExtractOpFromShr().
Definition at line 2480 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::MVT::i32, llvm::MVT::i64, llvm::isShiftedMask_32(), llvm::isShiftedMask_64(), and llvm::BitmaskEnumDetail::Mask().
Referenced by tryBitfieldInsertOpFromOr(), and tryBitfieldInsertOpFromOrAndImm().
|
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 851 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::ATOMIC_LOAD, llvm::ISD::ATOMIC_STORE, llvm::isStrongerThanMonotonic(), llvm::ISD::LOAD, N, and llvm::ISD::STORE.
|
static |
Determine whether it is worth it to fold SHL into the addressing mode.
Definition at line 513 of file AArch64ISelDAGToDAG.cpp.
References assert(), llvm::SDValue::getOpcode(), llvm::SDValue::getOperand(), and llvm::ISD::SHL.
|
static |
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).
Extract the appropriate low bits if this is the case.
Definition at line 772 of file AArch64ISelDAGToDAG.cpp.
References llvm::SelectionDAG::getTargetConstant(), llvm::MVT::i32, N, and SubReg.
|
static |
NarrowVector - Given a value in the V128 register class, produce the equivalent value in the V64 register class.
Definition at line 1633 of file AArch64ISelDAGToDAG.cpp.
References llvm::EVT::getSimpleVT(), llvm::SelectionDAG::getTargetExtractSubreg(), llvm::SDValue::getValueType(), llvm::EVT::getVectorElementType(), llvm::EVT::getVectorNumElements(), and llvm::MVT::getVectorVT().
|
static |
Definition at line 2577 of file AArch64ISelDAGToDAG.cpp.
References llvm::ISD::AND, assert(), llvm::BitWidth, llvm::SelectionDAG::computeKnownBits(), llvm::APInt::countLeadingZeros(), llvm::APInt::countPopulation(), llvm::countTrailingZeros(), llvm::APInt::countTrailingZeros(), DL, llvm::APInt::getBitsSet(), llvm::KnownBits::getBitWidth(), llvm::SelectionDAG::getMachineNode(), llvm::SDValue::getNode(), llvm::SDNode::getOperand(), llvm::EVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), llvm::SDValue::getValueType(), llvm::SDValue::hasOneUse(), I, llvm::MVT::i32, llvm::MVT::i64, isBitfieldDstMask(), isBitfieldExtractOp(), isBitfieldPositioningOp(), isOpcWithIntImmediate(), isShiftedMask(), llvm::AArch64_AM::LSR, N, llvm::ISD::OR, llvm::SelectionDAG::SelectNodeTo(), llvm::ISD::SRL, std::swap(), and llvm::KnownBits::Zero.
|
static |
Definition at line 2489 of file AArch64ISelDAGToDAG.cpp.
References llvm::And, llvm::ISD::AND, assert(), llvm::BitWidth, llvm::SelectionDAG::computeKnownBits(), llvm::APInt::countPopulation(), llvm::countTrailingOnes(), DL, llvm::SelectionDAG::getMachineNode(), llvm::EVT::getSizeInBits(), llvm::SelectionDAG::getTargetConstant(), llvm::APInt::getZExtValue(), llvm::MVT::i32, llvm::MVT::i64, llvm::AArch64_AM::isLogicalImmediate(), isOpcWithIntImmediate(), isShiftedMask(), llvm::AArch64ISD::MOVI, N, llvm::ISD::OR, llvm::SelectionDAG::SelectNodeTo(), Shift, and llvm::KnownBits::Zero.
|
static |
Definition at line 1019 of file AArch64ISelDAGToDAG.cpp.
References llvm::SelectionDAG::getMachineNode(), llvm::SelectionDAG::getTargetConstant(), llvm::MVT::i32, llvm::MVT::i64, N, and SubReg.
Referenced by getAVX512Node(), and isBitfieldExtractOpFromAnd().