forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //=-- SystemZHazardRecognizer.h - SystemZ Hazard Recognizer -----*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file declares a hazard recognizer for the SystemZ scheduler.
 | |
| //
 | |
| // This class is used by the SystemZ scheduling strategy to maintain
 | |
| // the state during scheduling, and provide cost functions for
 | |
| // scheduling candidates. This includes:
 | |
| //
 | |
| // * Decoder grouping. A decoder group can maximally hold 3 uops, and
 | |
| // instructions that always begin a new group should be scheduled when
 | |
| // the current decoder group is empty.
 | |
| // * Processor resources usage. It is beneficial to balance the use of
 | |
| // resources.
 | |
| //
 | |
| // ===---------------------------------------------------------------------===//
 | |
| 
 | |
| #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
 | |
| #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H
 | |
| 
 | |
| #include "SystemZSubtarget.h"
 | |
| #include "llvm/CodeGen/MachineFunction.h"
 | |
| #include "llvm/CodeGen/MachineScheduler.h"
 | |
| #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
 | |
| #include "llvm/ADT/SmallVector.h"
 | |
| #include "llvm/MC/MCInstrDesc.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| #include <string>
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| /// SystemZHazardRecognizer maintains the state during scheduling.
 | |
| class SystemZHazardRecognizer : public ScheduleHazardRecognizer {
 | |
| 
 | |
|   ScheduleDAGMI *DAG;
 | |
|   const TargetSchedModel *SchedModel;
 | |
| 
 | |
|   /// Keep track of the number of decoder slots used in the current
 | |
|   /// decoder group.
 | |
|   unsigned CurrGroupSize;
 | |
| 
 | |
|   /// The tracking of resources here are quite similar to the common
 | |
|   /// code use of a critical resource. However, z13 differs in the way
 | |
|   /// that it has two processor sides which may be interesting to
 | |
|   /// model in the future (a work in progress).
 | |
| 
 | |
|   /// Counters for the number of uops scheduled per processor
 | |
|   /// resource.
 | |
|   SmallVector<int, 0> ProcResourceCounters;
 | |
| 
 | |
|   /// This is the resource with the greatest queue, which the
 | |
|   /// scheduler tries to avoid.
 | |
|   unsigned CriticalResourceIdx;
 | |
| 
 | |
|   /// Return the number of decoder slots MI requires.
 | |
|   inline unsigned getNumDecoderSlots(SUnit *SU) const;
 | |
| 
 | |
|   /// Return true if MI fits into current decoder group.
 | |
|   bool fitsIntoCurrentGroup(SUnit *SU) const;
 | |
| 
 | |
|   /// Two decoder groups per cycle are formed (for z13), meaning 2x3
 | |
|   /// instructions. This function returns a number between 0 and 5,
 | |
|   /// representing the current decoder slot of the current cycle.
 | |
|   unsigned getCurrCycleIdx();
 | |
|   
 | |
|   /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx()
 | |
|   /// when a stalling operation is scheduled (which uses the FPd resource).
 | |
|   unsigned LastFPdOpCycleIdx;
 | |
| 
 | |
|   /// A counter of decoder groups scheduled.
 | |
|   unsigned GrpCount;
 | |
| 
 | |
|   unsigned getCurrGroupSize() {return CurrGroupSize;};
 | |
| 
 | |
|   /// Start next decoder group.
 | |
|   void nextGroup(bool DbgOutput = true);
 | |
| 
 | |
|   /// Clear all counters for processor resources.
 | |
|   void clearProcResCounters();
 | |
| 
 | |
|   /// With the goal of alternating processor sides for stalling (FPd)
 | |
|   /// ops, return true if it seems good to schedule an FPd op next.
 | |
|   bool isFPdOpPreferred_distance(const SUnit *SU);
 | |
| 
 | |
| public:
 | |
|   SystemZHazardRecognizer(const MachineSchedContext *C);
 | |
| 
 | |
|   void setDAG(ScheduleDAGMI *dag) {
 | |
|     DAG = dag;
 | |
|     SchedModel = dag->getSchedModel();
 | |
|   }
 | |
|   
 | |
|   HazardType getHazardType(SUnit *m, int Stalls = 0) override;    
 | |
|   void Reset() override;
 | |
|   void EmitInstruction(SUnit *SU) override;
 | |
| 
 | |
|   // Cost functions used by SystemZPostRASchedStrategy while
 | |
|   // evaluating candidates.
 | |
| 
 | |
|   /// Return the cost of decoder grouping for SU. If SU must start a
 | |
|   /// new decoder group, this is negative if this fits the schedule or
 | |
|   /// positive if it would mean ending a group prematurely. For normal
 | |
|   /// instructions this returns 0.
 | |
|   int groupingCost(SUnit *SU) const; 
 | |
| 
 | |
|   /// Return the cost of SU in regards to processor resources usage.
 | |
|   /// A positive value means it would be better to wait with SU, while
 | |
|   /// a negative value means it would be good to schedule SU next.
 | |
|   int resourcesCost(SUnit *SU);
 | |
| 
 | |
| #ifndef NDEBUG
 | |
|   // Debug dumping.
 | |
|   std::string CurGroupDbg; // current group as text
 | |
|   void dumpSU(SUnit *SU, raw_ostream &OS) const;
 | |
|   void dumpCurrGroup(std::string Msg = "") const;
 | |
|   void dumpProcResourceCounters() const;
 | |
| #endif
 | |
| };
 | |
| 
 | |
| } // namespace llvm
 | |
| 
 | |
| #endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZHAZARDRECOGNIZER_H */
 |