LLVM  16.0.0git
HexagonSubtarget.cpp
Go to the documentation of this file.
1 //===- HexagonSubtarget.cpp - Hexagon Subtarget Information ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Hexagon specific subclass of TargetSubtarget.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "HexagonSubtarget.h"
14 #include "Hexagon.h"
15 #include "HexagonInstrInfo.h"
16 #include "HexagonRegisterInfo.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/SmallSet.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
27 #include "llvm/IR/IntrinsicsHexagon.h"
31 #include <algorithm>
32 #include <cassert>
33 #include <map>
34 
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "hexagon-subtarget"
38 
39 #define GET_SUBTARGETINFO_CTOR
40 #define GET_SUBTARGETINFO_TARGET_DESC
41 #include "HexagonGenSubtargetInfo.inc"
42 
43 static cl::opt<bool> EnableBSBSched("enable-bsb-sched", cl::Hidden,
44  cl::init(true));
45 
46 static cl::opt<bool> EnableTCLatencySched("enable-tc-latency-sched", cl::Hidden,
47  cl::init(false));
48 
49 static cl::opt<bool>
50  EnableDotCurSched("enable-cur-sched", cl::Hidden, cl::init(true),
51  cl::desc("Enable the scheduler to generate .cur"));
52 
53 static cl::opt<bool>
54  DisableHexagonMISched("disable-hexagon-misched", cl::Hidden,
55  cl::desc("Disable Hexagon MI Scheduling"));
56 
58  "hexagon-subreg-liveness", cl::Hidden, cl::init(true),
59  cl::desc("Enable subregister liveness tracking for Hexagon"));
60 
62  "hexagon-long-calls", cl::Hidden,
63  cl::desc("If present, forces/disables the use of long calls"));
64 
65 static cl::opt<bool>
66  EnablePredicatedCalls("hexagon-pred-calls", cl::Hidden,
67  cl::desc("Consider calls to be predicable"));
68 
69 static cl::opt<bool> SchedPredsCloser("sched-preds-closer", cl::Hidden,
70  cl::init(true));
71 
72 static cl::opt<bool> SchedRetvalOptimization("sched-retval-optimization",
73  cl::Hidden, cl::init(true));
74 
76  "hexagon-check-bank-conflict", cl::Hidden, cl::init(true),
77  cl::desc("Enable checking for cache bank conflicts"));
78 
80  StringRef FS, const TargetMachine &TM)
81  : HexagonGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
82  OptLevel(TM.getOptLevel()),
83  CPUString(std::string(Hexagon_MC::selectHexagonCPU(CPU))),
84  TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)),
85  RegInfo(getHwMode()), TLInfo(TM, *this),
86  InstrItins(getInstrItineraryForCPU(CPUString)) {
88  // Beware of the default constructor of InstrItineraryData: it will
89  // reset all members to 0.
90  assert(InstrItins.Itineraries != nullptr && "InstrItins not initialized");
91 }
92 
95  Optional<Hexagon::ArchEnum> ArchVer = Hexagon::getCpu(CPUString);
96  if (ArchVer)
97  HexagonArchVersion = *ArchVer;
98  else
99  llvm_unreachable("Unrecognized Hexagon processor version");
100 
101  UseHVX128BOps = false;
102  UseHVX64BOps = false;
103  UseAudioOps = false;
104  UseLongCalls = false;
105 
106  SubtargetFeatures Features(FS);
107 
108  // Turn on QFloat if the HVX version is v68+.
109  // The function ParseSubtargetFeatures will set feature bits and initialize
110  // subtarget's variables all in one, so there isn't a good way to preprocess
111  // the feature string, other than by tinkering with it directly.
112  auto IsQFloatFS = [](StringRef F) {
113  return F == "+hvx-qfloat" || F == "-hvx-qfloat";
114  };
115  if (!llvm::count_if(Features.getFeatures(), IsQFloatFS)) {
116  auto getHvxVersion = [&Features](StringRef FS) -> StringRef {
117  for (StringRef F : llvm::reverse(Features.getFeatures())) {
118  if (F.startswith("+hvxv"))
119  return F;
120  }
121  for (StringRef F : llvm::reverse(Features.getFeatures())) {
122  if (F == "-hvx")
123  return StringRef();
124  if (F.startswith("+hvx") || F == "-hvx")
125  return F.take_front(4); // Return "+hvx" or "-hvx".
126  }
127  return StringRef();
128  };
129 
130  bool AddQFloat = false;
131  StringRef HvxVer = getHvxVersion(FS);
132  if (HvxVer.startswith("+hvxv")) {
133  int Ver = 0;
134  if (!HvxVer.drop_front(5).consumeInteger(10, Ver) && Ver >= 68)
135  AddQFloat = true;
136  } else if (HvxVer == "+hvx") {
137  if (hasV68Ops())
138  AddQFloat = true;
139  }
140 
141  if (AddQFloat)
142  Features.AddFeature("+hvx-qfloat");
143  }
144 
145  std::string FeatureString = Features.getString();
146  ParseSubtargetFeatures(CPUString, /*TuneCPU*/ CPUString, FeatureString);
147 
148  if (useHVXV68Ops())
149  UseHVXFloatingPoint = UseHVXIEEEFPOps || UseHVXQFloatOps;
150 
151  if (UseHVXQFloatOps && UseHVXIEEEFPOps && UseHVXFloatingPoint)
152  LLVM_DEBUG(
153  dbgs() << "Behavior is undefined for simultaneous qfloat and ieee hvx codegen...");
154 
156  UseLongCalls = OverrideLongCalls;
157 
159 
160  if (isTinyCore()) {
161  // Tiny core has a single thread, so back-to-back scheduling is enabled by
162  // default.
164  UseBSBScheduling = false;
165  }
166 
167  FeatureBitset FeatureBits = getFeatureBits();
169  setFeatureBits(FeatureBits.reset(Hexagon::FeatureDuplex));
170  setFeatureBits(Hexagon_MC::completeHVXFeatures(FeatureBits));
171 
172  return *this;
173 }
174 
175 bool HexagonSubtarget::isHVXElementType(MVT Ty, bool IncludeBool) const {
176  if (!useHVXOps())
177  return false;
178  if (Ty.isVector())
179  Ty = Ty.getVectorElementType();
180  if (IncludeBool && Ty == MVT::i1)
181  return true;
182  ArrayRef<MVT> ElemTypes = getHVXElementTypes();
183  return llvm::is_contained(ElemTypes, Ty);
184 }
185 
186 bool HexagonSubtarget::isHVXVectorType(EVT VecTy, bool IncludeBool) const {
187  if (!VecTy.isSimple())
188  return false;
189  if (!VecTy.isVector() || !useHVXOps() || VecTy.isScalableVector())
190  return false;
191  MVT ElemTy = VecTy.getSimpleVT().getVectorElementType();
192  if (!IncludeBool && ElemTy == MVT::i1)
193  return false;
194 
195  unsigned HwLen = getVectorLength();
196  unsigned NumElems = VecTy.getVectorNumElements();
197  ArrayRef<MVT> ElemTypes = getHVXElementTypes();
198 
199  if (IncludeBool && ElemTy == MVT::i1) {
200  // Boolean HVX vector types are formed from regular HVX vector types
201  // by replacing the element type with i1.
202  for (MVT T : ElemTypes)
203  if (NumElems * T.getSizeInBits() == 8 * HwLen)
204  return true;
205  return false;
206  }
207 
208  unsigned VecWidth = VecTy.getSizeInBits();
209  if (VecWidth != 8 * HwLen && VecWidth != 16 * HwLen)
210  return false;
211  return llvm::is_contained(ElemTypes, ElemTy);
212 }
213 
214 bool HexagonSubtarget::isTypeForHVX(Type *VecTy, bool IncludeBool) const {
215  if (!VecTy->isVectorTy() || isa<ScalableVectorType>(VecTy))
216  return false;
217  // Avoid types like <2 x i32*>.
218  Type *ScalTy = VecTy->getScalarType();
219  if (!ScalTy->isIntegerTy() &&
220  !(ScalTy->isFloatingPointTy() && useHVXFloatingPoint()))
221  return false;
222  // The given type may be something like <17 x i32>, which is not MVT,
223  // but can be represented as (non-simple) EVT.
224  EVT Ty = EVT::getEVT(VecTy, /*HandleUnknown*/false);
225  if (!Ty.getVectorElementType().isSimple())
226  return false;
227 
228  auto isHvxTy = [this, IncludeBool](MVT SimpleTy) {
229  if (isHVXVectorType(SimpleTy, IncludeBool))
230  return true;
231  auto Action = getTargetLowering()->getPreferredVectorAction(SimpleTy);
232  return Action == TargetLoweringBase::TypeWidenVector;
233  };
234 
235  // Round up EVT to have power-of-2 elements, and keep checking if it
236  // qualifies for HVX, dividing it in half after each step.
237  MVT ElemTy = Ty.getVectorElementType().getSimpleVT();
238  unsigned VecLen = PowerOf2Ceil(Ty.getVectorNumElements());
239  while (VecLen > 1) {
240  MVT SimpleTy = MVT::getVectorVT(ElemTy, VecLen);
241  if (SimpleTy.isValid() && isHvxTy(SimpleTy))
242  return true;
243  VecLen /= 2;
244  }
245 
246  return false;
247 }
248 
250  for (SUnit &SU : DAG->SUnits) {
251  if (!SU.isInstr())
252  continue;
253  SmallVector<SDep, 4> Erase;
254  for (auto &D : SU.Preds)
255  if (D.getKind() == SDep::Output && D.getReg() == Hexagon::USR_OVF)
256  Erase.push_back(D);
257  for (auto &E : Erase)
258  SU.removePred(E);
259  }
260 }
261 
263  for (SUnit &SU : DAG->SUnits) {
264  // Update the latency of chain edges between v60 vector load or store
265  // instructions to be 1. These instruction cannot be scheduled in the
266  // same packet.
267  MachineInstr &MI1 = *SU.getInstr();
268  auto *QII = static_cast<const HexagonInstrInfo*>(DAG->TII);
269  bool IsStoreMI1 = MI1.mayStore();
270  bool IsLoadMI1 = MI1.mayLoad();
271  if (!QII->isHVXVec(MI1) || !(IsStoreMI1 || IsLoadMI1))
272  continue;
273  for (SDep &SI : SU.Succs) {
274  if (SI.getKind() != SDep::Order || SI.getLatency() != 0)
275  continue;
276  MachineInstr &MI2 = *SI.getSUnit()->getInstr();
277  if (!QII->isHVXVec(MI2))
278  continue;
279  if ((IsStoreMI1 && MI2.mayStore()) || (IsLoadMI1 && MI2.mayLoad())) {
280  SI.setLatency(1);
281  SU.setHeightDirty();
282  // Change the dependence in the opposite direction too.
283  for (SDep &PI : SI.getSUnit()->Preds) {
284  if (PI.getSUnit() != &SU || PI.getKind() != SDep::Order)
285  continue;
286  PI.setLatency(1);
287  SI.getSUnit()->setDepthDirty();
288  }
289  }
290  }
291  }
292 }
293 
294 // Check if a call and subsequent A2_tfrpi instructions should maintain
295 // scheduling affinity. We are looking for the TFRI to be consumed in
296 // the next instruction. This should help reduce the instances of
297 // double register pairs being allocated and scheduled before a call
298 // when not used until after the call. This situation is exacerbated
299 // by the fact that we allocate the pair from the callee saves list,
300 // leading to excess spills and restores.
301 bool HexagonSubtarget::CallMutation::shouldTFRICallBind(
302  const HexagonInstrInfo &HII, const SUnit &Inst1,
303  const SUnit &Inst2) const {
304  if (Inst1.getInstr()->getOpcode() != Hexagon::A2_tfrpi)
305  return false;
306 
307  // TypeXTYPE are 64 bit operations.
308  unsigned Type = HII.getType(*Inst2.getInstr());
311 }
312 
314  ScheduleDAGMI *DAG = static_cast<ScheduleDAGMI*>(DAGInstrs);
315  SUnit* LastSequentialCall = nullptr;
316  // Map from virtual register to physical register from the copy.
317  DenseMap<unsigned, unsigned> VRegHoldingReg;
318  // Map from the physical register to the instruction that uses virtual
319  // register. This is used to create the barrier edge.
320  DenseMap<unsigned, SUnit *> LastVRegUse;
321  auto &TRI = *DAG->MF.getSubtarget().getRegisterInfo();
322  auto &HII = *DAG->MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
323 
324  // Currently we only catch the situation when compare gets scheduled
325  // before preceding call.
326  for (unsigned su = 0, e = DAG->SUnits.size(); su != e; ++su) {
327  // Remember the call.
328  if (DAG->SUnits[su].getInstr()->isCall())
329  LastSequentialCall = &DAG->SUnits[su];
330  // Look for a compare that defines a predicate.
331  else if (DAG->SUnits[su].getInstr()->isCompare() && LastSequentialCall)
332  DAG->addEdge(&DAG->SUnits[su], SDep(LastSequentialCall, SDep::Barrier));
333  // Look for call and tfri* instructions.
334  else if (SchedPredsCloser && LastSequentialCall && su > 1 && su < e-1 &&
335  shouldTFRICallBind(HII, DAG->SUnits[su], DAG->SUnits[su+1]))
336  DAG->addEdge(&DAG->SUnits[su], SDep(&DAG->SUnits[su-1], SDep::Barrier));
337  // Prevent redundant register copies due to reads and writes of physical
338  // registers. The original motivation for this was the code generated
339  // between two calls, which are caused both the return value and the
340  // argument for the next call being in %r0.
341  // Example:
342  // 1: <call1>
343  // 2: %vreg = COPY %r0
344  // 3: <use of %vreg>
345  // 4: %r0 = ...
346  // 5: <call2>
347  // The scheduler would often swap 3 and 4, so an additional register is
348  // needed. This code inserts a Barrier dependence between 3 & 4 to prevent
349  // this.
350  // The code below checks for all the physical registers, not just R0/D0/V0.
351  else if (SchedRetvalOptimization) {
352  const MachineInstr *MI = DAG->SUnits[su].getInstr();
353  if (MI->isCopy() &&
354  Register::isPhysicalRegister(MI->getOperand(1).getReg())) {
355  // %vregX = COPY %r0
356  VRegHoldingReg[MI->getOperand(0).getReg()] = MI->getOperand(1).getReg();
357  LastVRegUse.erase(MI->getOperand(1).getReg());
358  } else {
359  for (const MachineOperand &MO : MI->operands()) {
360  if (!MO.isReg())
361  continue;
362  if (MO.isUse() && !MI->isCopy() &&
363  VRegHoldingReg.count(MO.getReg())) {
364  // <use of %vregX>
365  LastVRegUse[VRegHoldingReg[MO.getReg()]] = &DAG->SUnits[su];
366  } else if (MO.isDef() && Register::isPhysicalRegister(MO.getReg())) {
367  for (MCRegAliasIterator AI(MO.getReg(), &TRI, true); AI.isValid();
368  ++AI) {
369  if (LastVRegUse.count(*AI) &&
370  LastVRegUse[*AI] != &DAG->SUnits[su])
371  // %r0 = ...
372  DAG->addEdge(&DAG->SUnits[su], SDep(LastVRegUse[*AI], SDep::Barrier));
373  LastVRegUse.erase(*AI);
374  }
375  }
376  }
377  }
378  }
379  }
380 }
381 
384  return;
385 
386  const auto &HII = static_cast<const HexagonInstrInfo&>(*DAG->TII);
387 
388  // Create artificial edges between loads that could likely cause a bank
389  // conflict. Since such loads would normally not have any dependency
390  // between them, we cannot rely on existing edges.
391  for (unsigned i = 0, e = DAG->SUnits.size(); i != e; ++i) {
392  SUnit &S0 = DAG->SUnits[i];
393  MachineInstr &L0 = *S0.getInstr();
394  if (!L0.mayLoad() || L0.mayStore() ||
396  continue;
397  int64_t Offset0;
398  unsigned Size0;
399  MachineOperand *BaseOp0 = HII.getBaseAndOffset(L0, Offset0, Size0);
400  // Is the access size is longer than the L1 cache line, skip the check.
401  if (BaseOp0 == nullptr || !BaseOp0->isReg() || Size0 >= 32)
402  continue;
403  // Scan only up to 32 instructions ahead (to avoid n^2 complexity).
404  for (unsigned j = i+1, m = std::min(i+32, e); j != m; ++j) {
405  SUnit &S1 = DAG->SUnits[j];
406  MachineInstr &L1 = *S1.getInstr();
407  if (!L1.mayLoad() || L1.mayStore() ||
409  continue;
410  int64_t Offset1;
411  unsigned Size1;
412  MachineOperand *BaseOp1 = HII.getBaseAndOffset(L1, Offset1, Size1);
413  if (BaseOp1 == nullptr || !BaseOp1->isReg() || Size1 >= 32 ||
414  BaseOp0->getReg() != BaseOp1->getReg())
415  continue;
416  // Check bits 3 and 4 of the offset: if they differ, a bank conflict
417  // is unlikely.
418  if (((Offset0 ^ Offset1) & 0x18) != 0)
419  continue;
420  // Bits 3 and 4 are the same, add an artificial edge and set extra
421  // latency.
422  SDep A(&S0, SDep::Artificial);
423  A.setLatency(1);
424  S1.addPred(A, true);
425  }
426  }
427 }
428 
429 /// Enable use of alias analysis during code generation (during MI
430 /// scheduling, DAGCombine, etc.).
432  if (OptLevel != CodeGenOpt::None)
433  return true;
434  return false;
435 }
436 
437 /// Perform target specific adjustments to the latency of a schedule
438 /// dependency.
440  SUnit *Dst, int DstOpIdx,
441  SDep &Dep) const {
442  if (!Src->isInstr() || !Dst->isInstr())
443  return;
444 
445  MachineInstr *SrcInst = Src->getInstr();
446  MachineInstr *DstInst = Dst->getInstr();
447  const HexagonInstrInfo *QII = getInstrInfo();
448 
449  // Instructions with .new operands have zero latency.
450  SmallSet<SUnit *, 4> ExclSrc;
451  SmallSet<SUnit *, 4> ExclDst;
452  if (QII->canExecuteInBundle(*SrcInst, *DstInst) &&
453  isBestZeroLatency(Src, Dst, QII, ExclSrc, ExclDst)) {
454  Dep.setLatency(0);
455  return;
456  }
457 
458  // Set the latency for a copy to zero since we hope that is will get
459  // removed.
460  if (DstInst->isCopy())
461  Dep.setLatency(0);
462 
463  // If it's a REG_SEQUENCE/COPY, use its destination instruction to determine
464  // the correct latency.
465  // If there are multiple uses of the def of COPY/REG_SEQUENCE, set the latency
466  // only if the latencies on all the uses are equal, otherwise set it to
467  // default.
468  if ((DstInst->isRegSequence() || DstInst->isCopy())) {
469  Register DReg = DstInst->getOperand(0).getReg();
470  int DLatency = -1;
471  for (const auto &DDep : Dst->Succs) {
472  MachineInstr *DDst = DDep.getSUnit()->getInstr();
473  int UseIdx = -1;
474  for (unsigned OpNum = 0; OpNum < DDst->getNumOperands(); OpNum++) {
475  const MachineOperand &MO = DDst->getOperand(OpNum);
476  if (MO.isReg() && MO.getReg() && MO.isUse() && MO.getReg() == DReg) {
477  UseIdx = OpNum;
478  break;
479  }
480  }
481 
482  if (UseIdx == -1)
483  continue;
484 
485  int Latency = (InstrInfo.getOperandLatency(&InstrItins, *SrcInst, 0,
486  *DDst, UseIdx));
487  // Set DLatency for the first time.
488  DLatency = (DLatency == -1) ? Latency : DLatency;
489 
490  // For multiple uses, if the Latency is different across uses, reset
491  // DLatency.
492  if (DLatency != Latency) {
493  DLatency = -1;
494  break;
495  }
496  }
497 
498  DLatency = std::max(DLatency, 0);
499  Dep.setLatency((unsigned)DLatency);
500  }
501 
502  // Try to schedule uses near definitions to generate .cur.
503  ExclSrc.clear();
504  ExclDst.clear();
505  if (EnableDotCurSched && QII->isToBeScheduledASAP(*SrcInst, *DstInst) &&
506  isBestZeroLatency(Src, Dst, QII, ExclSrc, ExclDst)) {
507  Dep.setLatency(0);
508  return;
509  }
510  int Latency = Dep.getLatency();
511  bool IsArtificial = Dep.isArtificial();
512  Latency = updateLatency(*SrcInst, *DstInst, IsArtificial, Latency);
513  Dep.setLatency(Latency);
514 }
515 
517  std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
518  Mutations.push_back(std::make_unique<UsrOverflowMutation>());
519  Mutations.push_back(std::make_unique<HVXMemLatencyMutation>());
520  Mutations.push_back(std::make_unique<BankConflictMutation>());
521 }
522 
524  std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
525  Mutations.push_back(std::make_unique<UsrOverflowMutation>());
526  Mutations.push_back(std::make_unique<HVXMemLatencyMutation>());
527 }
528 
529 // Pin the vtable to this file.
530 void HexagonSubtarget::anchor() {}
531 
534  return !DisableHexagonMISched;
535  return true;
536 }
537 
539  return EnablePredicatedCalls;
540 }
541 
542 int HexagonSubtarget::updateLatency(MachineInstr &SrcInst,
543  MachineInstr &DstInst, bool IsArtificial,
544  int Latency) const {
545  if (IsArtificial)
546  return 1;
547  if (!hasV60Ops())
548  return Latency;
549 
550  auto &QII = static_cast<const HexagonInstrInfo &>(*getInstrInfo());
551  // BSB scheduling.
552  if (QII.isHVXVec(SrcInst) || useBSBScheduling())
553  Latency = (Latency + 1) >> 1;
554  return Latency;
555 }
556 
557 void HexagonSubtarget::restoreLatency(SUnit *Src, SUnit *Dst) const {
558  MachineInstr *SrcI = Src->getInstr();
559  for (auto &I : Src->Succs) {
560  if (!I.isAssignedRegDep() || I.getSUnit() != Dst)
561  continue;
562  Register DepR = I.getReg();
563  int DefIdx = -1;
564  for (unsigned OpNum = 0; OpNum < SrcI->getNumOperands(); OpNum++) {
565  const MachineOperand &MO = SrcI->getOperand(OpNum);
566  bool IsSameOrSubReg = false;
567  if (MO.isReg()) {
568  Register MOReg = MO.getReg();
569  if (DepR.isVirtual()) {
570  IsSameOrSubReg = (MOReg == DepR);
571  } else {
572  IsSameOrSubReg = getRegisterInfo()->isSubRegisterEq(DepR, MOReg);
573  }
574  if (MO.isDef() && IsSameOrSubReg)
575  DefIdx = OpNum;
576  }
577  }
578  assert(DefIdx >= 0 && "Def Reg not found in Src MI");
579  MachineInstr *DstI = Dst->getInstr();
580  SDep T = I;
581  for (unsigned OpNum = 0; OpNum < DstI->getNumOperands(); OpNum++) {
582  const MachineOperand &MO = DstI->getOperand(OpNum);
583  if (MO.isReg() && MO.isUse() && MO.getReg() == DepR) {
584  int Latency = (InstrInfo.getOperandLatency(&InstrItins, *SrcI,
585  DefIdx, *DstI, OpNum));
586 
587  // For some instructions (ex: COPY), we might end up with < 0 latency
588  // as they don't have any Itinerary class associated with them.
589  Latency = std::max(Latency, 0);
590  bool IsArtificial = I.isArtificial();
591  Latency = updateLatency(*SrcI, *DstI, IsArtificial, Latency);
592  I.setLatency(Latency);
593  }
594  }
595 
596  // Update the latency of opposite edge too.
597  T.setSUnit(Src);
598  auto F = find(Dst->Preds, T);
599  assert(F != Dst->Preds.end());
600  F->setLatency(I.getLatency());
601  }
602 }
603 
604 /// Change the latency between the two SUnits.
605 void HexagonSubtarget::changeLatency(SUnit *Src, SUnit *Dst, unsigned Lat)
606  const {
607  for (auto &I : Src->Succs) {
608  if (!I.isAssignedRegDep() || I.getSUnit() != Dst)
609  continue;
610  SDep T = I;
611  I.setLatency(Lat);
612 
613  // Update the latency of opposite edge too.
614  T.setSUnit(Src);
615  auto F = find(Dst->Preds, T);
616  assert(F != Dst->Preds.end());
617  F->setLatency(Lat);
618  }
619 }
620 
621 /// If the SUnit has a zero latency edge, return the other SUnit.
623  for (auto &I : Deps)
624  if (I.isAssignedRegDep() && I.getLatency() == 0 &&
625  !I.getSUnit()->getInstr()->isPseudo())
626  return I.getSUnit();
627  return nullptr;
628 }
629 
630 // Return true if these are the best two instructions to schedule
631 // together with a zero latency. Only one dependence should have a zero
632 // latency. If there are multiple choices, choose the best, and change
633 // the others, if needed.
634 bool HexagonSubtarget::isBestZeroLatency(SUnit *Src, SUnit *Dst,
635  const HexagonInstrInfo *TII, SmallSet<SUnit*, 4> &ExclSrc,
636  SmallSet<SUnit*, 4> &ExclDst) const {
637  MachineInstr &SrcInst = *Src->getInstr();
638  MachineInstr &DstInst = *Dst->getInstr();
639 
640  // Ignore Boundary SU nodes as these have null instructions.
641  if (Dst->isBoundaryNode())
642  return false;
643 
644  if (SrcInst.isPHI() || DstInst.isPHI())
645  return false;
646 
647  if (!TII->isToBeScheduledASAP(SrcInst, DstInst) &&
648  !TII->canExecuteInBundle(SrcInst, DstInst))
649  return false;
650 
651  // The architecture doesn't allow three dependent instructions in the same
652  // packet. So, if the destination has a zero latency successor, then it's
653  // not a candidate for a zero latency predecessor.
654  if (getZeroLatency(Dst, Dst->Succs) != nullptr)
655  return false;
656 
657  // Check if the Dst instruction is the best candidate first.
658  SUnit *Best = nullptr;
659  SUnit *DstBest = nullptr;
660  SUnit *SrcBest = getZeroLatency(Dst, Dst->Preds);
661  if (SrcBest == nullptr || Src->NodeNum >= SrcBest->NodeNum) {
662  // Check that Src doesn't have a better candidate.
663  DstBest = getZeroLatency(Src, Src->Succs);
664  if (DstBest == nullptr || Dst->NodeNum <= DstBest->NodeNum)
665  Best = Dst;
666  }
667  if (Best != Dst)
668  return false;
669 
670  // The caller frequently adds the same dependence twice. If so, then
671  // return true for this case too.
672  if ((Src == SrcBest && Dst == DstBest ) ||
673  (SrcBest == nullptr && Dst == DstBest) ||
674  (Src == SrcBest && Dst == nullptr))
675  return true;
676 
677  // Reassign the latency for the previous bests, which requires setting
678  // the dependence edge in both directions.
679  if (SrcBest != nullptr) {
680  if (!hasV60Ops())
681  changeLatency(SrcBest, Dst, 1);
682  else
683  restoreLatency(SrcBest, Dst);
684  }
685  if (DstBest != nullptr) {
686  if (!hasV60Ops())
687  changeLatency(Src, DstBest, 1);
688  else
689  restoreLatency(Src, DstBest);
690  }
691 
692  // Attempt to find another opprotunity for zero latency in a different
693  // dependence.
694  if (SrcBest && DstBest)
695  // If there is an edge from SrcBest to DstBst, then try to change that
696  // to 0 now.
697  changeLatency(SrcBest, DstBest, 0);
698  else if (DstBest) {
699  // Check if the previous best destination instruction has a new zero
700  // latency dependence opportunity.
701  ExclSrc.insert(Src);
702  for (auto &I : DstBest->Preds)
703  if (ExclSrc.count(I.getSUnit()) == 0 &&
704  isBestZeroLatency(I.getSUnit(), DstBest, TII, ExclSrc, ExclDst))
705  changeLatency(I.getSUnit(), DstBest, 0);
706  } else if (SrcBest) {
707  // Check if previous best source instruction has a new zero latency
708  // dependence opportunity.
709  ExclDst.insert(Dst);
710  for (auto &I : SrcBest->Succs)
711  if (ExclDst.count(I.getSUnit()) == 0 &&
712  isBestZeroLatency(SrcBest, I.getSUnit(), TII, ExclSrc, ExclDst))
713  changeLatency(SrcBest, I.getSUnit(), 0);
714  }
715 
716  return true;
717 }
718 
720  return 32;
721 }
722 
724  return 32;
725 }
726 
728  return EnableSubregLiveness;
729 }
730 
732  struct Scalar {
733  unsigned Opcode;
734  Intrinsic::ID IntId;
735  };
736  struct Hvx {
737  unsigned Opcode;
738  Intrinsic::ID Int64Id, Int128Id;
739  };
740 
741  static Scalar ScalarInts[] = {
742 #define GET_SCALAR_INTRINSICS
744 #undef GET_SCALAR_INTRINSICS
745  };
746 
747  static Hvx HvxInts[] = {
748 #define GET_HVX_INTRINSICS
750 #undef GET_HVX_INTRINSICS
751  };
752 
753  const auto CmpOpcode = [](auto A, auto B) { return A.Opcode < B.Opcode; };
754  [[maybe_unused]] static bool SortedScalar =
755  (llvm::sort(ScalarInts, CmpOpcode), true);
756  [[maybe_unused]] static bool SortedHvx =
757  (llvm::sort(HvxInts, CmpOpcode), true);
758 
759  auto [BS, ES] = std::make_pair(std::begin(ScalarInts), std::end(ScalarInts));
760  auto [BH, EH] = std::make_pair(std::begin(HvxInts), std::end(HvxInts));
761 
762  auto FoundScalar = std::lower_bound(BS, ES, Scalar{Opc, 0}, CmpOpcode);
763  if (FoundScalar != ES && FoundScalar->Opcode == Opc)
764  return FoundScalar->IntId;
765 
766  auto FoundHvx = std::lower_bound(BH, EH, Hvx{Opc, 0, 0}, CmpOpcode);
767  if (FoundHvx != EH && FoundHvx->Opcode == Opc) {
768  unsigned HwLen = getVectorLength();
769  if (HwLen == 64)
770  return FoundHvx->Int64Id;
771  if (HwLen == 128)
772  return FoundHvx->Int128Id;
773  }
774 
775  std::string error = "Invalid opcode (" + std::to_string(Opc) + ")";
776  llvm_unreachable(error.c_str());
777  return 0;
778 }
i
i
Definition: README.txt:29
HexagonMCTargetDesc.h
llvm::HexagonSubtarget::hasV68Ops
bool hasV68Ops() const
Definition: HexagonSubtarget.h:189
llvm::HexagonSubtarget::getVectorLength
unsigned getVectorLength() const
Definition: HexagonSubtarget.h:313
llvm::cl::Option::getPosition
unsigned getPosition() const
Definition: CommandLine.h:306
llvm::HexagonSubtarget::ParseSubtargetFeatures
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
ParseSubtargetFeatures - Parses features string setting specified subtarget options.
llvm::MVT::getVectorElementType
MVT getVectorElementType() const
Definition: MachineValueType.h:533
ScheduleDAG.h
SchedRetvalOptimization
static cl::opt< bool > SchedRetvalOptimization("sched-retval-optimization", cl::Hidden, cl::init(true))
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:108
MachineInstr.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
SchedPredsCloser
static cl::opt< bool > SchedPredsCloser("sched-preds-closer", cl::Hidden, cl::init(true))
llvm::SDep::Artificial
@ Artificial
Arbitrary strong DAG edge (no real dependence).
Definition: ScheduleDAG.h:72
llvm::Latency
@ Latency
Definition: SIMachineScheduler.h:34
llvm::StringRef::consumeInteger
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:503
llvm::lower_bound
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1897
StringRef.h
ScheduleDAGInstrs.h
llvm::MachineInstr::mayLoad
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Definition: MachineInstr.h:1056
llvm::SubtargetFeatures::AddFeature
void AddFeature(StringRef String, bool Enable=true)
Adds Features.
Definition: SubtargetFeature.cpp:37
llvm::Type::getScalarType
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:328
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::HexagonSubtarget::HexagonSubtarget
HexagonSubtarget(const Triple &TT, StringRef CPU, StringRef FS, const TargetMachine &TM)
Definition: HexagonSubtarget.cpp:79
llvm::MVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: MachineValueType.h:377
llvm::HexagonSubtarget::useHVXFloatingPoint
bool useHVXFloatingPoint() const
Definition: HexagonSubtarget.h:233
HexagonSubtarget.h
ErrorHandling.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::Hexagon_MC::addArchSubtarget
void addArchSubtarget(MCSubtargetInfo const *STI, StringRef FS)
Definition: HexagonMCTargetDesc.cpp:582
llvm::HexagonInstrInfo::getAddrMode
unsigned getAddrMode(const MachineInstr &MI) const
Definition: HexagonInstrInfo.cpp:3243
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:127
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
llvm::ScheduleDAGInstrs::addEdge
bool addEdge(SUnit *SuccSU, const SDep &PredDep)
Add a DAG edge to the given SU with the given predecessor dependence data.
Definition: ScheduleDAGInstrs.cpp:1199
llvm::EVT::isScalableVector
bool isScalableVector() const
Return true if this is a vector type where the runtime length is machine dependent.
Definition: ValueTypes.h:160
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::X86AS::FS
@ FS
Definition: X86.h:200
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:136
error
#define error(X)
Definition: SymbolRecordMapping.cpp:14
llvm::SUnit::Succs
SmallVector< SDep, 4 > Succs
All sunit successors.
Definition: ScheduleDAG.h:257
llvm::Optional
Definition: APInt.h:33
llvm::HexagonSubtarget::HexagonArchVersion
Hexagon::ArchEnum HexagonArchVersion
Definition: HexagonSubtarget.h:71
llvm::DenseMapBase::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
llvm::HexagonSubtarget::getIntrinsicId
Intrinsic::ID getIntrinsicId(unsigned Opc) const
Definition: HexagonSubtarget.cpp:731
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::HexagonSubtarget::enableSubRegLiveness
bool enableSubRegLiveness() const override
Definition: HexagonSubtarget.cpp:727
llvm::MachineInstr::isCopy
bool isCopy() const
Definition: MachineInstr.h:1336
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
EnableCheckBankConflict
static cl::opt< bool > EnableCheckBankConflict("hexagon-check-bank-conflict", cl::Hidden, cl::init(true), cl::desc("Enable checking for cache bank conflicts"))
STLExtras.h
llvm::PowerOf2Ceil
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition: MathExtras.h:630
llvm::Type::isFloatingPointTy
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition: Type.h:184
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::count_if
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition: STLExtras.h:1877
llvm::HexagonSubtarget::isTypeForHVX
bool isTypeForHVX(Type *VecTy, bool IncludeBool=false) const
Definition: HexagonSubtarget.cpp:214
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::HexagonSubtarget::BankConflictMutation::apply
void apply(ScheduleDAGInstrs *DAG) override
Definition: HexagonSubtarget.cpp:382
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::HexagonSubtarget::getHVXElementTypes
ArrayRef< MVT > getHVXElementTypes() const
Definition: HexagonSubtarget.h:322
llvm::EVT::isSimple
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:129
llvm::SDep::isArtificial
bool isArtificial() const
Tests if this is an Order dependence that is marked as "artificial", meaning it isn't necessary for c...
Definition: ScheduleDAG.h:200
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::MVT::isValid
bool isValid() const
Return true if this is a valid simple valuetype.
Definition: MachineValueType.h:345
llvm::HexagonSubtarget::getL1CacheLineSize
unsigned getL1CacheLineSize() const
Definition: HexagonSubtarget.cpp:719
CommandLine.h
llvm::HexagonSubtarget::getSMSMutations
void getSMSMutations(std::vector< std::unique_ptr< ScheduleDAGMutation >> &Mutations) const override
Definition: HexagonSubtarget.cpp:523
llvm::HexagonTargetLowering::getPreferredVectorAction
LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
Definition: HexagonISelLowering.cpp:2171
llvm::HexagonSubtarget::UseBSBScheduling
bool UseBSBScheduling
True if the target should use Back-Skip-Back scheduling.
Definition: HexagonSubtarget.h:76
llvm::MVT::i1
@ i1
Definition: MachineValueType.h:43
InstrInfo
return InstrInfo
Definition: RISCVInsertVSETVLI.cpp:668
llvm::SUnit::removePred
void removePred(const SDep &D)
Removes the specified edge as a pred of the current node if it exists.
Definition: ScheduleDAG.cpp:175
TargetMachine.h
llvm::StringRef::startswith
bool startswith(StringRef Prefix) const
Definition: StringRef.h:260
llvm::HexagonDisableDuplex
cl::opt< bool > HexagonDisableDuplex
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::EVT
Extended Value Type.
Definition: ValueTypes.h:34
llvm::MachineOperand::isUse
bool isUse() const
Definition: MachineOperand.h:369
llvm::HexagonSubtarget::OptLevel
CodeGenOpt::Level OptLevel
Definition: HexagonSubtarget.h:73
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
llvm::EVT::getVectorNumElements
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:308
llvm::SUnit::NodeNum
unsigned NodeNum
Entry # of node in the node vector.
Definition: ScheduleDAG.h:264
llvm::Register::isPhysicalRegister
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
SI
@ SI
Definition: SIInstrInfo.cpp:7882
llvm::HexagonSubtarget::enableMachineScheduler
bool enableMachineScheduler() const override
Definition: HexagonSubtarget.cpp:532
llvm::SubtargetFeatures::getFeatures
const std::vector< std::string > & getFeatures() const
Returns the vector of individual subtarget features.
Definition: SubtargetFeature.h:193
llvm::SubtargetFeatures
Manages the enabling and disabling of subtarget specific features.
Definition: SubtargetFeature.h:180
llvm::Type::isVectorTy
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:246
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::HexagonSubtarget::useHVXOps
bool useHVXOps() const
Definition: HexagonSubtarget.h:234
EnableDotCurSched
static cl::opt< bool > EnableDotCurSched("enable-cur-sched", cl::Hidden, cl::init(true), cl::desc("Enable the scheduler to generate .cur"))
llvm::HexagonInstrInfo::getType
uint64_t getType(const MachineInstr &MI) const
Definition: HexagonInstrInfo.cpp:4579
llvm::HexagonSubtarget::isTinyCore
bool isTinyCore() const
Definition: HexagonSubtarget.h:226
HexagonGenSubtargetInfo
llvm::cl::Option::getNumOccurrences
int getNumOccurrences() const
Definition: CommandLine.h:403
llvm::SDep::Output
@ Output
A register output-dependence (aka WAW).
Definition: ScheduleDAG.h:55
llvm::InstrItineraryData::Itineraries
const InstrItinerary * Itineraries
Array of itineraries selected.
Definition: MCInstrItineraries.h:116
HexagonInstrInfo.h
llvm::TargetLoweringBase::TypeWidenVector
@ TypeWidenVector
Definition: TargetLowering.h:213
llvm::HexagonInstrInfo::getBaseAndOffset
MachineOperand * getBaseAndOffset(const MachineInstr &MI, int64_t &Offset, unsigned &AccessSize) const
Definition: HexagonInstrInfo.cpp:3252
llvm::NVPTX::PTXLdStInstCode::Scalar
@ Scalar
Definition: NVPTX.h:122
Hexagon.h
llvm::SDep::Order
@ Order
Any other ordering dependency.
Definition: ScheduleDAG.h:56
llvm::HexagonSubtarget::getL1PrefetchDistance
unsigned getL1PrefetchDistance() const
Definition: HexagonSubtarget.cpp:723
HexagonDepInstrIntrinsics.inc
EnableBSBSched
static cl::opt< bool > EnableBSBSched("enable-bsb-sched", cl::Hidden, cl::init(true))
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:210
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1657
llvm::HexagonSubtarget::getInstrInfo
const HexagonInstrInfo * getInstrInfo() const override
Definition: HexagonSubtarget.h:124
llvm::HexagonII::TypeS_2op
@ TypeS_2op
Definition: HexagonDepITypes.h:60
llvm::Register::isVirtual
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
llvm::SubtargetFeatures::getString
std::string getString() const
Returns features as a string.
Definition: SubtargetFeature.cpp:50
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:657
llvm::cl::opt< bool >
OverrideLongCalls
static cl::opt< bool > OverrideLongCalls("hexagon-long-calls", cl::Hidden, cl::desc("If present, forces/disables the use of long calls"))
llvm::SmallSet::count
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition: SmallSet.h:165
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:340
getZeroLatency
static SUnit * getZeroLatency(SUnit *N, SmallVector< SDep, 4 > &Deps)
If the SUnit has a zero latency edge, return the other SUnit.
Definition: HexagonSubtarget.cpp:622
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::HexagonSubtarget::useAA
bool useAA() const override
Enable use of alias analysis during code generation (during MI scheduling, DAGCombine,...
Definition: HexagonSubtarget.cpp:431
llvm::find
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
llvm::HexagonII::TypeALU64
@ TypeALU64
Definition: HexagonDepITypes.h:20
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:53
llvm::DenseMap< unsigned, unsigned >
llvm::HexagonSubtarget::CallMutation::apply
void apply(ScheduleDAGInstrs *DAG) override
Definition: HexagonSubtarget.cpp:313
llvm::EVT::getEVT
static EVT getEVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:579
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::SUnit::getInstr
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
Definition: ScheduleDAG.h:373
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:447
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1843
HexagonRegisterInfo.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
llvm::Hexagon::getCpu
Optional< Hexagon::ArchEnum > getCpu(StringRef CPU)
Definition: HexagonDepArch.h:32
llvm::MachineInstr::isPHI
bool isPHI() const
Definition: MachineInstr.h:1300
llvm::MVT
Machine Value Type.
Definition: MachineValueType.h:31
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::ScheduleDAGMI
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
Definition: MachineScheduler.h:273
llvm::HexagonII::BaseImmOffset
@ BaseImmOffset
Definition: HexagonBaseInfo.h:34
llvm::HexagonSubtarget::usePredicatedCalls
bool usePredicatedCalls() const
Definition: HexagonSubtarget.cpp:538
llvm::HexagonInstrInfo
Definition: HexagonInstrInfo.h:38
llvm::MVT::getVectorVT
static MVT getVectorVT(MVT VT, unsigned NumElements)
Definition: MachineValueType.h:1230
llvm::CodeGenOpt::None
@ None
Definition: CodeGen.h:53
llvm::HexagonSubtarget::useHVXV68Ops
bool useHVXV68Ops() const
Definition: HexagonSubtarget.h:252
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:154
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm::HexagonSubtarget::isHVXElementType
bool isHVXElementType(MVT Ty, bool IncludeBool=false) const
Definition: HexagonSubtarget.cpp:175
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
llvm::ScheduleDAG::MF
MachineFunction & MF
Machine function.
Definition: ScheduleDAG.h:559
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::HexagonSubtarget::getPostRAMutations
void getPostRAMutations(std::vector< std::unique_ptr< ScheduleDAGMutation >> &Mutations) const override
Definition: HexagonSubtarget.cpp:516
llvm::SDep::Barrier
@ Barrier
An unknown scheduling barrier.
Definition: ScheduleDAG.h:69
llvm::MachineOperand::isDef
bool isDef() const
Definition: MachineOperand.h:374
llvm::FeatureBitset::reset
constexpr FeatureBitset & reset(unsigned I)
Definition: SubtargetFeature.h:68
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
DisableHexagonMISched
static cl::opt< bool > DisableHexagonMISched("disable-hexagon-misched", cl::Hidden, cl::desc("Disable Hexagon MI Scheduling"))
llvm::SDep
Scheduling dependency.
Definition: ScheduleDAG.h:49
llvm::HexagonSubtarget::UsrOverflowMutation::apply
void apply(ScheduleDAGInstrs *DAG) override
Definition: HexagonSubtarget.cpp:249
EnableTCLatencySched
static cl::opt< bool > EnableTCLatencySched("enable-tc-latency-sched", cl::Hidden, cl::init(false))
llvm::MachineInstr::isRegSequence
bool isRegSequence() const
Definition: MachineInstr.h:1328
j
return j(j<< 16)
llvm::ScheduleDAG::SUnits
std::vector< SUnit > SUnits
The scheduling units.
Definition: ScheduleDAG.h:561
std
Definition: BitVector.h:851
llvm::HexagonSubtarget::getRegisterInfo
const HexagonRegisterInfo * getRegisterInfo() const override
Definition: HexagonSubtarget.h:125
llvm::HexagonSubtarget::initializeSubtargetDependencies
HexagonSubtarget & initializeSubtargetDependencies(StringRef CPU, StringRef FS)
Definition: HexagonSubtarget.cpp:94
llvm::HexagonSubtarget::getTargetLowering
const HexagonTargetLowering * getTargetLowering() const override
Definition: HexagonSubtarget.h:128
llvm::SUnit::setHeightDirty
void setHeightDirty()
Sets a flag in this node to indicate that its stored Height value will require recomputation the next...
Definition: ScheduleDAG.cpp:232
llvm::MachineInstr::mayStore
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
Definition: MachineInstr.h:1069
llvm::HexagonII::TypeS_3op
@ TypeS_3op
Definition: HexagonDepITypes.h:61
llvm::SDep::setLatency
void setLatency(unsigned Lat)
Sets the latency for this edge.
Definition: ScheduleDAG.h:147
llvm::ScheduleDAG::TII
const TargetInstrInfo * TII
Target instruction information.
Definition: ScheduleDAG.h:557
llvm::HexagonSubtarget::useBSBScheduling
bool useBSBScheduling() const
Definition: HexagonSubtarget.h:273
llvm::SUnit::addPred
bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
Definition: ScheduleDAG.cpp:107
EnablePredicatedCalls
static cl::opt< bool > EnablePredicatedCalls("hexagon-pred-calls", cl::Hidden, cl::desc("Consider calls to be predicable"))
EnableSubregLiveness
static cl::opt< bool > EnableSubregLiveness("hexagon-subreg-liveness", cl::Hidden, cl::init(true), cl::desc("Enable subregister liveness tracking for Hexagon"))
llvm::SmallSet::insert
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:178
llvm::EVT::getVectorElementType
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:300
BH
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference BH
Definition: README-X86-64.txt:44
llvm::M68kBeads::DReg
@ DReg
Definition: M68kBaseInfo.h:61
llvm::MCRegAliasIterator::isValid
bool isValid() const
Definition: MCRegisterInfo.h:813
llvm::Hexagon_MC::selectHexagonCPU
StringRef selectHexagonCPU(StringRef CPU)
Definition: HexagonMCTargetDesc.cpp:153
MachineScheduler.h
llvm::HexagonSubtarget::isHVXVectorType
bool isHVXVectorType(EVT VecTy, bool IncludeBool=false) const
Definition: HexagonSubtarget.cpp:186
SmallVector.h
llvm::SUnit::isInstr
bool isInstr() const
Returns true if this SUnit refers to a machine instruction as opposed to an SDNode.
Definition: ScheduleDAG.h:362
N
#define N
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:519
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:85
llvm::HexagonInstrInfo::isToBeScheduledASAP
bool isToBeScheduledASAP(const MachineInstr &MI1, const MachineInstr &MI2) const
Definition: HexagonInstrInfo.cpp:2677
llvm::HexagonSubtarget
Definition: HexagonSubtarget.h:43
llvm::HexagonInstrInfo::canExecuteInBundle
bool canExecuteInBundle(const MachineInstr &First, const MachineInstr &Second) const
Can these instructions execute at the same time in a bundle.
Definition: HexagonInstrInfo.cpp:3047
llvm::SmallSet::clear
void clear()
Definition: SmallSet.h:217
llvm::HexagonInstrInfo::getOperandLatency
int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
getOperandLatency - Compute and return the use operand latency of a given pair of def and use.
Definition: HexagonInstrInfo.cpp:4289
llvm::reverse
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:485
MachineOperand.h
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::Hexagon_MC::completeHVXFeatures
FeatureBitset completeHVXFeatures(const FeatureBitset &FB)
Definition: HexagonMCTargetDesc.cpp:466
llvm::SUnit::Preds
SmallVector< SDep, 4 > Preds
All sunit predecessors.
Definition: ScheduleDAG.h:256
llvm::SUnit
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:242
llvm::cl::desc
Definition: CommandLine.h:413
llvm::ScheduleDAGInstrs
A ScheduleDAG for scheduling lists of MachineInstr.
Definition: ScheduleDAGInstrs.h:120
llvm::HexagonSubtarget::hasV60Ops
bool hasV60Ops() const
Definition: HexagonSubtarget.h:159
llvm::HexagonSubtarget::adjustSchedDependency
void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, SDep &Dep) const override
Perform target specific adjustments to the latency of a schedule dependency.
Definition: HexagonSubtarget.cpp:439
llvm::HexagonSubtarget::HVXMemLatencyMutation::apply
void apply(ScheduleDAGInstrs *DAG) override
Definition: HexagonSubtarget.cpp:262
llvm::SDep::getLatency
unsigned getLatency() const
Returns the latency value for this edge, which roughly means the minimum number of cycles that must e...
Definition: ScheduleDAG.h:142
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:601
llvm::HexagonII::TypeM
@ TypeM
Definition: HexagonDepITypes.h:54
llvm::MCRegAliasIterator
MCRegAliasIterator enumerates all registers aliasing Reg.
Definition: MCRegisterInfo.h:788
SpecialSubKind::string
@ string
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:288
SmallSet.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:39