Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===---------------------- RetireControlUnit.h -----------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
/// \file
9
///
10
/// This file simulates the hardware responsible for retiring instructions.
11
///
12
//===----------------------------------------------------------------------===//
13
 
14
#ifndef LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H
15
#define LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H
16
 
17
#include "llvm/MC/MCSchedule.h"
18
#include "llvm/MCA/HardwareUnits/HardwareUnit.h"
19
#include "llvm/MCA/Instruction.h"
20
#include <vector>
21
 
22
namespace llvm {
23
namespace mca {
24
 
25
/// This class tracks which instructions are in-flight (i.e., dispatched but not
26
/// retired) in the OoO backend.
27
//
28
/// This class checks on every cycle if/which instructions can be retired.
29
/// Instructions are retired in program order.
30
/// In the event of an instruction being retired, the pipeline that owns
31
/// this RetireControlUnit (RCU) gets notified.
32
///
33
/// On instruction retired, register updates are all architecturally
34
/// committed, and any physicall registers previously allocated for the
35
/// retired instruction are freed.
36
struct RetireControlUnit : public HardwareUnit {
37
  // A RUToken is created by the RCU for every instruction dispatched to the
38
  // schedulers.  These "tokens" are managed by the RCU in its token Queue.
39
  //
40
  // On every cycle ('cycleEvent'), the RCU iterates through the token queue
41
  // looking for any token with its 'Executed' flag set.  If a token has that
42
  // flag set, then the instruction has reached the write-back stage and will
43
  // be retired by the RCU.
44
  //
45
  // 'NumSlots' represents the number of entries consumed by the instruction in
46
  // the reorder buffer. Those entries will become available again once the
47
  // instruction is retired.
48
  //
49
  // Note that the size of the reorder buffer is defined by the scheduling
50
  // model via field 'NumMicroOpBufferSize'.
51
  struct RUToken {
52
    InstRef IR;
53
    unsigned NumSlots; // Slots reserved to this instruction.
54
    bool Executed;     // True if the instruction is past the WB stage.
55
  };
56
 
57
private:
58
  unsigned NextAvailableSlotIdx;
59
  unsigned CurrentInstructionSlotIdx;
60
  unsigned NumROBEntries;
61
  unsigned AvailableEntries;
62
  unsigned MaxRetirePerCycle; // 0 means no limit.
63
  std::vector<RUToken> Queue;
64
 
65
  unsigned normalizeQuantity(unsigned Quantity) const {
66
    // Some instructions may declare a number of uOps which exceeds the size
67
    // of the reorder buffer. To avoid problems, cap the amount of slots to
68
    // the size of the reorder buffer.
69
    Quantity = std::min(Quantity, NumROBEntries);
70
 
71
    // Further normalize the number of micro opcodes for instructions that
72
    // declare zero opcodes. This should match the behavior of method
73
    // reserveSlot().
74
    return std::max(Quantity, 1U);
75
  }
76
 
77
  unsigned computeNextSlotIdx() const;
78
 
79
public:
80
  RetireControlUnit(const MCSchedModel &SM);
81
 
82
  bool isEmpty() const { return AvailableEntries == NumROBEntries; }
83
 
84
  bool isAvailable(unsigned Quantity = 1) const {
85
    return AvailableEntries >= normalizeQuantity(Quantity);
86
  }
87
 
88
  unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; }
89
 
90
  // Reserves a number of slots, and returns a new token reference.
91
  unsigned dispatch(const InstRef &IS);
92
 
93
  // Return the current token from the RCU's circular token queue.
94
  const RUToken &getCurrentToken() const;
95
 
96
  const RUToken &peekNextToken() const;
97
 
98
  // Advance the pointer to the next token in the circular token queue.
99
  void consumeCurrentToken();
100
 
101
  // Update the RCU token to represent the executed state.
102
  void onInstructionExecuted(unsigned TokenID);
103
 
104
#ifndef NDEBUG
105
  void dump() const;
106
#endif
107
 
108
  // Assigned to instructions that are not handled by the RCU.
109
  static const unsigned UnhandledTokenID = ~0U;
110
};
111
 
112
} // namespace mca
113
} // namespace llvm
114
 
115
#endif // LLVM_MCA_HARDWAREUNITS_RETIRECONTROLUNIT_H