25 #define DEBUG_TYPE "hexagon-subtarget"
27 #define GET_SUBTARGETINFO_CTOR
28 #define GET_SUBTARGETINFO_TARGET_DESC
29 #include "HexagonGenSubtargetInfo.inc"
33 cl::desc(
"Generate V4 MEMOP in code generation for Hexagon target"));
37 cl::desc(
"Do not generate V4 MEMOP in code generation for Hexagon target"));
41 cl::desc(
"Generate non-chopped conversion from fp to int."));
48 cl::desc(
"Enable Hexagon Double Vector eXtensions"));
52 cl::desc(
"Enable Hexagon Vector eXtensions"));
59 cl::desc(
"Enable the scheduler to generate .cur"));
66 cl::desc(
"Disable Hexagon MI Scheduling"));
70 cl::desc(
"Enable subregister liveness tracking for Hexagon"));
74 cl::desc(
"If present, forces/disables the use of long calls"));
76 void HexagonSubtarget::initializeEnvironment() {
78 ModeIEEERndNear =
false;
86 static std::map<StringRef, HexagonArchEnum> CpuTable {
89 {
"hexagonv55",
V55 },
90 {
"hexagonv60",
V60 },
93 auto foundIt = CpuTable.find(CPUString);
94 if (foundIt != CpuTable.end())
100 UseHVXDblOps =
false;
101 UseLongCalls =
false;
117 InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this),
120 initializeEnvironment();
123 InstrItins = getInstrItineraryForCPU(CPUString);
134 ModeIEEERndNear =
true;
136 ModeIEEERndNear =
false;
143 for (
auto &SU : DAG->
SUnits) {
147 for (
auto &
D : SU.Preds)
148 if (
D.getKind() ==
SDep::Output &&
D.getReg() == Hexagon::USR_OVF)
150 for (
auto &
E : Erase)
154 for (
auto &SU : DAG->
SUnits) {
161 bool IsLoadMI1 = MI1.
mayLoad();
162 if (!QII->isV60VectorInstruction(MI1) || !(IsStoreMI1 || IsLoadMI1))
164 for (
auto &
SI : SU.Succs) {
168 if (!QII->isV60VectorInstruction(MI2))
174 for (
auto &PI :
SI.getSUnit()->Preds) {
175 if (PI.getSUnit() != &SU || PI.getKind() !=
SDep::Order)
178 SI.getSUnit()->setDepthDirty();
187 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
const {
188 Mutations.push_back(make_unique<HexagonSubtarget::HexagonDAGMutation>());
192 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
const {
193 Mutations.push_back(make_unique<HexagonSubtarget::HexagonDAGMutation>());
198 void HexagonSubtarget::anchor() {}
211 void HexagonSubtarget::updateLatency(
MachineInstr &SrcInst,
222 QII.isLateInstrFeedsEarlyInstr(SrcInst, DstInst)) {
228 if (QII.isTC1(SrcInst) || QII.isTC2(SrcInst))
229 if (!QII.isTC1(DstInst) && !QII.isTC2(DstInst))
237 if (
I.isAssignedRegDep() &&
I.getLatency() == 0 &&
238 !
I.getSUnit()->getInstr()->isPseudo())
245 SUnit *Dst,
unsigned Lat)
const {
247 for (
auto &
I : Deps) {
248 if (
I.getSUnit() != Dst)
251 SUnit *UpdateDst =
I.getSUnit();
252 updateLatency(SrcI, *UpdateDst->
getInstr(),
I);
254 for (
auto &PI : UpdateDst->
Preds) {
255 if (PI.getSUnit() != Src || !PI.isAssignedRegDep())
258 updateLatency(SrcI, *UpdateDst->
getInstr(), PI);
267 bool HexagonSubtarget::isBestZeroLatency(
SUnit *Src,
SUnit *Dst,
280 SUnit *Best =
nullptr;
281 SUnit *DstBest =
nullptr;
294 if (Src == SrcBest && Dst == DstBest)
299 if (SrcBest !=
nullptr)
300 changeLatency(SrcBest, SrcBest->
Succs, Dst, 1);
301 if (DstBest !=
nullptr)
302 changeLatency(Src, Src->
Succs, DstBest, 1);
305 if (SrcBest && DstBest)
306 changeLatency(SrcBest, SrcBest->
Succs, DstBest, 0);
339 isBestZeroLatency(Src, Dst, QII)) {
367 changePhiLatency(*SrcInst, Dst, Dep);
374 DstInst = Dst->
Succs[0].getSUnit()->getInstr();
378 isBestZeroLatency(Src, Dst, QII)) {
383 updateLatency(*SrcInst, *DstInst, Dep);
void push_back(const T &Elt)
static SUnit * getZeroLatency(SUnit *N, SmallVector< SDep, 4 > &Deps)
If the SUnit has a zero latency edge, return the other SUnit.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
MachineInstr * getInstr() const
getInstr - Return the representative MachineInstr for this SUnit.
StringRef selectHexagonCPU(const Triple &TT, StringRef CPU)
bool isInstr() const
isInstr - Return true if this SUnit refers to a machine instruction as opposed to an SDNode...
static cl::opt< bool > EnableHexagonHVXDouble("enable-hexagon-hvx-double", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Enable Hexagon Double Vector eXtensions"))
void getSMSMutations(std::vector< std::unique_ptr< ScheduleDAGMutation >> &Mutations) const override
static cl::opt< bool > EnableIEEERndNear("enable-hexagon-ieee-rnd-near", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Generate non-chopped conversion from fp to int."))
bool isAssignedRegDep() const
isAssignedRegDep - Test if this is a Data dependence that is associated with a register.
HexagonSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS)
SmallVector< SDep, 4 > Preds
A register anti-dependedence (aka WAR).
static cl::opt< bool > EnableTCLatencySched("enable-tc-latency-sched", cl::Hidden, cl::ZeroOrMore, cl::init(false))
const HexagonInstrInfo * TII
Kind getKind() const
getKind - Return an enum value representing the kind of the dependence.
unsigned getL1CacheLineSize() const
static cl::opt< bool > OverrideLongCalls("hexagon-long-calls", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("If present, forces/disables the use of long calls"))
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
A register output-dependence (aka WAW).
HexagonSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const TargetMachine &TM)
bool canExecuteInBundle(const MachineInstr &First, const MachineInstr &Second) const
Can these instructions execute at the same time in a bundle.
static cl::opt< bool > DisableMemOps("disable-hexagon-memops", cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed, cl::init(false), cl::desc("Do not generate V4 MEMOP in code generation for Hexagon target"))
static cl::opt< bool > EnableMemOps("enable-hexagon-memops", cl::Hidden, cl::ZeroOrMore, cl::ValueDisallowed, cl::init(true), cl::desc("Generate V4 MEMOP in code generation for Hexagon target"))
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
SDep - Scheduling dependency.
initializer< Ty > init(const Ty &Val)
HexagonArchEnum HexagonArchVersion
const MachineOperand & getOperand(unsigned i) const
static cl::opt< bool > EnableHexagonHVX("enable-hexagon-hvx", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Enable Hexagon Vector eXtensions"))
unsigned getLatency() const
getLatency - Return the latency value for this edge, which roughly means the minimum number of cycles...
static cl::opt< bool > EnableSubregLiveness("hexagon-subreg-liveness", cl::Hidden, cl::ZeroOrMore, cl::init(true), cl::desc("Enable subregister liveness tracking for Hexagon"))
bool isToBeScheduledASAP(const MachineInstr &MI1, const MachineInstr &MI2) const
Any other ordering dependency.
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getL1PrefetchDistance() const
Triple - Helper class for working with autoconf configuration names.
void apply(ScheduleDAGInstrs *DAG) override
bool useBSBScheduling() const
bool enableMachineScheduler() const override
void getPostRAMutations(std::vector< std::unique_ptr< ScheduleDAGMutation >> &Mutations) const override
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool UseBSBScheduling
True if the target should use Back-Skip-Back scheduling.
bool enableSubRegLiveness() const override
void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const override
Perform target specific adjustments to the latency of a schedule dependency.
bool isBoundaryNode() const
Boundary nodes are placeholders for the boundary of the scheduling region.
void setLatency(unsigned Lat)
setLatency - Set the latency for this edge.
ScheduleDAGInstrs - A ScheduleDAG subclass for scheduling lists of MachineInstrs. ...
Representation of each machine instruction.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
static cl::opt< bool > EnableVecFrwdSched("enable-evec-frwd-sched", cl::Hidden, cl::ZeroOrMore, cl::init(true))
const TargetInstrInfo * TII
unsigned getReg() const
getReg - Returns the register number.
const HexagonInstrInfo * getInstrInfo() const override
SmallVector< SDep, 4 > Succs
Primary interface to the complete machine description for the target machine.
static cl::opt< bool > EnableBSBSched("enable-bsb-sched", cl::Hidden, cl::ZeroOrMore, cl::init(true))
StringRef - Represent a constant reference to a string, i.e.
static cl::opt< bool > DisableHexagonMISched("disable-hexagon-misched", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable Hexagon MI Scheduling"))
bool isRegSequence() const
std::vector< SUnit > SUnits
unsigned getReg() const
getReg - Return the register associated with this edge.
SUnit - Scheduling unit. This is a node in the scheduling DAG.
static cl::opt< bool > EnableDotCurSched("enable-cur-sched", cl::Hidden, cl::ZeroOrMore, cl::init(true), cl::desc("Enable the scheduler to generate .cur"))