GCNHazardRecognizer.h revision 355940
143412Snewton//===-- GCNHazardRecognizers.h - GCN Hazard Recognizers ---------*- C++ -*-===//
243412Snewton//
343412Snewton// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
443412Snewton// See https://llvm.org/LICENSE.txt for license information.
543412Snewton// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
643412Snewton//
743412Snewton//===----------------------------------------------------------------------===//
843412Snewton//
943412Snewton// This file defines hazard recognizers for scheduling on GCN processors.
1043412Snewton//
1143412Snewton//===----------------------------------------------------------------------===//
1243412Snewton
1343412Snewton#ifndef LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H
1443412Snewton#define LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H
1543412Snewton
1643412Snewton#include "llvm/ADT/BitVector.h"
1743412Snewton#include "llvm/ADT/STLExtras.h"
1843412Snewton#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
1997748Sschweikh#include "llvm/CodeGen/TargetSchedule.h"
2043412Snewton#include <list>
2143412Snewton
2243412Snewtonnamespace llvm {
2343412Snewton
2443412Snewtonclass MachineFunction;
2543412Snewtonclass MachineInstr;
2643412Snewtonclass MachineOperand;
2743412Snewtonclass MachineRegisterInfo;
2843412Snewtonclass ScheduleDAG;
2943412Snewtonclass SIInstrInfo;
3043412Snewtonclass SIRegisterInfo;
3143412Snewtonclass GCNSubtarget;
3243412Snewton
33116174Sobrienclass GCNHazardRecognizer final : public ScheduleHazardRecognizer {
34116174Sobrienpublic:
35116174Sobrien  typedef function_ref<bool(MachineInstr *)> IsHazardFn;
3643412Snewton
3743412Snewtonprivate:
3843412Snewton  // Distinguish if we are called from scheduler or hazard recognizer
3943412Snewton  bool IsHazardRecognizerMode;
4043412Snewton
4143412Snewton  // This variable stores the instruction that has been emitted this cycle. It
4243412Snewton  // will be added to EmittedInstrs, when AdvanceCycle() or RecedeCycle() is
4376166Smarkm  // called.
4476166Smarkm  MachineInstr *CurrCycleInstr;
4543412Snewton  std::list<MachineInstr*> EmittedInstrs;
4676166Smarkm  const MachineFunction &MF;
4743412Snewton  const GCNSubtarget &ST;
4843412Snewton  const SIInstrInfo &TII;
4943412Snewton  const SIRegisterInfo &TRI;
5043412Snewton  TargetSchedModel TSchedModel;
5143412Snewton
5243412Snewton  /// RegUnits of uses in the current soft memory clause.
5343412Snewton  BitVector ClauseUses;
5443412Snewton
5543412Snewton  /// RegUnits of defs in the current soft memory clause.
5665302Sobrien  BitVector ClauseDefs;
5743412Snewton
5892761Salfred  void resetClause() {
5943412Snewton    ClauseUses.reset();
6043412Snewton    ClauseDefs.reset();
6143412Snewton  }
6243412Snewton
6343412Snewton  void addClauseInst(const MachineInstr &MI);
6443412Snewton
6543412Snewton  // Advance over a MachineInstr bundle. Look for hazards in the bundled
6643412Snewton  // instructions.
6743412Snewton  void processBundle();
6843412Snewton
6943412Snewton  int getWaitStatesSince(IsHazardFn IsHazard, int Limit);
7043412Snewton  int getWaitStatesSinceDef(unsigned Reg, IsHazardFn IsHazardDef, int Limit);
71101771Sjeff  int getWaitStatesSinceSetReg(IsHazardFn IsHazard, int Limit);
7243412Snewton
7343412Snewton  int checkSoftClauseHazards(MachineInstr *SMEM);
7443412Snewton  int checkSMRDHazards(MachineInstr *SMRD);
7543412Snewton  int checkVMEMHazards(MachineInstr* VMEM);
7643412Snewton  int checkDPPHazards(MachineInstr *DPP);
7743412Snewton  int checkDivFMasHazards(MachineInstr *DivFMas);
7843412Snewton  int checkGetRegHazards(MachineInstr *GetRegInstr);
7943412Snewton  int checkSetRegHazards(MachineInstr *SetRegInstr);
8043412Snewton  int createsVALUHazard(const MachineInstr &MI);
8143412Snewton  int checkVALUHazards(MachineInstr *VALU);
8243412Snewton  int checkVALUHazardsHelper(const MachineOperand &Def, const MachineRegisterInfo &MRI);
8343412Snewton  int checkRWLaneHazards(MachineInstr *RWLane);
8443412Snewton  int checkRFEHazards(MachineInstr *RFE);
8543412Snewton  int checkInlineAsmHazards(MachineInstr *IA);
8643412Snewton  int checkAnyInstHazards(MachineInstr *MI);
8743412Snewton  int checkReadM0Hazards(MachineInstr *SMovRel);
8843412Snewton  int checkNSAtoVMEMHazard(MachineInstr *MI);
8943412Snewton  int checkFPAtomicToDenormModeHazard(MachineInstr *MI);
9043412Snewton  void fixHazards(MachineInstr *MI);
9143412Snewton  bool fixVcmpxPermlaneHazards(MachineInstr *MI);
9243412Snewton  bool fixVMEMtoScalarWriteHazards(MachineInstr *MI);
9380114Sassar  bool fixSMEMtoVectorWriteHazards(MachineInstr *MI);
9443412Snewton  bool fixVcmpxExecWARHazard(MachineInstr *MI);
9543412Snewton  bool fixLdsBranchVmemWARHazard(MachineInstr *MI);
9643412Snewton
9743412Snewton  int checkMAIHazards(MachineInstr *MI);
9843412Snewton  int checkMAILdStHazards(MachineInstr *MI);
9943412Snewton
10043412Snewtonpublic:
10143412Snewton  GCNHazardRecognizer(const MachineFunction &MF);
10243412Snewton  // We can only issue one instruction per cycle.
10343412Snewton  bool atIssueLimit() const override { return true; }
10443412Snewton  void EmitInstruction(SUnit *SU) override;
10543412Snewton  void EmitInstruction(MachineInstr *MI) override;
10643412Snewton  HazardType getHazardType(SUnit *SU, int Stalls) override;
10771454Sjhb  void EmitNoop() override;
10871454Sjhb  unsigned PreEmitNoops(SUnit *SU) override;
10943412Snewton  unsigned PreEmitNoops(MachineInstr *) override;
11043412Snewton  unsigned PreEmitNoopsCommon(MachineInstr *);
11143412Snewton  void AdvanceCycle() override;
11284783Sps  void RecedeCycle() override;
11343412Snewton};
11443412Snewton
11543412Snewton} // end namespace llvm
116101771Sjeff
117101771Sjeff#endif //LLVM_LIB_TARGET_AMDGPUHAZARDRECOGNIZERS_H
11843412Snewton