#include "HexagonISelLowering.h"
#include "Hexagon.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "HexagonTargetObjectFile.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/TargetCallingConv.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsHexagon.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
static cl::opt<bool> EmitJumpTables("hexagon-emit-jump-tables",
cl::init(true), cl::Hidden,
cl::desc("Control jump table emission on Hexagon target"));
static cl::opt<bool>
EnableHexSDNodeSched("enable-hexagon-sdnode-sched", cl::Hidden,
cl::desc("Enable Hexagon SDNode scheduling"));
static cl::opt<bool> EnableFastMath("ffast-math", cl::Hidden,
cl::desc("Enable Fast Math processing"));
static cl::opt<int> MinimumJumpTables("minimum-jump-tables", cl::Hidden,
cl::init(5),
cl::desc("Set minimum jump tables"));
static cl::opt<int>
MaxStoresPerMemcpyCL("max-store-memcpy", cl::Hidden, cl::init(6),
cl::desc("Max #stores to inline memcpy"));
static cl::opt<int>
MaxStoresPerMemcpyOptSizeCL("max-store-memcpy-Os", cl::Hidden, cl::init(4),
cl::desc("Max #stores to inline memcpy"));
static cl::opt<int>
MaxStoresPerMemmoveCL("max-store-memmove", cl::Hidden, cl::init(6),
cl::desc("Max #stores to inline memmove"));
static cl::opt<int>
MaxStoresPerMemmoveOptSizeCL("max-store-memmove-Os", cl::Hidden,
cl::init(4),
cl::desc("Max #stores to inline memmove"));
static cl::opt<int>
MaxStoresPerMemsetCL("max-store-memset", cl::Hidden, cl::init(8),
cl::desc("Max #stores to inline memset"));
static cl::opt<int>
MaxStoresPerMemsetOptSizeCL("max-store-memset-Os", cl::Hidden, cl::init(4),
cl::desc("Max #stores to inline memset"));
static cl::opt<bool> AlignLoads("hexagon-align-loads",
cl::Hidden, cl::init(false),
cl::desc("Rewrite unaligned loads as a pair of aligned loads"));
static cl::opt<bool>
DisableArgsMinAlignment("hexagon-disable-args-min-alignment", cl::Hidden,
cl::init(false),
cl::desc("Disable minimum alignment of 1 for "
"arguments passed by value on stack"));
namespace {
class HexagonCCState : public CCState { … };
}
static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags, CCState &State) { … }
#include "HexagonGenCallingConv.inc"
SDValue
HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG)
const { … }
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst,
SDValue Chain, ISD::ArgFlagsTy Flags,
SelectionDAG &DAG, const SDLoc &dl) { … }
bool
HexagonTargetLowering::CanLowerReturn(
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
LLVMContext &Context) const { … }
SDValue
HexagonTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SDLoc &dl, SelectionDAG &DAG) const { … }
bool HexagonTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const { … }
Register HexagonTargetLowering::getRegisterByName(
const char* RegName, LLT VT, const MachineFunction &) const { … }
SDValue HexagonTargetLowering::LowerCallResult(
SDValue Chain, SDValue Glue, CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,
const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const { … }
SDValue
HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const { … }
bool HexagonTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM,
SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerFDIV(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerPREFETCH(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerREADCYCLECOUNTER(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerREADSTEADYCOUNTER(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerFormalArguments(
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { … }
SDValue
HexagonTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const { … }
SDValue
HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG)
const { … }
SDValue
HexagonTargetLowering::GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
GlobalAddressSDNode *GA, SDValue Glue, EVT PtrVT, unsigned ReturnReg,
unsigned char OperandFlags) const { … }
SDValue
HexagonTargetLowering::LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerGlobalTLSAddress(SDValue Op,
SelectionDAG &DAG) const { … }
HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
const HexagonSubtarget &ST)
: … { … }
const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const { … }
bool
HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
const SDLoc &dl, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::replaceMemWithUndef(SDValue Op, SelectionDAG &DAG)
const { … }
static bool isBrevLdIntrinsic(const Value *Inst) { … }
static Value *getBrevLdObject(Value *V) { … }
static Value *returnEdge(const PHINode *PN, Value *IntrBaseVal) { … }
static Value *getUnderLyingObjectForBrevLdIntr(Value *V) { … }
bool HexagonTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
const CallInst &I,
MachineFunction &MF,
unsigned Intrinsic) const { … }
bool HexagonTargetLowering::hasBitTest(SDValue X, SDValue Y) const { … }
bool HexagonTargetLowering::isTruncateFree(Type *Ty1, Type *Ty2) const { … }
bool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { … }
bool HexagonTargetLowering::isFMAFasterThanFMulAndFAdd(
const MachineFunction &MF, EVT VT) const { … }
bool HexagonTargetLowering::shouldExpandBuildVectorWithShuffles(EVT VT,
unsigned DefinedValues) const { … }
bool HexagonTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
unsigned Index) const { … }
bool HexagonTargetLowering::isTargetCanonicalConstantNode(SDValue Op) const { … }
bool HexagonTargetLowering::isShuffleMaskLegal(ArrayRef<int> Mask,
EVT VT) const { … }
TargetLoweringBase::LegalizeTypeAction
HexagonTargetLowering::getPreferredVectorAction(MVT VT) const { … }
TargetLoweringBase::LegalizeAction
HexagonTargetLowering::getCustomOperationAction(SDNode &Op) const { … }
std::pair<SDValue, int>
HexagonTargetLowering::getBaseAndOffset(SDValue Addr) const { … }
SDValue
HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
const { … }
SDValue
HexagonTargetLowering::getSplatValue(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::getVectorShiftByInt(SDValue Op, SelectionDAG &DAG)
const { … }
SDValue
HexagonTargetLowering::LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const { … }
bool
HexagonTargetLowering::getBuildVectorConstInts(ArrayRef<SDValue> Values,
MVT VecTy, SelectionDAG &DAG,
MutableArrayRef<ConstantInt*> Consts) const { … }
SDValue
HexagonTargetLowering::buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl,
MVT VecTy, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl,
MVT VecTy, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::extractVector(SDValue VecV, SDValue IdxV,
const SDLoc &dl, MVT ValTy, MVT ResTy,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::extractVectorPred(SDValue VecV, SDValue IdxV,
const SDLoc &dl, MVT ValTy, MVT ResTy,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::insertVector(SDValue VecV, SDValue ValV, SDValue IdxV,
const SDLoc &dl, MVT ValTy,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::insertVectorPred(SDValue VecV, SDValue ValV,
SDValue IdxV, const SDLoc &dl,
MVT ValTy, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::expandPredicate(SDValue Vec32, const SDLoc &dl,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::contractPredicate(SDValue Vec64, const SDLoc &dl,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG)
const { … }
SDValue
HexagonTargetLowering::appendUndef(SDValue Val, MVT ResTy, SelectionDAG &DAG)
const { … }
SDValue
HexagonTargetLowering::getCombine(SDValue Hi, SDValue Lo, const SDLoc &dl,
MVT ResTy, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerCONCAT_VECTORS(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerEXTRACT_SUBVECTOR(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerINSERT_SUBVECTOR(SDValue Op,
SelectionDAG &DAG) const { … }
bool
HexagonTargetLowering::allowTruncateForTailCall(Type *Ty1, Type *Ty2) const { … }
SDValue
HexagonTargetLowering::LowerLoad(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerStore(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG)
const { … }
SDValue
HexagonTargetLowering::LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const { … }
SDValue HexagonTargetLowering::LowerUAddSubOCarry(SDValue Op,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { … }
void
HexagonTargetLowering::LowerOperationWrapper(SDNode *N,
SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const { … }
void
HexagonTargetLowering::ReplaceNodeResults(SDNode *N,
SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const { … }
SDValue
HexagonTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const { … }
SDValue
HexagonTargetLowering::getPICJumpTableRelocBase(SDValue Table,
SelectionDAG &DAG) const { … }
TargetLowering::ConstraintType
HexagonTargetLowering::getConstraintType(StringRef Constraint) const { … }
std::pair<unsigned, const TargetRegisterClass*>
HexagonTargetLowering::getRegForInlineAsmConstraint(
const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const { … }
bool HexagonTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const { … }
bool HexagonTargetLowering::isLegalAddressingMode(const DataLayout &DL,
const AddrMode &AM, Type *Ty,
unsigned AS, Instruction *I) const { … }
bool HexagonTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA)
const { … }
bool HexagonTargetLowering::isLegalICmpImmediate(int64_t Imm) const { … }
bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
SDValue Callee,
CallingConv::ID CalleeCC,
bool IsVarArg,
bool IsCalleeStructRet,
bool IsCallerStructRet,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SmallVectorImpl<ISD::InputArg> &Ins,
SelectionDAG& DAG) const { … }
EVT HexagonTargetLowering::getOptimalMemOpType(
const MemOp &Op, const AttributeList &FuncAttributes) const { … }
bool HexagonTargetLowering::allowsMemoryAccess(
LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace,
Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const { … }
bool HexagonTargetLowering::allowsMisalignedMemoryAccesses(
EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags,
unsigned *Fast) const { … }
std::pair<const TargetRegisterClass*, uint8_t>
HexagonTargetLowering::findRepresentativeClass(const TargetRegisterInfo *TRI,
MVT VT) const { … }
bool HexagonTargetLowering::shouldReduceLoadWidth(SDNode *Load,
ISD::LoadExtType ExtTy, EVT NewVT) const { … }
void HexagonTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
SDNode *Node) const { … }
Value *HexagonTargetLowering::emitLoadLinked(IRBuilderBase &Builder,
Type *ValueTy, Value *Addr,
AtomicOrdering Ord) const { … }
Value *HexagonTargetLowering::emitStoreConditional(IRBuilderBase &Builder,
Value *Val, Value *Addr,
AtomicOrdering Ord) const { … }
TargetLowering::AtomicExpansionKind
HexagonTargetLowering::shouldExpandAtomicLoadInIR(LoadInst *LI) const { … }
TargetLowering::AtomicExpansionKind
HexagonTargetLowering::shouldExpandAtomicStoreInIR(StoreInst *SI) const { … }
TargetLowering::AtomicExpansionKind
HexagonTargetLowering::shouldExpandAtomicCmpXchgInIR(
AtomicCmpXchgInst *AI) const { … }