blob: b9038e073e47ec0272652ffb3723cb2fe1e22557 [file] [log] [blame]
David Goodwin5ab4fd42009-08-10 15:55:25 +00001//=- llvm/CodeGen/SimpleHazardRecognizer.h - Scheduling Support -*- C++ -*-=//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the SimpleHazardRecognizer class, which
11// implements hazard-avoidance heuristics for scheduling, based on the
12// scheduling itineraries specified for the target.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CODEGEN_SIMPLEHAZARDRECOGNIZER_H
17#define LLVM_CODEGEN_SIMPLEHAZARDRECOGNIZER_H
18
19#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
20#include "llvm/CodeGen/ScheduleDAG.h"
21#include "llvm/Target/TargetMachine.h"
22#include "llvm/Target/TargetInstrInfo.h"
23
24namespace llvm {
25 /// SimpleHazardRecognizer - A *very* simple hazard recognizer. It uses
26 /// a coarse classification and attempts to avoid that instructions of
27 /// a given class aren't grouped too densely together.
28 class SimpleHazardRecognizer : public ScheduleHazardRecognizer {
29 /// Class - A simple classification for SUnits.
30 enum Class {
31 Other, Load, Store
32 };
33
34 /// Window - The Class values of the most recently issued
35 /// instructions.
36 Class Window[8];
37
Evan Cheng0b5007a2010-06-14 20:18:40 +000038 /// Pos - Current position pointing into Window.
39 ///
40 unsigned Pos;
41
David Goodwin5ab4fd42009-08-10 15:55:25 +000042 /// getClass - Classify the given SUnit.
43 Class getClass(const SUnit *SU) {
44 const MachineInstr *MI = SU->getInstr();
45 const TargetInstrDesc &TID = MI->getDesc();
46 if (TID.mayLoad())
47 return Load;
48 if (TID.mayStore())
49 return Store;
50 return Other;
51 }
52
53 /// Step - Rotate the existing entries in Window and insert the
54 /// given class value in position as the most recent.
55 void Step(Class C) {
Evan Cheng0b5007a2010-06-14 20:18:40 +000056 Window[Pos] = C;
57 if (Pos == 0)
58 Pos = array_lengthof(Window)-1;
59 else
60 --Pos;
David Goodwin5ab4fd42009-08-10 15:55:25 +000061 }
62
63 public:
64 SimpleHazardRecognizer() : Window() {
65 Reset();
66 }
67
68 virtual HazardType getHazardType(SUnit *SU) {
69 Class C = getClass(SU);
70 if (C == Other)
71 return NoHazard;
Evan Cheng0b5007a2010-06-14 20:18:40 +000072
David Goodwin5ab4fd42009-08-10 15:55:25 +000073 unsigned Score = 0;
Evan Cheng0b5007a2010-06-14 20:18:40 +000074 for (unsigned i = array_lengthof(Window); i != 0; --i) {
75 unsigned RealPos = (Pos + (i-1)) % array_lengthof(Window);
76 if (Window[RealPos] == C) {
77 Score += i;
78 if (Score > array_lengthof(Window) * 2)
79 return Hazard;
80 }
81 }
David Goodwin5ab4fd42009-08-10 15:55:25 +000082 return NoHazard;
83 }
84
85 virtual void Reset() {
86 for (unsigned i = 0; i != array_lengthof(Window); ++i)
87 Window[i] = Other;
Evan Cheng0b5007a2010-06-14 20:18:40 +000088 Pos = array_lengthof(Window)-1;
David Goodwin5ab4fd42009-08-10 15:55:25 +000089 }
90
91 virtual void EmitInstruction(SUnit *SU) {
92 Step(getClass(SU));
93 }
94
95 virtual void AdvanceCycle() {
96 Step(Other);
97 }
98 };
99}
100
101#endif