| //=- llvm/CodeGen/SimpleHazardRecognizer.h - Scheduling Support -*- C++ -*-=// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements the SimpleHazardRecognizer class, which |
| // implements hazard-avoidance heuristics for scheduling, based on the |
| // scheduling itineraries specified for the target. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CODEGEN_SIMPLEHAZARDRECOGNIZER_H |
| #define LLVM_CODEGEN_SIMPLEHAZARDRECOGNIZER_H |
| |
| #include "llvm/CodeGen/ScheduleHazardRecognizer.h" |
| #include "llvm/CodeGen/ScheduleDAG.h" |
| #include "llvm/Target/TargetMachine.h" |
| #include "llvm/Target/TargetInstrInfo.h" |
| |
| namespace llvm { |
| /// SimpleHazardRecognizer - A *very* simple hazard recognizer. It uses |
| /// a coarse classification and attempts to avoid that instructions of |
| /// a given class aren't grouped too densely together. |
| class SimpleHazardRecognizer : public ScheduleHazardRecognizer { |
| /// Class - A simple classification for SUnits. |
| enum Class { |
| Other, Load, Store |
| }; |
| |
| /// Window - The Class values of the most recently issued |
| /// instructions. |
| Class Window[8]; |
| |
| /// getClass - Classify the given SUnit. |
| Class getClass(const SUnit *SU) { |
| const MachineInstr *MI = SU->getInstr(); |
| const TargetInstrDesc &TID = MI->getDesc(); |
| if (TID.mayLoad()) |
| return Load; |
| if (TID.mayStore()) |
| return Store; |
| return Other; |
| } |
| |
| /// Step - Rotate the existing entries in Window and insert the |
| /// given class value in position as the most recent. |
| void Step(Class C) { |
| std::copy(Window+1, array_endof(Window), Window); |
| Window[array_lengthof(Window)-1] = C; |
| } |
| |
| public: |
| SimpleHazardRecognizer() : Window() { |
| Reset(); |
| } |
| |
| virtual HazardType getHazardType(SUnit *SU) { |
| Class C = getClass(SU); |
| if (C == Other) |
| return NoHazard; |
| unsigned Score = 0; |
| for (unsigned i = 0; i != array_lengthof(Window); ++i) |
| if (Window[i] == C) |
| Score += i + 1; |
| if (Score > array_lengthof(Window) * 2) |
| return Hazard; |
| return NoHazard; |
| } |
| |
| virtual void Reset() { |
| for (unsigned i = 0; i != array_lengthof(Window); ++i) |
| Window[i] = Other; |
| } |
| |
| virtual void EmitInstruction(SUnit *SU) { |
| Step(getClass(SU)); |
| } |
| |
| virtual void AdvanceCycle() { |
| Step(Other); |
| } |
| }; |
| } |
| |
| #endif |