blob: b9038e073e47ec0272652ffb3723cb2fe1e22557 [file] [log] [blame]
//=- 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];
/// Pos - Current position pointing into Window.
///
unsigned Pos;
/// 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) {
Window[Pos] = C;
if (Pos == 0)
Pos = array_lengthof(Window)-1;
else
--Pos;
}
public:
SimpleHazardRecognizer() : Window() {
Reset();
}
virtual HazardType getHazardType(SUnit *SU) {
Class C = getClass(SU);
if (C == Other)
return NoHazard;
unsigned Score = 0;
for (unsigned i = array_lengthof(Window); i != 0; --i) {
unsigned RealPos = (Pos + (i-1)) % array_lengthof(Window);
if (Window[RealPos] == C) {
Score += i;
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;
Pos = array_lengthof(Window)-1;
}
virtual void EmitInstruction(SUnit *SU) {
Step(getClass(SU));
}
virtual void AdvanceCycle() {
Step(Other);
}
};
}
#endif