Home | History | Annotate | Download | only in Hexagon
      1 //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the interfaces that Hexagon uses to lower LLVM code into a
     11 // selection DAG.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
     16 #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
     17 
     18 #include "Hexagon.h"
     19 #include "llvm/CodeGen/CallingConvLower.h"
     20 #include "llvm/IR/CallingConv.h"
     21 #include "llvm/Target/TargetLowering.h"
     22 
     23 namespace llvm {
     24 
     25 // Return true when the given node fits in a positive half word.
     26 bool isPositiveHalfWord(SDNode *N);
     27 
     28   namespace HexagonISD {
     29     enum NodeType : unsigned {
     30       OP_BEGIN = ISD::BUILTIN_OP_END,
     31 
     32       CONST32 = OP_BEGIN,
     33       CONST32_GP,  // For marking data present in GP.
     34       FCONST32,
     35       ALLOCA,
     36       ARGEXTEND,
     37 
     38       AT_GOT,      // Index in GOT.
     39       AT_PCREL,    // Offset relative to PC.
     40 
     41       CALLv3,      // A V3+ call instruction.
     42       CALLv3nr,    // A V3+ call instruction that doesn't return.
     43       CALLR,
     44 
     45       RET_FLAG,    // Return with a flag operand.
     46       BARRIER,     // Memory barrier.
     47       JT,          // Jump table.
     48       CP,          // Constant pool.
     49 
     50       POPCOUNT,
     51       COMBINE,
     52       PACKHL,
     53       VSPLATB,
     54       VSPLATH,
     55       SHUFFEB,
     56       SHUFFEH,
     57       SHUFFOB,
     58       SHUFFOH,
     59       VSXTBH,
     60       VSXTBW,
     61       VSRAW,
     62       VSRAH,
     63       VSRLW,
     64       VSRLH,
     65       VSHLW,
     66       VSHLH,
     67       VCMPBEQ,
     68       VCMPBGT,
     69       VCMPBGTU,
     70       VCMPHEQ,
     71       VCMPHGT,
     72       VCMPHGTU,
     73       VCMPWEQ,
     74       VCMPWGT,
     75       VCMPWGTU,
     76 
     77       INSERT,
     78       INSERTRP,
     79       EXTRACTU,
     80       EXTRACTURP,
     81       VCOMBINE,
     82       TC_RETURN,
     83       EH_RETURN,
     84       DCFETCH,
     85 
     86       OP_END
     87     };
     88   }
     89 
     90   class HexagonSubtarget;
     91 
     92   class HexagonTargetLowering : public TargetLowering {
     93     int VarArgsFrameOffset;   // Frame offset to start of varargs area.
     94 
     95     bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize)
     96         const;
     97     void promoteLdStType(MVT VT, MVT PromotedLdStVT);
     98     const HexagonTargetMachine &HTM;
     99     const HexagonSubtarget &Subtarget;
    100 
    101   public:
    102     explicit HexagonTargetLowering(const TargetMachine &TM,
    103                                    const HexagonSubtarget &ST);
    104 
    105     /// IsEligibleForTailCallOptimization - Check whether the call is eligible
    106     /// for tail call optimization. Targets which want to do tail call
    107     /// optimization should implement this function.
    108     bool IsEligibleForTailCallOptimization(SDValue Callee,
    109         CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet,
    110         bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs,
    111         const SmallVectorImpl<SDValue> &OutVals,
    112         const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const;
    113 
    114     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
    115     bool isTruncateFree(EVT VT1, EVT VT2) const override;
    116 
    117     bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override;
    118 
    119     // Should we expand the build vector with shuffles?
    120     bool shouldExpandBuildVectorWithShuffles(EVT VT,
    121         unsigned DefinedValues) const override;
    122 
    123     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
    124     const char *getTargetNodeName(unsigned Opcode) const override;
    125     SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const;
    126     SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
    127     SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
    128     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
    129     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
    130     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
    131     SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
    132     SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
    133     SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
    134     SDValue
    135     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    136                          const SmallVectorImpl<ISD::InputArg> &Ins,
    137                          const SDLoc &dl, SelectionDAG &DAG,
    138                          SmallVectorImpl<SDValue> &InVals) const override;
    139     SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
    140     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
    141     SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
    142     SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
    143         SelectionDAG &DAG) const;
    144     SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA,
    145         SelectionDAG &DAG) const;
    146     SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA,
    147         SelectionDAG &DAG) const;
    148     SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain,
    149         GlobalAddressSDNode *GA, SDValue *InFlag, EVT PtrVT,
    150         unsigned ReturnReg, unsigned char OperandFlags) const;
    151     SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
    152 
    153     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
    154         SmallVectorImpl<SDValue> &InVals) const override;
    155     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
    156                             CallingConv::ID CallConv, bool isVarArg,
    157                             const SmallVectorImpl<ISD::InputArg> &Ins,
    158                             const SDLoc &dl, SelectionDAG &DAG,
    159                             SmallVectorImpl<SDValue> &InVals,
    160                             const SmallVectorImpl<SDValue> &OutVals,
    161                             SDValue Callee) const;
    162 
    163     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
    164     SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const;
    165     SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
    166     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
    167     SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
    168     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
    169     SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
    170 
    171     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
    172                         const SmallVectorImpl<ISD::OutputArg> &Outs,
    173                         const SmallVectorImpl<SDValue> &OutVals,
    174                         const SDLoc &dl, SelectionDAG &DAG) const override;
    175 
    176     bool mayBeEmittedAsTailCall(CallInst *CI) const override;
    177     MachineBasicBlock *
    178     EmitInstrWithCustomInserter(MachineInstr &MI,
    179                                 MachineBasicBlock *BB) const override;
    180 
    181     /// If a physical register, this returns the register that receives the
    182     /// exception address on entry to an EH pad.
    183     unsigned
    184     getExceptionPointerRegister(const Constant *PersonalityFn) const override {
    185       return Hexagon::R0;
    186     }
    187 
    188     /// If a physical register, this returns the register that receives the
    189     /// exception typeid on entry to a landing pad.
    190     unsigned
    191     getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
    192       return Hexagon::R1;
    193     }
    194 
    195     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
    196     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
    197     SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
    198     EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
    199                            EVT VT) const override {
    200       if (!VT.isVector())
    201         return MVT::i1;
    202       else
    203         return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements());
    204     }
    205 
    206     bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
    207                                     SDValue &Base, SDValue &Offset,
    208                                     ISD::MemIndexedMode &AM,
    209                                     SelectionDAG &DAG) const override;
    210 
    211     ConstraintType getConstraintType(StringRef Constraint) const override;
    212 
    213     std::pair<unsigned, const TargetRegisterClass *>
    214     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
    215                                  StringRef Constraint, MVT VT) const override;
    216 
    217     unsigned
    218     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
    219       if (ConstraintCode == "o")
    220         return InlineAsm::Constraint_o;
    221       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
    222     }
    223 
    224     // Intrinsics
    225     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
    226     SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
    227     /// isLegalAddressingMode - Return true if the addressing mode represented
    228     /// by AM is legal for this target, for a load/store of the specified type.
    229     /// The type may be VoidTy, in which case only return true if the addressing
    230     /// mode is legal for a load/store of any legal type.
    231     /// TODO: Handle pre/postinc as well.
    232     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
    233                                Type *Ty, unsigned AS) const override;
    234     /// Return true if folding a constant offset with the given GlobalAddress
    235     /// is legal.  It is frequently not legal in PIC relocation models.
    236     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
    237 
    238     bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
    239 
    240     /// isLegalICmpImmediate - Return true if the specified immediate is legal
    241     /// icmp immediate, that is the target has icmp instructions which can
    242     /// compare a register against the immediate without having to materialize
    243     /// the immediate into a register.
    244     bool isLegalICmpImmediate(int64_t Imm) const override;
    245 
    246     bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace,
    247         unsigned Align, bool *Fast) const override;
    248 
    249     /// Returns relocation base for the given PIC jumptable.
    250     SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
    251                                      const override;
    252 
    253     // Handling of atomic RMW instructions.
    254     Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
    255         AtomicOrdering Ord) const override;
    256     Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val,
    257         Value *Addr, AtomicOrdering Ord) const override;
    258     AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override;
    259     bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override;
    260     bool shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override;
    261 
    262     AtomicExpansionKind
    263     shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override {
    264       return AtomicExpansionKind::LLSC;
    265     }
    266 
    267   protected:
    268     std::pair<const TargetRegisterClass*, uint8_t>
    269     findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT)
    270         const override;
    271   };
    272 } // end namespace llvm
    273 
    274 #endif    // Hexagon_ISELLOWERING_H
    275