xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Hexagon/HexagonSubtarget.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- HexagonSubtarget.h - Define Subtarget for the Hexagon ----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares the Hexagon specific subclass of TargetSubtarget.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H
150b57cec5SDimitry Andric 
1681ad6265SDimitry Andric #include "HexagonDepArch.h"
170b57cec5SDimitry Andric #include "HexagonFrameLowering.h"
180b57cec5SDimitry Andric #include "HexagonISelLowering.h"
190b57cec5SDimitry Andric #include "HexagonInstrInfo.h"
200b57cec5SDimitry Andric #include "HexagonRegisterInfo.h"
210b57cec5SDimitry Andric #include "HexagonSelectionDAGInfo.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h"
230b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/ScheduleDAGMutation.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCInstrItineraries.h"
27fe6060f1SDimitry Andric #include "llvm/Support/Alignment.h"
280b57cec5SDimitry Andric #include <memory>
290b57cec5SDimitry Andric #include <string>
300b57cec5SDimitry Andric #include <vector>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric #define GET_SUBTARGETINFO_HEADER
330b57cec5SDimitry Andric #include "HexagonGenSubtargetInfo.inc"
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric namespace llvm {
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric class MachineInstr;
380b57cec5SDimitry Andric class SDep;
390b57cec5SDimitry Andric class SUnit;
400b57cec5SDimitry Andric class TargetMachine;
410b57cec5SDimitry Andric class Triple;
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric class HexagonSubtarget : public HexagonGenSubtargetInfo {
440b57cec5SDimitry Andric   virtual void anchor();
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   bool UseHVX64BOps = false;
470b57cec5SDimitry Andric   bool UseHVX128BOps = false;
480b57cec5SDimitry Andric 
495ffd83dbSDimitry Andric   bool UseAudioOps = false;
505ffd83dbSDimitry Andric   bool UseCompound = false;
510b57cec5SDimitry Andric   bool UseLongCalls = false;
520b57cec5SDimitry Andric   bool UseMemops = false;
530b57cec5SDimitry Andric   bool UsePackets = false;
540b57cec5SDimitry Andric   bool UseNewValueJumps = false;
550b57cec5SDimitry Andric   bool UseNewValueStores = false;
560b57cec5SDimitry Andric   bool UseSmallData = false;
575ffd83dbSDimitry Andric   bool UseUnsafeMath = false;
580b57cec5SDimitry Andric   bool UseZRegOps = false;
590eae32dcSDimitry Andric   bool UseHVXIEEEFPOps = false;
600eae32dcSDimitry Andric   bool UseHVXQFloatOps = false;
610eae32dcSDimitry Andric   bool UseHVXFloatingPoint = false;
620eae32dcSDimitry Andric   bool UseCabac = false;
630b57cec5SDimitry Andric 
645ffd83dbSDimitry Andric   bool HasPreV65 = false;
650b57cec5SDimitry Andric   bool HasMemNoShuf = false;
660b57cec5SDimitry Andric   bool EnableDuplex = false;
670b57cec5SDimitry Andric   bool ReservedR19 = false;
680b57cec5SDimitry Andric   bool NoreturnStackElim = false;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric public:
710b57cec5SDimitry Andric   Hexagon::ArchEnum HexagonArchVersion;
720b57cec5SDimitry Andric   Hexagon::ArchEnum HexagonHVXVersion = Hexagon::ArchEnum::NoArch;
735f757f3fSDimitry Andric   CodeGenOptLevel OptLevel;
740b57cec5SDimitry Andric   /// True if the target should use Back-Skip-Back scheduling. This is the
750b57cec5SDimitry Andric   /// default for V60.
760b57cec5SDimitry Andric   bool UseBSBScheduling;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   struct UsrOverflowMutation : public ScheduleDAGMutation {
790b57cec5SDimitry Andric     void apply(ScheduleDAGInstrs *DAG) override;
800b57cec5SDimitry Andric   };
810b57cec5SDimitry Andric   struct HVXMemLatencyMutation : public ScheduleDAGMutation {
820b57cec5SDimitry Andric     void apply(ScheduleDAGInstrs *DAG) override;
830b57cec5SDimitry Andric   };
840b57cec5SDimitry Andric   struct CallMutation : public ScheduleDAGMutation {
850b57cec5SDimitry Andric     void apply(ScheduleDAGInstrs *DAG) override;
860b57cec5SDimitry Andric   private:
870b57cec5SDimitry Andric     bool shouldTFRICallBind(const HexagonInstrInfo &HII,
880b57cec5SDimitry Andric           const SUnit &Inst1, const SUnit &Inst2) const;
890b57cec5SDimitry Andric   };
900b57cec5SDimitry Andric   struct BankConflictMutation : public ScheduleDAGMutation {
910b57cec5SDimitry Andric     void apply(ScheduleDAGInstrs *DAG) override;
920b57cec5SDimitry Andric   };
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric private:
955ffd83dbSDimitry Andric   enum HexagonProcFamilyEnum { Others, TinyCore };
965ffd83dbSDimitry Andric 
970b57cec5SDimitry Andric   std::string CPUString;
98bdd1243dSDimitry Andric   HexagonProcFamilyEnum HexagonProcFamily = Others;
995ffd83dbSDimitry Andric   Triple TargetTriple;
1005ffd83dbSDimitry Andric 
1015ffd83dbSDimitry Andric   // The following objects can use the TargetTriple, so they must be
1025ffd83dbSDimitry Andric   // declared after it.
1030b57cec5SDimitry Andric   HexagonInstrInfo InstrInfo;
1040b57cec5SDimitry Andric   HexagonRegisterInfo RegInfo;
1050b57cec5SDimitry Andric   HexagonTargetLowering TLInfo;
1060b57cec5SDimitry Andric   HexagonSelectionDAGInfo TSInfo;
1070b57cec5SDimitry Andric   HexagonFrameLowering FrameLowering;
1080b57cec5SDimitry Andric   InstrItineraryData InstrItins;
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric public:
1110b57cec5SDimitry Andric   HexagonSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
1120b57cec5SDimitry Andric                    const TargetMachine &TM);
1130b57cec5SDimitry Andric 
getTargetTriple()1145ffd83dbSDimitry Andric   const Triple &getTargetTriple() const { return TargetTriple; }
isEnvironmentMusl()1155ffd83dbSDimitry Andric   bool isEnvironmentMusl() const {
1165ffd83dbSDimitry Andric     return TargetTriple.getEnvironment() == Triple::Musl;
1175ffd83dbSDimitry Andric   }
1185ffd83dbSDimitry Andric 
1190b57cec5SDimitry Andric   /// getInstrItins - Return the instruction itineraries based on subtarget
1200b57cec5SDimitry Andric   /// selection.
getInstrItineraryData()1210b57cec5SDimitry Andric   const InstrItineraryData *getInstrItineraryData() const override {
1220b57cec5SDimitry Andric     return &InstrItins;
1230b57cec5SDimitry Andric   }
getInstrInfo()1240b57cec5SDimitry Andric   const HexagonInstrInfo *getInstrInfo() const override { return &InstrInfo; }
getRegisterInfo()1250b57cec5SDimitry Andric   const HexagonRegisterInfo *getRegisterInfo() const override {
1260b57cec5SDimitry Andric     return &RegInfo;
1270b57cec5SDimitry Andric   }
getTargetLowering()1280b57cec5SDimitry Andric   const HexagonTargetLowering *getTargetLowering() const override {
1290b57cec5SDimitry Andric     return &TLInfo;
1300b57cec5SDimitry Andric   }
getFrameLowering()1310b57cec5SDimitry Andric   const HexagonFrameLowering *getFrameLowering() const override {
1320b57cec5SDimitry Andric     return &FrameLowering;
1330b57cec5SDimitry Andric   }
getSelectionDAGInfo()1340b57cec5SDimitry Andric   const HexagonSelectionDAGInfo *getSelectionDAGInfo() const override {
1350b57cec5SDimitry Andric     return &TSInfo;
1360b57cec5SDimitry Andric   }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   HexagonSubtarget &initializeSubtargetDependencies(StringRef CPU,
1390b57cec5SDimitry Andric                                                     StringRef FS);
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric   /// ParseSubtargetFeatures - Parses features string setting specified
1420b57cec5SDimitry Andric   /// subtarget options.  Definition of function is auto generated by tblgen.
143e8d8bef9SDimitry Andric   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
1440b57cec5SDimitry Andric 
isXRaySupported()1450eae32dcSDimitry Andric   bool isXRaySupported() const override { return true; }
1460eae32dcSDimitry Andric 
hasV5Ops()1470b57cec5SDimitry Andric   bool hasV5Ops() const {
1480b57cec5SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V5;
1490b57cec5SDimitry Andric   }
hasV5OpsOnly()1500b57cec5SDimitry Andric   bool hasV5OpsOnly() const {
1510b57cec5SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V5;
1520b57cec5SDimitry Andric   }
hasV55Ops()1530b57cec5SDimitry Andric   bool hasV55Ops() const {
1540b57cec5SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V55;
1550b57cec5SDimitry Andric   }
hasV55OpsOnly()1560b57cec5SDimitry Andric   bool hasV55OpsOnly() const {
1570b57cec5SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V55;
1580b57cec5SDimitry Andric   }
hasV60Ops()1590b57cec5SDimitry Andric   bool hasV60Ops() const {
1600b57cec5SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V60;
1610b57cec5SDimitry Andric   }
hasV60OpsOnly()1620b57cec5SDimitry Andric   bool hasV60OpsOnly() const {
1630b57cec5SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V60;
1640b57cec5SDimitry Andric   }
hasV62Ops()1650b57cec5SDimitry Andric   bool hasV62Ops() const {
1660b57cec5SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V62;
1670b57cec5SDimitry Andric   }
hasV62OpsOnly()1680b57cec5SDimitry Andric   bool hasV62OpsOnly() const {
1690b57cec5SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V62;
1700b57cec5SDimitry Andric   }
hasV65Ops()1710b57cec5SDimitry Andric   bool hasV65Ops() const {
1720b57cec5SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V65;
1730b57cec5SDimitry Andric   }
hasV65OpsOnly()1740b57cec5SDimitry Andric   bool hasV65OpsOnly() const {
1750b57cec5SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V65;
1760b57cec5SDimitry Andric   }
hasV66Ops()1770b57cec5SDimitry Andric   bool hasV66Ops() const {
1780b57cec5SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V66;
1790b57cec5SDimitry Andric   }
hasV66OpsOnly()1800b57cec5SDimitry Andric   bool hasV66OpsOnly() const {
1810b57cec5SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V66;
1820b57cec5SDimitry Andric   }
hasV67Ops()1835ffd83dbSDimitry Andric   bool hasV67Ops() const {
1845ffd83dbSDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V67;
1855ffd83dbSDimitry Andric   }
hasV67OpsOnly()1865ffd83dbSDimitry Andric   bool hasV67OpsOnly() const {
1875ffd83dbSDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V67;
1885ffd83dbSDimitry Andric   }
hasV68Ops()189fe6060f1SDimitry Andric   bool hasV68Ops() const {
190fe6060f1SDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V68;
191fe6060f1SDimitry Andric   }
hasV68OpsOnly()192fe6060f1SDimitry Andric   bool hasV68OpsOnly() const {
193fe6060f1SDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V68;
194fe6060f1SDimitry Andric   }
hasV69Ops()1950eae32dcSDimitry Andric   bool hasV69Ops() const {
1960eae32dcSDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V69;
1970eae32dcSDimitry Andric   }
hasV69OpsOnly()1980eae32dcSDimitry Andric   bool hasV69OpsOnly() const {
1990eae32dcSDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V69;
2000eae32dcSDimitry Andric   }
hasV71Ops()201bdd1243dSDimitry Andric   bool hasV71Ops() const {
202bdd1243dSDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V71;
203bdd1243dSDimitry Andric   }
hasV71OpsOnly()204bdd1243dSDimitry Andric   bool hasV71OpsOnly() const {
205bdd1243dSDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V71;
206bdd1243dSDimitry Andric   }
hasV73Ops()207bdd1243dSDimitry Andric   bool hasV73Ops() const {
208bdd1243dSDimitry Andric     return getHexagonArchVersion() >= Hexagon::ArchEnum::V73;
209bdd1243dSDimitry Andric   }
hasV73OpsOnly()210bdd1243dSDimitry Andric   bool hasV73OpsOnly() const {
211bdd1243dSDimitry Andric     return getHexagonArchVersion() == Hexagon::ArchEnum::V73;
212bdd1243dSDimitry Andric   }
2130b57cec5SDimitry Andric 
useAudioOps()2145ffd83dbSDimitry Andric   bool useAudioOps() const { return UseAudioOps; }
useCompound()2155ffd83dbSDimitry Andric   bool useCompound() const { return UseCompound; }
useLongCalls()2160b57cec5SDimitry Andric   bool useLongCalls() const { return UseLongCalls; }
useMemops()2170b57cec5SDimitry Andric   bool useMemops() const { return UseMemops; }
usePackets()2180b57cec5SDimitry Andric   bool usePackets() const { return UsePackets; }
useNewValueJumps()2190b57cec5SDimitry Andric   bool useNewValueJumps() const { return UseNewValueJumps; }
useNewValueStores()2200b57cec5SDimitry Andric   bool useNewValueStores() const { return UseNewValueStores; }
useSmallData()2210b57cec5SDimitry Andric   bool useSmallData() const { return UseSmallData; }
useUnsafeMath()2225ffd83dbSDimitry Andric   bool useUnsafeMath() const { return UseUnsafeMath; }
useZRegOps()2230b57cec5SDimitry Andric   bool useZRegOps() const { return UseZRegOps; }
useCabac()2240eae32dcSDimitry Andric   bool useCabac() const { return UseCabac; }
2250b57cec5SDimitry Andric 
isTinyCore()2265ffd83dbSDimitry Andric   bool isTinyCore() const { return HexagonProcFamily == TinyCore; }
isTinyCoreWithDuplex()2275ffd83dbSDimitry Andric   bool isTinyCoreWithDuplex() const { return isTinyCore() && EnableDuplex; }
2285ffd83dbSDimitry Andric 
useHVXIEEEFPOps()2290eae32dcSDimitry Andric   bool useHVXIEEEFPOps() const { return UseHVXIEEEFPOps && useHVXOps(); }
useHVXQFloatOps()2300eae32dcSDimitry Andric   bool useHVXQFloatOps() const {
2310eae32dcSDimitry Andric     return UseHVXQFloatOps && HexagonHVXVersion >= Hexagon::ArchEnum::V68;
2320eae32dcSDimitry Andric   }
useHVXFloatingPoint()2330eae32dcSDimitry Andric   bool useHVXFloatingPoint() const { return UseHVXFloatingPoint; }
useHVXOps()2340b57cec5SDimitry Andric   bool useHVXOps() const {
2350b57cec5SDimitry Andric     return HexagonHVXVersion > Hexagon::ArchEnum::NoArch;
2360b57cec5SDimitry Andric   }
useHVXV60Ops()2375ffd83dbSDimitry Andric   bool useHVXV60Ops() const {
2385ffd83dbSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V60;
2395ffd83dbSDimitry Andric   }
useHVXV62Ops()2405ffd83dbSDimitry Andric   bool useHVXV62Ops() const {
2415ffd83dbSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V62;
2425ffd83dbSDimitry Andric   }
useHVXV65Ops()2435ffd83dbSDimitry Andric   bool useHVXV65Ops() const {
2445ffd83dbSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V65;
2455ffd83dbSDimitry Andric   }
useHVXV66Ops()2465ffd83dbSDimitry Andric   bool useHVXV66Ops() const {
2475ffd83dbSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V66;
2485ffd83dbSDimitry Andric   }
useHVXV67Ops()2495ffd83dbSDimitry Andric   bool useHVXV67Ops() const {
2505ffd83dbSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V67;
2515ffd83dbSDimitry Andric   }
useHVXV68Ops()252fe6060f1SDimitry Andric   bool useHVXV68Ops() const {
253fe6060f1SDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V68;
254fe6060f1SDimitry Andric   }
useHVXV69Ops()2550eae32dcSDimitry Andric   bool useHVXV69Ops() const {
2560eae32dcSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V69;
2570eae32dcSDimitry Andric   }
useHVXV71Ops()258bdd1243dSDimitry Andric   bool useHVXV71Ops() const {
259bdd1243dSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V71;
260bdd1243dSDimitry Andric   }
useHVXV73Ops()261bdd1243dSDimitry Andric   bool useHVXV73Ops() const {
262bdd1243dSDimitry Andric     return HexagonHVXVersion >= Hexagon::ArchEnum::V73;
263bdd1243dSDimitry Andric   }
useHVX128BOps()2640b57cec5SDimitry Andric   bool useHVX128BOps() const { return useHVXOps() && UseHVX128BOps; }
useHVX64BOps()2650b57cec5SDimitry Andric   bool useHVX64BOps() const { return useHVXOps() && UseHVX64BOps; }
2660b57cec5SDimitry Andric 
hasMemNoShuf()2670b57cec5SDimitry Andric   bool hasMemNoShuf() const { return HasMemNoShuf; }
hasReservedR19()2680b57cec5SDimitry Andric   bool hasReservedR19() const { return ReservedR19; }
2690b57cec5SDimitry Andric   bool usePredicatedCalls() const;
2700b57cec5SDimitry Andric 
noreturnStackElim()2710b57cec5SDimitry Andric   bool noreturnStackElim() const { return NoreturnStackElim; }
2720b57cec5SDimitry Andric 
useBSBScheduling()2730b57cec5SDimitry Andric   bool useBSBScheduling() const { return UseBSBScheduling; }
2740b57cec5SDimitry Andric   bool enableMachineScheduler() const override;
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric   // Always use the TargetLowering default scheduler.
2770b57cec5SDimitry Andric   // FIXME: This will use the vliw scheduler which is probably just hurting
2780b57cec5SDimitry Andric   // compiler time and will be removed eventually anyway.
enableMachineSchedDefaultSched()2790b57cec5SDimitry Andric   bool enableMachineSchedDefaultSched() const override { return false; }
2800b57cec5SDimitry Andric 
2815ffd83dbSDimitry Andric   // For use with PostRAScheduling: get the anti-dependence breaking that should
2825ffd83dbSDimitry Andric   // be performed before post-RA scheduling.
getAntiDepBreakMode()2830b57cec5SDimitry Andric   AntiDepBreakMode getAntiDepBreakMode() const override { return ANTIDEP_ALL; }
2845ffd83dbSDimitry Andric   /// True if the subtarget should run a scheduler after register
2855ffd83dbSDimitry Andric   /// allocation.
enablePostRAScheduler()2860b57cec5SDimitry Andric   bool enablePostRAScheduler() const override { return true; }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   bool enableSubRegLiveness() const override;
2890b57cec5SDimitry Andric 
getCPUString()2900b57cec5SDimitry Andric   const std::string &getCPUString () const { return CPUString; }
2910b57cec5SDimitry Andric 
getHexagonArchVersion()2920b57cec5SDimitry Andric   const Hexagon::ArchEnum &getHexagonArchVersion() const {
2930b57cec5SDimitry Andric     return HexagonArchVersion;
2940b57cec5SDimitry Andric   }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   void getPostRAMutations(
2970b57cec5SDimitry Andric       std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
2980b57cec5SDimitry Andric       const override;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   void getSMSMutations(
3010b57cec5SDimitry Andric       std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
3020b57cec5SDimitry Andric       const override;
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   /// Enable use of alias analysis during code generation (during MI
3050b57cec5SDimitry Andric   /// scheduling, DAGCombine, etc.).
3060b57cec5SDimitry Andric   bool useAA() const override;
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   /// Perform target specific adjustments to the latency of a schedule
3090b57cec5SDimitry Andric   /// dependency.
3105ffd83dbSDimitry Andric   void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
311*0fca6ea1SDimitry Andric                              SDep &Dep,
312*0fca6ea1SDimitry Andric                              const TargetSchedModel *SchedModel) const override;
3130b57cec5SDimitry Andric 
getVectorLength()3140b57cec5SDimitry Andric   unsigned getVectorLength() const {
3150b57cec5SDimitry Andric     assert(useHVXOps());
3160b57cec5SDimitry Andric     if (useHVX64BOps())
3170b57cec5SDimitry Andric       return 64;
3180b57cec5SDimitry Andric     if (useHVX128BOps())
3190b57cec5SDimitry Andric       return 128;
3200b57cec5SDimitry Andric     llvm_unreachable("Invalid HVX vector length settings");
3210b57cec5SDimitry Andric   }
3220b57cec5SDimitry Andric 
getHVXElementTypes()3230b57cec5SDimitry Andric   ArrayRef<MVT> getHVXElementTypes() const {
3240b57cec5SDimitry Andric     static MVT Types[] = {MVT::i8, MVT::i16, MVT::i32};
3250eae32dcSDimitry Andric     static MVT TypesV68[] = {MVT::i8, MVT::i16, MVT::i32, MVT::f16, MVT::f32};
3260eae32dcSDimitry Andric 
3270eae32dcSDimitry Andric     if (useHVXV68Ops() && useHVXFloatingPoint())
328bdd1243dSDimitry Andric       return ArrayRef(TypesV68);
329bdd1243dSDimitry Andric     return ArrayRef(Types);
3300b57cec5SDimitry Andric   }
3310b57cec5SDimitry Andric 
332e8d8bef9SDimitry Andric   bool isHVXElementType(MVT Ty, bool IncludeBool = false) const;
333bdd1243dSDimitry Andric   bool isHVXVectorType(EVT VecTy, bool IncludeBool = false) const;
334e8d8bef9SDimitry Andric   bool isTypeForHVX(Type *VecTy, bool IncludeBool = false) const;
3350b57cec5SDimitry Andric 
getTypeAlignment(MVT Ty)336fe6060f1SDimitry Andric   Align getTypeAlignment(MVT Ty) const {
3370b57cec5SDimitry Andric     if (isHVXVectorType(Ty, true))
338fe6060f1SDimitry Andric       return Align(getVectorLength());
339fe6060f1SDimitry Andric     return Align(std::max<unsigned>(1, Ty.getSizeInBits() / 8));
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   unsigned getL1CacheLineSize() const;
3430b57cec5SDimitry Andric   unsigned getL1PrefetchDistance() const;
3440b57cec5SDimitry Andric 
345bdd1243dSDimitry Andric   Intrinsic::ID getIntrinsicId(unsigned Opc) const;
346bdd1243dSDimitry Andric 
3470b57cec5SDimitry Andric private:
3480b57cec5SDimitry Andric   // Helper function responsible for increasing the latency only.
34904eeddc0SDimitry Andric   int updateLatency(MachineInstr &SrcInst, MachineInstr &DstInst,
35004eeddc0SDimitry Andric                     bool IsArtificial, int Latency) const;
3510b57cec5SDimitry Andric   void restoreLatency(SUnit *Src, SUnit *Dst) const;
3520b57cec5SDimitry Andric   void changeLatency(SUnit *Src, SUnit *Dst, unsigned Lat) const;
3530b57cec5SDimitry Andric   bool isBestZeroLatency(SUnit *Src, SUnit *Dst, const HexagonInstrInfo *TII,
3540b57cec5SDimitry Andric       SmallSet<SUnit*, 4> &ExclSrc, SmallSet<SUnit*, 4> &ExclDst) const;
3550b57cec5SDimitry Andric };
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric } // end namespace llvm
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H
360