HexagonSubtarget.h revision 341825
1//===- HexagonSubtarget.h - Define Subtarget for the Hexagon ----*- 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 declares the Hexagon specific subclass of TargetSubtarget. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H 15#define LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H 16 17#include "HexagonDepArch.h" 18#include "HexagonFrameLowering.h" 19#include "HexagonISelLowering.h" 20#include "HexagonInstrInfo.h" 21#include "HexagonRegisterInfo.h" 22#include "HexagonSelectionDAGInfo.h" 23#include "llvm/ADT/SmallSet.h" 24#include "llvm/ADT/StringRef.h" 25#include "llvm/CodeGen/ScheduleDAGMutation.h" 26#include "llvm/CodeGen/TargetSubtargetInfo.h" 27#include "llvm/MC/MCInstrItineraries.h" 28#include <memory> 29#include <string> 30#include <vector> 31 32#define GET_SUBTARGETINFO_HEADER 33#include "HexagonGenSubtargetInfo.inc" 34 35namespace llvm { 36 37class MachineInstr; 38class SDep; 39class SUnit; 40class TargetMachine; 41class Triple; 42 43class HexagonSubtarget : public HexagonGenSubtargetInfo { 44 virtual void anchor(); 45 46 bool UseHVX64BOps = false; 47 bool UseHVX128BOps = false; 48 49 bool UseLongCalls = false; 50 bool UseMemops = false; 51 bool UsePackets = false; 52 bool UseNewValueJumps = false; 53 bool UseNewValueStores = false; 54 bool UseSmallData = false; 55 56 bool HasMemNoShuf = false; 57 bool EnableDuplex = false; 58 bool ReservedR19 = false; 59 60public: 61 Hexagon::ArchEnum HexagonArchVersion; 62 Hexagon::ArchEnum HexagonHVXVersion = Hexagon::ArchEnum::V4; 63 CodeGenOpt::Level OptLevel; 64 /// True if the target should use Back-Skip-Back scheduling. This is the 65 /// default for V60. 66 bool UseBSBScheduling; 67 68 struct UsrOverflowMutation : public ScheduleDAGMutation { 69 void apply(ScheduleDAGInstrs *DAG) override; 70 }; 71 struct HVXMemLatencyMutation : public ScheduleDAGMutation { 72 void apply(ScheduleDAGInstrs *DAG) override; 73 }; 74 struct CallMutation : public ScheduleDAGMutation { 75 void apply(ScheduleDAGInstrs *DAG) override; 76 private: 77 bool shouldTFRICallBind(const HexagonInstrInfo &HII, 78 const SUnit &Inst1, const SUnit &Inst2) const; 79 }; 80 struct BankConflictMutation : public ScheduleDAGMutation { 81 void apply(ScheduleDAGInstrs *DAG) override; 82 }; 83 84private: 85 std::string CPUString; 86 HexagonInstrInfo InstrInfo; 87 HexagonRegisterInfo RegInfo; 88 HexagonTargetLowering TLInfo; 89 HexagonSelectionDAGInfo TSInfo; 90 HexagonFrameLowering FrameLowering; 91 InstrItineraryData InstrItins; 92 93public: 94 HexagonSubtarget(const Triple &TT, StringRef CPU, StringRef FS, 95 const TargetMachine &TM); 96 97 /// getInstrItins - Return the instruction itineraries based on subtarget 98 /// selection. 99 const InstrItineraryData *getInstrItineraryData() const override { 100 return &InstrItins; 101 } 102 const HexagonInstrInfo *getInstrInfo() const override { return &InstrInfo; } 103 const HexagonRegisterInfo *getRegisterInfo() const override { 104 return &RegInfo; 105 } 106 const HexagonTargetLowering *getTargetLowering() const override { 107 return &TLInfo; 108 } 109 const HexagonFrameLowering *getFrameLowering() const override { 110 return &FrameLowering; 111 } 112 const HexagonSelectionDAGInfo *getSelectionDAGInfo() const override { 113 return &TSInfo; 114 } 115 116 HexagonSubtarget &initializeSubtargetDependencies(StringRef CPU, 117 StringRef FS); 118 119 /// ParseSubtargetFeatures - Parses features string setting specified 120 /// subtarget options. Definition of function is auto generated by tblgen. 121 void ParseSubtargetFeatures(StringRef CPU, StringRef FS); 122 123 bool hasV5Ops() const { 124 return getHexagonArchVersion() >= Hexagon::ArchEnum::V5; 125 } 126 bool hasV5OpsOnly() const { 127 return getHexagonArchVersion() == Hexagon::ArchEnum::V5; 128 } 129 bool hasV55Ops() const { 130 return getHexagonArchVersion() >= Hexagon::ArchEnum::V55; 131 } 132 bool hasV55OpsOnly() const { 133 return getHexagonArchVersion() == Hexagon::ArchEnum::V55; 134 } 135 bool hasV60Ops() const { 136 return getHexagonArchVersion() >= Hexagon::ArchEnum::V60; 137 } 138 bool hasV60OpsOnly() const { 139 return getHexagonArchVersion() == Hexagon::ArchEnum::V60; 140 } 141 bool hasV62Ops() const { 142 return getHexagonArchVersion() >= Hexagon::ArchEnum::V62; 143 } 144 bool hasV62OpsOnly() const { 145 return getHexagonArchVersion() == Hexagon::ArchEnum::V62; 146 } 147 bool hasV65Ops() const { 148 return getHexagonArchVersion() >= Hexagon::ArchEnum::V65; 149 } 150 bool hasV65OpsOnly() const { 151 return getHexagonArchVersion() == Hexagon::ArchEnum::V65; 152 } 153 154 bool useLongCalls() const { return UseLongCalls; } 155 bool useMemops() const { return UseMemops; } 156 bool usePackets() const { return UsePackets; } 157 bool useNewValueJumps() const { return UseNewValueJumps; } 158 bool useNewValueStores() const { return UseNewValueStores; } 159 bool useSmallData() const { return UseSmallData; } 160 161 bool useHVXOps() const { return HexagonHVXVersion > Hexagon::ArchEnum::V4; } 162 bool useHVX128BOps() const { return useHVXOps() && UseHVX128BOps; } 163 bool useHVX64BOps() const { return useHVXOps() && UseHVX64BOps; } 164 165 bool hasMemNoShuf() const { return HasMemNoShuf; } 166 bool hasReservedR19() const { return ReservedR19; } 167 bool usePredicatedCalls() const; 168 169 bool useBSBScheduling() const { return UseBSBScheduling; } 170 bool enableMachineScheduler() const override; 171 172 // Always use the TargetLowering default scheduler. 173 // FIXME: This will use the vliw scheduler which is probably just hurting 174 // compiler time and will be removed eventually anyway. 175 bool enableMachineSchedDefaultSched() const override { return false; } 176 177 AntiDepBreakMode getAntiDepBreakMode() const override { return ANTIDEP_ALL; } 178 bool enablePostRAScheduler() const override { return true; } 179 180 bool enableSubRegLiveness() const override; 181 182 const std::string &getCPUString () const { return CPUString; } 183 184 const Hexagon::ArchEnum &getHexagonArchVersion() const { 185 return HexagonArchVersion; 186 } 187 188 void getPostRAMutations( 189 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 190 const override; 191 192 void getSMSMutations( 193 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) 194 const override; 195 196 /// Enable use of alias analysis during code generation (during MI 197 /// scheduling, DAGCombine, etc.). 198 bool useAA() const override; 199 200 /// Perform target specific adjustments to the latency of a schedule 201 /// dependency. 202 void adjustSchedDependency(SUnit *def, SUnit *use, SDep& dep) const override; 203 204 unsigned getVectorLength() const { 205 assert(useHVXOps()); 206 if (useHVX64BOps()) 207 return 64; 208 if (useHVX128BOps()) 209 return 128; 210 llvm_unreachable("Invalid HVX vector length settings"); 211 } 212 213 ArrayRef<MVT> getHVXElementTypes() const { 214 static MVT Types[] = { MVT::i8, MVT::i16, MVT::i32 }; 215 return makeArrayRef(Types); 216 } 217 218 bool isHVXVectorType(MVT VecTy, bool IncludeBool = false) const { 219 if (!VecTy.isVector() || !useHVXOps()) 220 return false; 221 MVT ElemTy = VecTy.getVectorElementType(); 222 if (!IncludeBool && ElemTy == MVT::i1) 223 return false; 224 225 unsigned HwLen = getVectorLength(); 226 unsigned NumElems = VecTy.getVectorNumElements(); 227 ArrayRef<MVT> ElemTypes = getHVXElementTypes(); 228 229 if (IncludeBool && ElemTy == MVT::i1) { 230 // Special case for the v512i1, etc. 231 if (8*HwLen == NumElems) 232 return true; 233 // Boolean HVX vector types are formed from regular HVX vector types 234 // by replacing the element type with i1. 235 for (MVT T : ElemTypes) 236 if (NumElems * T.getSizeInBits() == 8*HwLen) 237 return true; 238 return false; 239 } 240 241 unsigned VecWidth = VecTy.getSizeInBits(); 242 if (VecWidth != 8*HwLen && VecWidth != 16*HwLen) 243 return false; 244 return llvm::any_of(ElemTypes, [ElemTy] (MVT T) { return ElemTy == T; }); 245 } 246 247 unsigned getTypeAlignment(MVT Ty) const { 248 if (isHVXVectorType(Ty, true)) 249 return getVectorLength(); 250 return Ty.getSizeInBits() / 8; 251 } 252 253 unsigned getL1CacheLineSize() const; 254 unsigned getL1PrefetchDistance() const; 255 256private: 257 // Helper function responsible for increasing the latency only. 258 void updateLatency(MachineInstr &SrcInst, MachineInstr &DstInst, SDep &Dep) 259 const; 260 void restoreLatency(SUnit *Src, SUnit *Dst) const; 261 void changeLatency(SUnit *Src, SUnit *Dst, unsigned Lat) const; 262 bool isBestZeroLatency(SUnit *Src, SUnit *Dst, const HexagonInstrInfo *TII, 263 SmallSet<SUnit*, 4> &ExclSrc, SmallSet<SUnit*, 4> &ExclDst) const; 264}; 265 266} // end namespace llvm 267 268#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H 269