1 #ifndef __NV50_IR_SCHED_GM107_H__
2 #define __NV50_IR_SCHED_GM107_H__
3 namespace nv50_ir {
4 
5 class SchedDataCalculatorGM107 : public Pass
6 {
7 public:
SchedDataCalculatorGM107(const TargetGM107 * targ)8    SchedDataCalculatorGM107(const TargetGM107 *targ) : score(NULL), targ(targ) {}
9 
10 private:
11    struct RegScores
12    {
13       struct ScoreData {
14          int r[256];
15          int p[8];
16          int c;
17       } rd, wr;
18       int base;
19 
rebaseRegScores20       void rebase(const int base)
21       {
22          const int delta = this->base - base;
23          if (!delta)
24             return;
25          this->base = 0;
26 
27          for (int i = 0; i < 256; ++i) {
28             rd.r[i] += delta;
29             wr.r[i] += delta;
30          }
31          for (int i = 0; i < 8; ++i) {
32             rd.p[i] += delta;
33             wr.p[i] += delta;
34          }
35          rd.c += delta;
36          wr.c += delta;
37       }
wipeRegScores38       void wipe()
39       {
40          memset(&rd, 0, sizeof(rd));
41          memset(&wr, 0, sizeof(wr));
42       }
getLatestRegScores43       int getLatest(const ScoreData& d) const
44       {
45          int max = 0;
46          for (int i = 0; i < 256; ++i)
47             if (d.r[i] > max)
48                max = d.r[i];
49          for (int i = 0; i < 8; ++i)
50             if (d.p[i] > max)
51                max = d.p[i];
52          if (d.c > max)
53             max = d.c;
54          return max;
55       }
getLatestRdRegScores56       inline int getLatestRd() const
57       {
58          return getLatest(rd);
59       }
getLatestWrRegScores60       inline int getLatestWr() const
61       {
62          return getLatest(wr);
63       }
getLatestRegScores64       inline int getLatest() const
65       {
66          return MAX2(getLatestRd(), getLatestWr());
67       }
setMaxRegScores68       void setMax(const RegScores *that)
69       {
70          for (int i = 0; i < 256; ++i) {
71             rd.r[i] = MAX2(rd.r[i], that->rd.r[i]);
72             wr.r[i] = MAX2(wr.r[i], that->wr.r[i]);
73          }
74          for (int i = 0; i < 8; ++i) {
75             rd.p[i] = MAX2(rd.p[i], that->rd.p[i]);
76             wr.p[i] = MAX2(wr.p[i], that->wr.p[i]);
77          }
78          rd.c = MAX2(rd.c, that->rd.c);
79          wr.c = MAX2(wr.c, that->wr.c);
80       }
printRegScores81       void print(int cycle)
82       {
83          for (int i = 0; i < 256; ++i) {
84             if (rd.r[i] > cycle)
85                INFO("rd $r%i @ %i\n", i, rd.r[i]);
86             if (wr.r[i] > cycle)
87                INFO("wr $r%i @ %i\n", i, wr.r[i]);
88          }
89          for (int i = 0; i < 8; ++i) {
90             if (rd.p[i] > cycle)
91                INFO("rd $p%i @ %i\n", i, rd.p[i]);
92             if (wr.p[i] > cycle)
93                INFO("wr $p%i @ %i\n", i, wr.p[i]);
94          }
95          if (rd.c > cycle)
96             INFO("rd $c @ %i\n", rd.c);
97          if (wr.c > cycle)
98             INFO("wr $c @ %i\n", wr.c);
99       }
100    };
101 
102    RegScores *score; // for current BB
103    std::vector<RegScores> scoreBoards;
104 
105    const TargetGM107 *targ;
106    bool visit(Function *);
107    bool visit(BasicBlock *);
108 
109    void commitInsn(const Instruction *, int);
110    int calcDelay(const Instruction *, int) const;
111    void setDelay(Instruction *, int, const Instruction *);
112    void recordWr(const Value *, int, int);
113    void checkRd(const Value *, int, int&) const;
114 
115    inline void emitYield(Instruction *);
116    inline void emitStall(Instruction *, uint8_t);
117    inline void emitReuse(Instruction *, uint8_t);
118    inline void emitWrDepBar(Instruction *, uint8_t);
119    inline void emitRdDepBar(Instruction *, uint8_t);
120    inline void emitWtDepBar(Instruction *, uint8_t);
121 
122    inline int getStall(const Instruction *) const;
123    inline int getWrDepBar(const Instruction *) const;
124    inline int getRdDepBar(const Instruction *) const;
125    inline int getWtDepBar(const Instruction *) const;
126 
127    void setReuseFlag(Instruction *);
128 
129    inline void printSchedInfo(int, const Instruction *) const;
130 
131    struct LiveBarUse {
LiveBarUseLiveBarUse132       LiveBarUse(Instruction *insn, Instruction *usei)
133          : insn(insn), usei(usei) { }
134       Instruction *insn;
135       Instruction *usei;
136    };
137 
138    struct LiveBarDef {
LiveBarDefLiveBarDef139       LiveBarDef(Instruction *insn, Instruction *defi)
140          : insn(insn), defi(defi) { }
141       Instruction *insn;
142       Instruction *defi;
143    };
144 
145    bool insertBarriers(BasicBlock *);
146 
147    bool doesInsnWriteTo(const Instruction *insn, const Value *val) const;
148    Instruction *findFirstUse(const Instruction *) const;
149    Instruction *findFirstDef(const Instruction *) const;
150 
151    bool needRdDepBar(const Instruction *) const;
152    bool needWrDepBar(const Instruction *) const;
153 };
154 
155 }; // namespace nv50_ir
156 #endif
157