1/*
2 * Copyright (c) 2011-2012, 2014 ARM Limited
3 * Copyright (c) 2010 The University of Edinburgh
4 * Copyright (c) 2012 Mark D. Hill and David A. Wood
5 * All rights reserved
6 *
7 * The license below extends only to copyright in the software and shall
8 * not be construed as granting a license to any other intellectual
9 * property including but not limited to intellectual property relating
10 * to a hardware implementation of the functionality of the software
11 * licensed hereunder.  You may use the software subject to the license
12 * terms below provided that you ensure that this notice is replicated
13 * unmodified and in its entirety in all distributions of the software,
14 * modified or unmodified, in source code or in binary form.
15 *
16 * Copyright (c) 2004-2005 The Regents of The University of Michigan
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * Authors: Kevin Lim
43 */
44
45#include "cpu/pred/bpred_unit.hh"
46
47#include <algorithm>
48
49#include "arch/isa_traits.hh"
50#include "arch/types.hh"
51#include "arch/utility.hh"
52#include "base/trace.hh"
53#include "config/the_isa.hh"
54#include "debug/Branch.hh"
55
56BPredUnit::BPredUnit(const Params *params)
57    : SimObject(params),
58      numThreads(params->numThreads),
59      predHist(numThreads),
60      BTB(params->BTBEntries,
61          params->BTBTagSize,
62          params->instShiftAmt,
63          params->numThreads),
64      RAS(numThreads),
65      iPred(params->indirectBranchPred),
66      instShiftAmt(params->instShiftAmt)
67{
68    for (auto& r : RAS)
69        r.init(params->RASSize);
70}
71
72void
73BPredUnit::regStats()
74{
75    SimObject::regStats();
76
77    lookups
78        .name(name() + ".lookups")
79        .desc("Number of BP lookups")
80        ;
81
82    condPredicted
83        .name(name() + ".condPredicted")
84        .desc("Number of conditional branches predicted")
85        ;
86
87    condIncorrect
88        .name(name() + ".condIncorrect")
89        .desc("Number of conditional branches incorrect")
90        ;
91
92    BTBLookups
93        .name(name() + ".BTBLookups")
94        .desc("Number of BTB lookups")
95        ;
96
97    BTBHits
98        .name(name() + ".BTBHits")
99        .desc("Number of BTB hits")
100        ;
101
102    BTBCorrect
103        .name(name() + ".BTBCorrect")
104        .desc("Number of correct BTB predictions (this stat may not "
105              "work properly.")
106        ;
107
108    BTBHitPct
109        .name(name() + ".BTBHitPct")
110        .desc("BTB Hit Percentage")
111        .precision(6);
112    BTBHitPct = (BTBHits / BTBLookups) * 100;
113
114    usedRAS
115        .name(name() + ".usedRAS")
116        .desc("Number of times the RAS was used to get a target.")
117        ;
118
119    RASIncorrect
120        .name(name() + ".RASInCorrect")
121        .desc("Number of incorrect RAS predictions.")
122        ;
123
124    indirectLookups
125        .name(name() + ".indirectLookups")
126        .desc("Number of indirect predictor lookups.")
127        ;
128
129    indirectHits
130        .name(name() + ".indirectHits")
131        .desc("Number of indirect target hits.")
132        ;
133
134    indirectMisses
135        .name(name() + ".indirectMisses")
136        .desc("Number of indirect misses.")
137        ;
138
139    indirectMispredicted
140        .name(name() + "indirectMispredicted")
141        .desc("Number of mispredicted indirect branches.")
142        ;
143
144}
145
146ProbePoints::PMUUPtr
147BPredUnit::pmuProbePoint(const char *name)
148{
149    ProbePoints::PMUUPtr ptr;
150    ptr.reset(new ProbePoints::PMU(getProbeManager(), name));
151
152    return ptr;
153}
154
155void
156BPredUnit::regProbePoints()
157{
158    ppBranches = pmuProbePoint("Branches");
159    ppMisses = pmuProbePoint("Misses");
160}
161
162void
163BPredUnit::drainSanityCheck() const
164{
165    // We shouldn't have any outstanding requests when we resume from
166    // a drained system.
167    for (const auto& ph M5_VAR_USED : predHist)
168        assert(ph.empty());
169}
170
171bool
172BPredUnit::predict(const StaticInstPtr &inst, const InstSeqNum &seqNum,
173                   TheISA::PCState &pc, ThreadID tid)
174{
175    // See if branch predictor predicts taken.
176    // If so, get its target addr either from the BTB or the RAS.
177    // Save off record of branch stuff so the RAS can be fixed
178    // up once it's done.
179
180    bool pred_taken = false;
181    TheISA::PCState target = pc;
182
183    ++lookups;
184    ppBranches->notify(1);
185
186    void *bp_history = NULL;
187    void *indirect_history = NULL;
188
189    if (inst->isUncondCtrl()) {
190        DPRINTF(Branch, "[tid:%i] [sn:%llu] "
191            "Unconditional control\n",
192            tid,seqNum);
193        pred_taken = true;
194        // Tell the BP there was an unconditional branch.
195        uncondBranch(tid, pc.instAddr(), bp_history);
196    } else {
197        ++condPredicted;
198        pred_taken = lookup(tid, pc.instAddr(), bp_history);
199
200        DPRINTF(Branch, "[tid:%i] [sn:%llu] "
201                "Branch predictor predicted %i for PC %s\n",
202                tid, seqNum,  pred_taken, pc);
203    }
204
205    const bool orig_pred_taken = pred_taken;
206    if (iPred) {
207        iPred->genIndirectInfo(tid, indirect_history);
208    }
209
210    DPRINTF(Branch, "[tid:%i] [sn:%llu] "
211            "Creating prediction history "
212            "for PC %s\n", tid, seqNum, pc);
213
214    PredictorHistory predict_record(seqNum, pc.instAddr(), pred_taken,
215                                    bp_history, indirect_history, tid, inst);
216
217    // Now lookup in the BTB or RAS.
218    if (pred_taken) {
219        if (inst->isReturn()) {
220            ++usedRAS;
221            predict_record.wasReturn = true;
222            // If it's a function return call, then look up the address
223            // in the RAS.
224            TheISA::PCState rasTop = RAS[tid].top();
225            target = TheISA::buildRetPC(pc, rasTop);
226
227            // Record the top entry of the RAS, and its index.
228            predict_record.usedRAS = true;
229            predict_record.RASIndex = RAS[tid].topIdx();
230            predict_record.RASTarget = rasTop;
231
232            RAS[tid].pop();
233
234            DPRINTF(Branch, "[tid:%i] [sn:%llu] Instruction %s is a return, "
235                    "RAS predicted target: %s, RAS index: %i\n",
236                    tid, seqNum, pc, target, predict_record.RASIndex);
237        } else {
238            ++BTBLookups;
239
240            if (inst->isCall()) {
241                RAS[tid].push(pc);
242                predict_record.pushedRAS = true;
243
244                // Record that it was a call so that the top RAS entry can
245                // be popped off if the speculation is incorrect.
246                predict_record.wasCall = true;
247
248                DPRINTF(Branch,
249                        "[tid:%i] [sn:%llu] Instruction %s was a call, adding "
250                        "%s to the RAS index: %i\n",
251                        tid, seqNum, pc, pc, RAS[tid].topIdx());
252            }
253
254            if (inst->isDirectCtrl() || !iPred) {
255                // Check BTB on direct branches
256                if (BTB.valid(pc.instAddr(), tid)) {
257                    ++BTBHits;
258                    // If it's not a return, use the BTB to get target addr.
259                    target = BTB.lookup(pc.instAddr(), tid);
260                    DPRINTF(Branch,
261                            "[tid:%i] [sn:%llu] Instruction %s predicted "
262                            "target is %s\n",
263                            tid, seqNum, pc, target);
264                } else {
265                    DPRINTF(Branch, "[tid:%i] [sn:%llu] BTB doesn't have a "
266                            "valid entry\n",tid,seqNum);
267                    pred_taken = false;
268                    // The Direction of the branch predictor is altered
269                    // because the BTB did not have an entry
270                    // The predictor needs to be updated accordingly
271                    if (!inst->isCall() && !inst->isReturn()) {
272                        btbUpdate(tid, pc.instAddr(), bp_history);
273                        DPRINTF(Branch,
274                                "[tid:%i] [sn:%llu] btbUpdate "
275                                "called for %s\n",
276                                tid, seqNum, pc);
277                    } else if (inst->isCall() && !inst->isUncondCtrl()) {
278                        RAS[tid].pop();
279                        predict_record.pushedRAS = false;
280                    }
281                    TheISA::advancePC(target, inst);
282                }
283            } else {
284                predict_record.wasIndirect = true;
285                ++indirectLookups;
286                //Consult indirect predictor on indirect control
287                if (iPred->lookup(pc.instAddr(), target, tid)) {
288                    // Indirect predictor hit
289                    ++indirectHits;
290                    DPRINTF(Branch,
291                            "[tid:%i] [sn:%llu] "
292                            "Instruction %s predicted "
293                            "indirect target is %s\n",
294                            tid, seqNum, pc, target);
295                } else {
296                    ++indirectMisses;
297                    pred_taken = false;
298                    DPRINTF(Branch,
299                            "[tid:%i] [sn:%llu] "
300                            "Instruction %s no indirect "
301                            "target\n",
302                            tid, seqNum, pc);
303                    if (!inst->isCall() && !inst->isReturn()) {
304
305                    } else if (inst->isCall() && !inst->isUncondCtrl()) {
306                        RAS[tid].pop();
307                        predict_record.pushedRAS = false;
308                    }
309                    TheISA::advancePC(target, inst);
310                }
311                iPred->recordIndirect(pc.instAddr(), target.instAddr(), seqNum,
312                        tid);
313            }
314        }
315    } else {
316        if (inst->isReturn()) {
317           predict_record.wasReturn = true;
318        }
319        TheISA::advancePC(target, inst);
320    }
321    predict_record.target = target.instAddr();
322
323    pc = target;
324
325    if (iPred) {
326        // Update the indirect predictor with the direction prediction
327        // Note that this happens after indirect lookup, so it does not use
328        // the new information
329        // Note also that we use orig_pred_taken instead of pred_taken in
330        // as this is the actual outcome of the direction prediction
331        iPred->updateDirectionInfo(tid, orig_pred_taken);
332    }
333
334    predHist[tid].push_front(predict_record);
335
336    DPRINTF(Branch,
337            "[tid:%i] [sn:%llu] History entry added. "
338            "predHist.size(): %i\n",
339            tid, seqNum, predHist[tid].size());
340
341    return pred_taken;
342}
343
344void
345BPredUnit::update(const InstSeqNum &done_sn, ThreadID tid)
346{
347    DPRINTF(Branch, "[tid:%i] Committing branches until "
348            "sn:%llu]\n", tid, done_sn);
349
350    while (!predHist[tid].empty() &&
351           predHist[tid].back().seqNum <= done_sn) {
352        // Update the branch predictor with the correct results.
353        update(tid, predHist[tid].back().pc,
354                    predHist[tid].back().predTaken,
355                    predHist[tid].back().bpHistory, false,
356                    predHist[tid].back().inst,
357                    predHist[tid].back().target);
358
359        if (iPred) {
360            iPred->commit(done_sn, tid, predHist[tid].back().indirectHistory);
361        }
362
363        predHist[tid].pop_back();
364    }
365}
366
367void
368BPredUnit::squash(const InstSeqNum &squashed_sn, ThreadID tid)
369{
370    History &pred_hist = predHist[tid];
371
372    if (iPred) {
373        iPred->squash(squashed_sn, tid);
374    }
375
376    while (!pred_hist.empty() &&
377           pred_hist.front().seqNum > squashed_sn) {
378        if (pred_hist.front().usedRAS) {
379            DPRINTF(Branch, "[tid:%i] [squash sn:%llu]"
380                    " Restoring top of RAS to: %i,"
381                    " target: %s\n", tid, squashed_sn,
382                    pred_hist.front().RASIndex, pred_hist.front().RASTarget);
383
384            RAS[tid].restore(pred_hist.front().RASIndex,
385                             pred_hist.front().RASTarget);
386        } else if (pred_hist.front().wasCall && pred_hist.front().pushedRAS) {
387             // Was a call but predicated false. Pop RAS here
388             DPRINTF(Branch, "[tid:%i] [squash sn:%llu] Squashing"
389                     "  Call [sn:%llu] PC: %s Popping RAS\n", tid, squashed_sn,
390                     pred_hist.front().seqNum, pred_hist.front().pc);
391             RAS[tid].pop();
392        }
393
394        // This call should delete the bpHistory.
395        squash(tid, pred_hist.front().bpHistory);
396        if (iPred) {
397            iPred->deleteIndirectInfo(tid, pred_hist.front().indirectHistory);
398        }
399
400        DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
401                "Removing history for [sn:%llu] "
402                "PC %#x\n", tid, squashed_sn, pred_hist.front().seqNum,
403                pred_hist.front().pc);
404
405        pred_hist.pop_front();
406
407        DPRINTF(Branch, "[tid:%i] [squash sn:%llu] predHist.size(): %i\n",
408                tid, squashed_sn, predHist[tid].size());
409    }
410}
411
412void
413BPredUnit::squash(const InstSeqNum &squashed_sn,
414                  const TheISA::PCState &corrTarget,
415                  bool actually_taken, ThreadID tid)
416{
417    // Now that we know that a branch was mispredicted, we need to undo
418    // all the branches that have been seen up until this branch and
419    // fix up everything.
420    // NOTE: This should be call conceivably in 2 scenarios:
421    // (1) After an branch is executed, it updates its status in the ROB
422    //     The commit stage then checks the ROB update and sends a signal to
423    //     the fetch stage to squash history after the mispredict
424    // (2) In the decode stage, you can find out early if a unconditional
425    //     PC-relative, branch was predicted incorrectly. If so, a signal
426    //     to the fetch stage is sent to squash history after the mispredict
427
428    History &pred_hist = predHist[tid];
429
430    ++condIncorrect;
431    ppMisses->notify(1);
432
433    DPRINTF(Branch, "[tid:%i] Squashing from sequence number %i, "
434            "setting target to %s\n", tid, squashed_sn, corrTarget);
435
436    // Squash All Branches AFTER this mispredicted branch
437    squash(squashed_sn, tid);
438
439    // If there's a squash due to a syscall, there may not be an entry
440    // corresponding to the squash.  In that case, don't bother trying to
441    // fix up the entry.
442    if (!pred_hist.empty()) {
443
444        auto hist_it = pred_hist.begin();
445        //HistoryIt hist_it = find(pred_hist.begin(), pred_hist.end(),
446        //                       squashed_sn);
447
448        //assert(hist_it != pred_hist.end());
449        if (pred_hist.front().seqNum != squashed_sn) {
450            DPRINTF(Branch, "Front sn %i != Squash sn %i\n",
451                    pred_hist.front().seqNum, squashed_sn);
452
453            assert(pred_hist.front().seqNum == squashed_sn);
454        }
455
456
457        if ((*hist_it).usedRAS) {
458            ++RASIncorrect;
459            DPRINTF(Branch,
460                    "[tid:%i] [squash sn:%llu] Incorrect RAS [sn:%llu]\n",
461                    tid, squashed_sn, hist_it->seqNum);
462        }
463
464        // There are separate functions for in-order and out-of-order
465        // branch prediction, but not for update. Therefore, this
466        // call should take into account that the mispredicted branch may
467        // be on the wrong path (i.e., OoO execution), and that the counter
468        // counter table(s) should not be updated. Thus, this call should
469        // restore the state of the underlying predictor, for instance the
470        // local/global histories. The counter tables will be updated when
471        // the branch actually commits.
472
473        // Remember the correct direction for the update at commit.
474        pred_hist.front().predTaken = actually_taken;
475        pred_hist.front().target = corrTarget.instAddr();
476
477        update(tid, (*hist_it).pc, actually_taken,
478               pred_hist.front().bpHistory, true, pred_hist.front().inst,
479               corrTarget.instAddr());
480
481        if (iPred) {
482            iPred->changeDirectionPrediction(tid,
483                pred_hist.front().indirectHistory, actually_taken);
484        }
485
486        if (actually_taken) {
487            if (hist_it->wasReturn && !hist_it->usedRAS) {
488                 DPRINTF(Branch, "[tid:%i] [squash sn:%llu] "
489                        "Incorrectly predicted "
490                        "return [sn:%llu] PC: %#x\n", tid, squashed_sn,
491                        hist_it->seqNum,
492                        hist_it->pc);
493                 RAS[tid].pop();
494                 hist_it->usedRAS = true;
495            }
496            if (hist_it->wasIndirect) {
497                ++indirectMispredicted;
498                if (iPred) {
499                    iPred->recordTarget(
500                        hist_it->seqNum, pred_hist.front().indirectHistory,
501                        corrTarget, tid);
502                }
503            } else {
504                DPRINTF(Branch,"[tid:%i] [squash sn:%llu] "
505                        "BTB Update called for [sn:%llu] "
506                        "PC %#x\n", tid, squashed_sn,
507                        hist_it->seqNum, hist_it->pc);
508
509                BTB.update((*hist_it).pc, corrTarget, tid);
510            }
511        } else {
512           //Actually not Taken
513           if (hist_it->usedRAS) {
514                DPRINTF(Branch,
515                        "[tid:%i] [squash sn:%llu] Incorrectly predicted "
516                        "return [sn:%llu] PC: %#x Restoring RAS\n", tid,
517                        squashed_sn,
518                        hist_it->seqNum, hist_it->pc);
519                DPRINTF(Branch,
520                        "[tid:%i] [squash sn:%llu] Restoring top of RAS "
521                        "to: %i, target: %s\n", tid, squashed_sn,
522                        hist_it->RASIndex, hist_it->RASTarget);
523                RAS[tid].restore(hist_it->RASIndex, hist_it->RASTarget);
524                hist_it->usedRAS = false;
525           } else if (hist_it->wasCall && hist_it->pushedRAS) {
526                 //Was a Call but predicated false. Pop RAS here
527                 DPRINTF(Branch,
528                        "[tid:%i] [squash sn:%llu] "
529                        "Incorrectly predicted "
530                        "Call [sn:%llu] PC: %s Popping RAS\n",
531                        tid, squashed_sn,
532                        hist_it->seqNum, hist_it->pc);
533                 RAS[tid].pop();
534                 hist_it->pushedRAS = false;
535           }
536        }
537    } else {
538        DPRINTF(Branch, "[tid:%i] [sn:%llu] pred_hist empty, can't "
539                "update\n", tid, squashed_sn);
540    }
541}
542
543void
544BPredUnit::dump()
545{
546    int i = 0;
547    for (const auto& ph : predHist) {
548        if (!ph.empty()) {
549            auto pred_hist_it = ph.begin();
550
551            cprintf("predHist[%i].size(): %i\n", i++, ph.size());
552
553            while (pred_hist_it != ph.end()) {
554                cprintf("sn:%llu], PC:%#x, tid:%i, predTaken:%i, "
555                        "bpHistory:%#x\n",
556                        pred_hist_it->seqNum, pred_hist_it->pc,
557                        pred_hist_it->tid, pred_hist_it->predTaken,
558                        pred_hist_it->bpHistory);
559                pred_hist_it++;
560            }
561
562            cprintf("\n");
563        }
564    }
565}
566
567