LLVM API Documentation

ScheduleHazardRecognizer.h
Go to the documentation of this file.
00001 //=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the ScheduleHazardRecognizer class, which implements
00011 // hazard-avoidance heuristics for scheduling.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
00016 #define LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
00017 
00018 namespace llvm {
00019 
00020 class SUnit;
00021 
00022 /// HazardRecognizer - This determines whether or not an instruction can be
00023 /// issued this cycle, and whether or not a noop needs to be inserted to handle
00024 /// the hazard.
00025 class ScheduleHazardRecognizer {
00026 protected:
00027   /// MaxLookAhead - Indicate the number of cycles in the scoreboard
00028   /// state. Important to restore the state after backtracking. Additionally,
00029   /// MaxLookAhead=0 identifies a fake recognizer, allowing the client to
00030   /// bypass virtual calls. Currently the PostRA scheduler ignores it.
00031   unsigned MaxLookAhead;
00032 
00033 public:
00034   ScheduleHazardRecognizer(): MaxLookAhead(0) {}
00035   virtual ~ScheduleHazardRecognizer();
00036 
00037   enum HazardType {
00038     NoHazard,      // This instruction can be emitted at this cycle.
00039     Hazard,        // This instruction can't be emitted at this cycle.
00040     NoopHazard     // This instruction can't be emitted, and needs noops.
00041   };
00042 
00043   unsigned getMaxLookAhead() const { return MaxLookAhead; }
00044 
00045   bool isEnabled() const { return MaxLookAhead != 0; }
00046 
00047   /// atIssueLimit - Return true if no more instructions may be issued in this
00048   /// cycle.
00049   ///
00050   /// FIXME: remove this once MachineScheduler is the only client.
00051   virtual bool atIssueLimit() const { return false; }
00052 
00053   /// getHazardType - Return the hazard type of emitting this node.  There are
00054   /// three possible results.  Either:
00055   ///  * NoHazard: it is legal to issue this instruction on this cycle.
00056   ///  * Hazard: issuing this instruction would stall the machine.  If some
00057   ///     other instruction is available, issue it first.
00058   ///  * NoopHazard: issuing this instruction would break the program.  If
00059   ///     some other instruction can be issued, do so, otherwise issue a noop.
00060   virtual HazardType getHazardType(SUnit *m, int Stalls = 0) {
00061     return NoHazard;
00062   }
00063 
00064   /// Reset - This callback is invoked when a new block of
00065   /// instructions is about to be schedule. The hazard state should be
00066   /// set to an initialized state.
00067   virtual void Reset() {}
00068 
00069   /// EmitInstruction - This callback is invoked when an instruction is
00070   /// emitted, to advance the hazard state.
00071   virtual void EmitInstruction(SUnit *) {}
00072 
00073   /// PreEmitNoops - This callback is invoked prior to emitting an instruction.
00074   /// It should return the number of noops to emit prior to the provided
00075   /// instruction.
00076   /// Note: This is only used during PostRA scheduling. EmitNoop is not called
00077   /// for these noops.
00078   virtual unsigned PreEmitNoops(SUnit *) {
00079     return 0;
00080   }
00081 
00082   /// ShouldPreferAnother - This callback may be invoked if getHazardType
00083   /// returns NoHazard. If, even though there is no hazard, it would be better to
00084   /// schedule another available instruction, this callback should return true.
00085   virtual bool ShouldPreferAnother(SUnit *) {
00086     return false;
00087   }
00088 
00089   /// AdvanceCycle - This callback is invoked whenever the next top-down
00090   /// instruction to be scheduled cannot issue in the current cycle, either
00091   /// because of latency or resource conflicts.  This should increment the
00092   /// internal state of the hazard recognizer so that previously "Hazard"
00093   /// instructions will now not be hazards.
00094   virtual void AdvanceCycle() {}
00095 
00096   /// RecedeCycle - This callback is invoked whenever the next bottom-up
00097   /// instruction to be scheduled cannot issue in the current cycle, either
00098   /// because of latency or resource conflicts.
00099   virtual void RecedeCycle() {}
00100 
00101   /// EmitNoop - This callback is invoked when a noop was added to the
00102   /// instruction stream.
00103   virtual void EmitNoop() {
00104     // Default implementation: count it as a cycle.
00105     AdvanceCycle();
00106   }
00107 };
00108 
00109 }
00110 
00111 #endif