loop_predictor.hh (13627:ec1395943cd2) loop_predictor.hh (13685:bb3377c81303)
1/*
2 * Copyright (c) 2014 The University of Wisconsin
3 *
4 * Copyright (c) 2006 INRIA (Institut National de Recherche en
5 * Informatique et en Automatique / French National Research Institute
6 * for Computer Science and Applied Mathematics)
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met: redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer;
14 * redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution;
17 * neither the name of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
34 * from André Seznec's code.
35 */
36
37#ifndef __CPU_PRED_LOOP_PREDICTOR_HH__
38#define __CPU_PRED_LOOP_PREDICTOR_HH__
39
40#include "base/statistics.hh"
41#include "base/types.hh"
42#include "sim/sim_object.hh"
43
44struct LoopPredictorParams;
45
46class LoopPredictor : public SimObject
47{
48 protected:
49 const unsigned logSizeLoopPred;
50 const unsigned loopTableAgeBits;
51 const unsigned loopTableConfidenceBits;
52 const unsigned loopTableTagBits;
53 const unsigned loopTableIterBits;
54 const unsigned logLoopTableAssoc;
55 const uint8_t confidenceThreshold;
56 const uint16_t loopTagMask;
57 const uint16_t loopNumIterMask;
58 const int loopSetMask;
59
60 // Prediction Structures
61 // Loop Predictor Entry
62 struct LoopEntry
63 {
64 uint16_t numIter;
65 uint16_t currentIter;
66 uint16_t currentIterSpec; // only for useSpeculation
67 uint8_t confidence;
68 uint16_t tag;
69 uint8_t age;
70 bool dir; // only for useDirectionBit
71
72 LoopEntry() : numIter(0), currentIter(0), currentIterSpec(0),
73 confidence(0), tag(0), age(0), dir(0) { }
74 };
75
76 LoopEntry *ltable;
77
78 int8_t loopUseCounter;
79 unsigned withLoopBits;
80
81 const bool useDirectionBit;
82 const bool useSpeculation;
83 const bool useHashing;
84 const bool restrictAllocation;
85 const unsigned initialLoopIter;
86 const unsigned initialLoopAge;
87 const bool optionalAgeReset;
88
89 // stats
90 Stats::Scalar loopPredictorCorrect;
91 Stats::Scalar loopPredictorWrong;
92
93 /**
94 * Updates an unsigned counter based on up/down parameter
95 * @param ctr Reference to counter to update.
96 * @param up Boolean indicating if the counter is incremented/decremented
97 * If true it is incremented, if false it is decremented
98 * @param nbits Counter width.
99 */
100 static inline void unsignedCtrUpdate(uint8_t &ctr, bool up, unsigned nbits)
101 {
102 assert(nbits <= sizeof(uint8_t) << 3);
103 if (up) {
104 if (ctr < ((1 << nbits) - 1))
105 ctr++;
106 } else {
107 if (ctr)
108 ctr--;
109 }
110 }
111 static inline void signedCtrUpdate(int8_t &ctr, bool up, unsigned nbits)
112 {
113 if (up) {
114 if (ctr < ((1 << (nbits - 1)) - 1))
115 ctr++;
116 } else {
117 if (ctr > -(1 << (nbits - 1)))
118 ctr--;
119 }
120 }
121 public:
122 // Primary branch history entry
123 struct BranchInfo
124 {
125 uint16_t loopTag;
126 uint16_t currentIter;
127
128 bool loopPred;
129 bool loopPredValid;
130 bool loopPredUsed;
131 int loopIndex;
132 int loopIndexB; // only for useHashing
133 int loopHit;
134 bool predTaken;
135
136 BranchInfo()
137 : loopTag(0), currentIter(0),
138 loopPred(false),
139 loopPredValid(false), loopIndex(0), loopIndexB(0), loopHit(0),
140 predTaken(false)
141 {}
142 };
143
144 /**
145 * Computes the index used to access the
146 * loop predictor.
147 * @param pc_in The unshifted branch PC.
148 * @param instShiftAmt Shift the pc by as many bits
149 */
150 int lindex(Addr pc_in, unsigned instShiftAmt) const;
151
152 /**
153 * Computes the index used to access the
154 * ltable structures.
155 * It may take hashing into account
156 * @param index Result of lindex function
157 * @param lowPcBits PC bits masked with set size
158 * @param way Way to be used
159 */
160 int finallindex(int lindex, int lowPcBits, int way) const;
161
162 /**
163 * Get a branch prediction from the loop
164 * predictor.
165 * @param pc The unshifted branch PC.
166 * @param bi Pointer to information on the
167 * prediction.
168 * @param speculative Use speculative number of iterations
169 * @param instShiftAmt Shift the pc by as many bits (if hashing is not
170 * used)
171 * @result the result of the prediction, if it could be predicted
172 */
173 bool getLoop(Addr pc, BranchInfo* bi, bool speculative,
174 unsigned instShiftAmt) const;
175
176 /**
177 * Updates the loop predictor.
178 * @param pc The unshifted branch PC.
179 * @param taken The actual branch outcome.
180 * @param bi Pointer to information on the
181 * prediction recorded at prediction time.
182 * @param tage_pred tage prediction of the branch
1/*
2 * Copyright (c) 2014 The University of Wisconsin
3 *
4 * Copyright (c) 2006 INRIA (Institut National de Recherche en
5 * Informatique et en Automatique / French National Research Institute
6 * for Computer Science and Applied Mathematics)
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are
12 * met: redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer;
14 * redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution;
17 * neither the name of the copyright holders nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Authors: Vignyan Reddy, Dibakar Gope and Arthur Perais,
34 * from André Seznec's code.
35 */
36
37#ifndef __CPU_PRED_LOOP_PREDICTOR_HH__
38#define __CPU_PRED_LOOP_PREDICTOR_HH__
39
40#include "base/statistics.hh"
41#include "base/types.hh"
42#include "sim/sim_object.hh"
43
44struct LoopPredictorParams;
45
46class LoopPredictor : public SimObject
47{
48 protected:
49 const unsigned logSizeLoopPred;
50 const unsigned loopTableAgeBits;
51 const unsigned loopTableConfidenceBits;
52 const unsigned loopTableTagBits;
53 const unsigned loopTableIterBits;
54 const unsigned logLoopTableAssoc;
55 const uint8_t confidenceThreshold;
56 const uint16_t loopTagMask;
57 const uint16_t loopNumIterMask;
58 const int loopSetMask;
59
60 // Prediction Structures
61 // Loop Predictor Entry
62 struct LoopEntry
63 {
64 uint16_t numIter;
65 uint16_t currentIter;
66 uint16_t currentIterSpec; // only for useSpeculation
67 uint8_t confidence;
68 uint16_t tag;
69 uint8_t age;
70 bool dir; // only for useDirectionBit
71
72 LoopEntry() : numIter(0), currentIter(0), currentIterSpec(0),
73 confidence(0), tag(0), age(0), dir(0) { }
74 };
75
76 LoopEntry *ltable;
77
78 int8_t loopUseCounter;
79 unsigned withLoopBits;
80
81 const bool useDirectionBit;
82 const bool useSpeculation;
83 const bool useHashing;
84 const bool restrictAllocation;
85 const unsigned initialLoopIter;
86 const unsigned initialLoopAge;
87 const bool optionalAgeReset;
88
89 // stats
90 Stats::Scalar loopPredictorCorrect;
91 Stats::Scalar loopPredictorWrong;
92
93 /**
94 * Updates an unsigned counter based on up/down parameter
95 * @param ctr Reference to counter to update.
96 * @param up Boolean indicating if the counter is incremented/decremented
97 * If true it is incremented, if false it is decremented
98 * @param nbits Counter width.
99 */
100 static inline void unsignedCtrUpdate(uint8_t &ctr, bool up, unsigned nbits)
101 {
102 assert(nbits <= sizeof(uint8_t) << 3);
103 if (up) {
104 if (ctr < ((1 << nbits) - 1))
105 ctr++;
106 } else {
107 if (ctr)
108 ctr--;
109 }
110 }
111 static inline void signedCtrUpdate(int8_t &ctr, bool up, unsigned nbits)
112 {
113 if (up) {
114 if (ctr < ((1 << (nbits - 1)) - 1))
115 ctr++;
116 } else {
117 if (ctr > -(1 << (nbits - 1)))
118 ctr--;
119 }
120 }
121 public:
122 // Primary branch history entry
123 struct BranchInfo
124 {
125 uint16_t loopTag;
126 uint16_t currentIter;
127
128 bool loopPred;
129 bool loopPredValid;
130 bool loopPredUsed;
131 int loopIndex;
132 int loopIndexB; // only for useHashing
133 int loopHit;
134 bool predTaken;
135
136 BranchInfo()
137 : loopTag(0), currentIter(0),
138 loopPred(false),
139 loopPredValid(false), loopIndex(0), loopIndexB(0), loopHit(0),
140 predTaken(false)
141 {}
142 };
143
144 /**
145 * Computes the index used to access the
146 * loop predictor.
147 * @param pc_in The unshifted branch PC.
148 * @param instShiftAmt Shift the pc by as many bits
149 */
150 int lindex(Addr pc_in, unsigned instShiftAmt) const;
151
152 /**
153 * Computes the index used to access the
154 * ltable structures.
155 * It may take hashing into account
156 * @param index Result of lindex function
157 * @param lowPcBits PC bits masked with set size
158 * @param way Way to be used
159 */
160 int finallindex(int lindex, int lowPcBits, int way) const;
161
162 /**
163 * Get a branch prediction from the loop
164 * predictor.
165 * @param pc The unshifted branch PC.
166 * @param bi Pointer to information on the
167 * prediction.
168 * @param speculative Use speculative number of iterations
169 * @param instShiftAmt Shift the pc by as many bits (if hashing is not
170 * used)
171 * @result the result of the prediction, if it could be predicted
172 */
173 bool getLoop(Addr pc, BranchInfo* bi, bool speculative,
174 unsigned instShiftAmt) const;
175
176 /**
177 * Updates the loop predictor.
178 * @param pc The unshifted branch PC.
179 * @param taken The actual branch outcome.
180 * @param bi Pointer to information on the
181 * prediction recorded at prediction time.
182 * @param tage_pred tage prediction of the branch
183 * @param random0 random value
184 * @param random1 random value
185 * @param random2 random value
186 */
183 */
187 void loopUpdate(Addr pc, bool Taken, BranchInfo* bi, bool tage_pred,
188 int random0, int random1, int random2);
184 void loopUpdate(Addr pc, bool Taken, BranchInfo* bi, bool tage_pred);
189
190 /**
191 * Speculatively updates the loop predictor
192 * iteration count (only for useSpeculation).
193 * @param taken The predicted branch outcome.
194 * @param bi Pointer to information on the prediction
195 * recorded at prediction time.
196 */
197 void specLoopUpdate(bool taken, BranchInfo* bi);
198
199 /**
200 * Update LTAGE for conditional branches.
201 * @param branch_pc The unshifted branch PC.
202 * @param taken Actual branch outcome.
203 * @param tage_pred Prediction from TAGE
204 * @param bi Pointer to information on the prediction
205 * recorded at prediction time.
206 * @param instShiftAmt Number of bits to shift instructions
185
186 /**
187 * Speculatively updates the loop predictor
188 * iteration count (only for useSpeculation).
189 * @param taken The predicted branch outcome.
190 * @param bi Pointer to information on the prediction
191 * recorded at prediction time.
192 */
193 void specLoopUpdate(bool taken, BranchInfo* bi);
194
195 /**
196 * Update LTAGE for conditional branches.
197 * @param branch_pc The unshifted branch PC.
198 * @param taken Actual branch outcome.
199 * @param tage_pred Prediction from TAGE
200 * @param bi Pointer to information on the prediction
201 * recorded at prediction time.
202 * @param instShiftAmt Number of bits to shift instructions
207 * @param rand0 Random integer value
208 * @param rand1 Random integer value
209 * @param rand2 Random integer value
210 */
203 */
211 void condBranchUpdate(
212 ThreadID tid, Addr branch_pc, bool taken, bool tage_pred,
213 BranchInfo* bi, unsigned instShiftAmt, int rand0, int rand1,
214 int rand2);
204 void condBranchUpdate(ThreadID tid, Addr branch_pc, bool taken,
205 bool tage_pred, BranchInfo* bi, unsigned instShiftAmt);
215
216 /**
217 * Get the loop prediction
218 * @param tid The thread ID to select the global
219 * histories to use.
220 * @param branch_pc The unshifted branch PC.
221 * @param cond_branch True if the branch is conditional.
222 * @param bi Reference to wrapping pointer to allow storing
223 * derived class prediction information in the base class.
224 * @param prev_pred_taken Result of the TAGE prediction
225 * @param instShiftAmt Shift the pc by as many bits
226 * @param instShiftAmt Shift the pc by as many bits
227 * @result the prediction, true if taken
228 */
229 bool loopPredict(
230 ThreadID tid, Addr branch_pc, bool cond_branch,
231 BranchInfo* bi, bool prev_pred_taken, unsigned instShiftAmt);
232
233 /**
234 * Update the stats
235 * @param taken Actual branch outcome
236 * @param bi Pointer to information on the prediction
237 * recorded at prediction time.
238 */
239 void updateStats(bool taken, BranchInfo* bi);
240
241 void squashLoop(BranchInfo * bi);
242
243 void squash(ThreadID tid, BranchInfo *bi);
244
245 virtual bool calcConf(int index) const;
246
206
207 /**
208 * Get the loop prediction
209 * @param tid The thread ID to select the global
210 * histories to use.
211 * @param branch_pc The unshifted branch PC.
212 * @param cond_branch True if the branch is conditional.
213 * @param bi Reference to wrapping pointer to allow storing
214 * derived class prediction information in the base class.
215 * @param prev_pred_taken Result of the TAGE prediction
216 * @param instShiftAmt Shift the pc by as many bits
217 * @param instShiftAmt Shift the pc by as many bits
218 * @result the prediction, true if taken
219 */
220 bool loopPredict(
221 ThreadID tid, Addr branch_pc, bool cond_branch,
222 BranchInfo* bi, bool prev_pred_taken, unsigned instShiftAmt);
223
224 /**
225 * Update the stats
226 * @param taken Actual branch outcome
227 * @param bi Pointer to information on the prediction
228 * recorded at prediction time.
229 */
230 void updateStats(bool taken, BranchInfo* bi);
231
232 void squashLoop(BranchInfo * bi);
233
234 void squash(ThreadID tid, BranchInfo *bi);
235
236 virtual bool calcConf(int index) const;
237
247 virtual bool optionalAgeInc(int nrand) const;
238 virtual bool optionalAgeInc() const;
248
249 virtual BranchInfo *makeBranchInfo();
250
251 /**
252 * Gets the value of the loop use counter
253 * @return the loop use counter value
254 */
255 int8_t getLoopUseCounter() const
256 {
257 return loopUseCounter;
258 }
259
260 /**
261 * Initialize the loop predictor
262 */
263 void init() override;
264
265 /**
266 * Register stats for this object
267 */
268 void regStats() override;
269
270 LoopPredictor(LoopPredictorParams *p);
271};
272#endif//__CPU_PRED_LOOP_PREDICTOR_HH__
239
240 virtual BranchInfo *makeBranchInfo();
241
242 /**
243 * Gets the value of the loop use counter
244 * @return the loop use counter value
245 */
246 int8_t getLoopUseCounter() const
247 {
248 return loopUseCounter;
249 }
250
251 /**
252 * Initialize the loop predictor
253 */
254 void init() override;
255
256 /**
257 * Register stats for this object
258 */
259 void regStats() override;
260
261 LoopPredictor(LoopPredictorParams *p);
262};
263#endif//__CPU_PRED_LOOP_PREDICTOR_HH__