1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[llvm-mca] Set the operand ID for implicit register reads/writes. NFC

Also, move the definition of InstRef at the end of Instruction.h to avoid a
forward declaration.

llvm-svn: 335363
This commit is contained in:
Andrea Di Biagio 2018-06-22 16:37:05 +00:00
parent 85ee56f371
commit 6a1ca757a7
2 changed files with 43 additions and 36 deletions

View File

@ -219,7 +219,7 @@ static void populateWrites(InstrDesc &ID, const MCInst &MCI,
for (CurrentDef = 0; CurrentDef < NumImplicitDefs; ++CurrentDef) {
unsigned Index = NumExplicitDefs + CurrentDef;
WriteDescriptor &Write = ID.Writes[Index];
Write.OpIndex = -1;
Write.OpIndex = ~CurrentDef;
Write.RegisterID = MCDesc.getImplicitDefs()[CurrentDef];
if (Index < NumWriteLatencyEntries) {
const MCWriteLatencyEntry &WLE =
@ -302,7 +302,7 @@ static void populateReads(InstrDesc &ID, const MCInst &MCI,
for (unsigned CurrentUse = 0; CurrentUse < NumImplicitUses; ++CurrentUse) {
ReadDescriptor &Read = ID.Reads[NumExplicitUses + CurrentUse];
Read.OpIndex = -1;
Read.OpIndex = ~CurrentUse;
Read.UseIndex = NumExplicitUses + CurrentUse;
Read.RegisterID = MCDesc.getImplicitUses()[CurrentUse];
Read.HasReadAdvanceEntries = HasReadAdvanceEntries;
@ -394,7 +394,7 @@ InstrBuilder::createInstruction(const MCInst &MCI) {
// Initialize Reads first.
for (const ReadDescriptor &RD : D.Reads) {
int RegID = -1;
if (RD.OpIndex != -1) {
if (!RD.isImplicitRead()) {
// explicit read.
const MCOperand &Op = MCI.getOperand(RD.OpIndex);
// Skip non-register operands.
@ -431,7 +431,7 @@ InstrBuilder::createInstruction(const MCInst &MCI) {
unsigned WriteIndex = 0;
for (const WriteDescriptor &WD : D.Writes) {
unsigned RegID =
WD.OpIndex == -1 ? WD.RegisterID : MCI.getOperand(WD.OpIndex).getReg();
WD.isImplicitWrite() ? WD.RegisterID : MCI.getOperand(WD.OpIndex).getReg();
// Check if this is a optional definition that references NoReg.
if (WD.IsOptionalDef && !RegID) {
++WriteIndex;

View File

@ -31,39 +31,11 @@ class ReadState;
constexpr int UNKNOWN_CYCLES = -512;
class Instruction;
/// An InstRef contains both a SourceMgr index and Instruction pair. The index
/// is used as a unique identifier for the instruction. MCA will make use of
/// this index as a key throughout MCA.
class InstRef : public std::pair<unsigned, Instruction *> {
public:
InstRef() : std::pair<unsigned, Instruction *>(0, nullptr) {}
InstRef(unsigned Index, Instruction *I)
: std::pair<unsigned, Instruction *>(Index, I) {}
unsigned getSourceIndex() const { return first; }
Instruction *getInstruction() { return second; }
const Instruction *getInstruction() const { return second; }
/// Returns true if this InstRef has been populated.
bool isValid() const { return second != nullptr; }
#ifndef NDEBUG
void print(llvm::raw_ostream &OS) const { OS << getSourceIndex(); }
#endif
};
#ifndef NDEBUG
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InstRef &IR) {
IR.print(OS);
return OS;
}
#endif
/// A register write descriptor.
struct WriteDescriptor {
// Operand index. -1 if this is an implicit write.
// Operand index. The index is negative for implicit writes only.
// For implicit writes, the actual operand index is computed performing
// a bitwise not of the OpIndex.
int OpIndex;
// Write latency. Number of cycles before write-back stage.
int Latency;
@ -83,12 +55,15 @@ struct WriteDescriptor {
// Optional definitions are allowed to reference regID zero (i.e. "no
// register").
bool IsOptionalDef;
bool isImplicitWrite() const { return OpIndex < 0; };
};
/// A register read descriptor.
struct ReadDescriptor {
// A MCOperand index. This is used by the Dispatch logic to identify register
// reads. This field defaults to -1 if this is an implicit read.
// reads. Implicit reads have negative indices. The actual operand index of an
// implicit read is the bitwise not of field OpIndex.
int OpIndex;
// The actual "UseIdx". This is used to query the ReadAdvance table. Explicit
// uses always come first in the sequence of uses.
@ -103,6 +78,8 @@ struct ReadDescriptor {
// used to dynamically check at Instruction creation time, if the input
// operands can benefit from a ReadAdvance bonus.
bool HasReadAdvanceEntries;
bool isImplicitRead() const { return OpIndex < 0; };
};
/// Tracks uses of a register definition (e.g. register write).
@ -198,6 +175,7 @@ public:
const ReadDescriptor &getDescriptor() const { return RD; }
unsigned getSchedClass() const { return RD.SchedClassID; }
unsigned getRegisterID() const { return RegisterID; }
void cycleEvent();
void writeStartEvent(unsigned Cycles);
void setDependentWrites(unsigned Writes) { DependentWrites = Writes; }
@ -368,6 +346,35 @@ public:
void cycleEvent();
};
/// An InstRef contains both a SourceMgr index and Instruction pair. The index
/// is used as a unique identifier for the instruction. MCA will make use of
/// this index as a key throughout MCA.
class InstRef : public std::pair<unsigned, Instruction *> {
public:
InstRef() : std::pair<unsigned, Instruction *>(0, nullptr) {}
InstRef(unsigned Index, Instruction *I)
: std::pair<unsigned, Instruction *>(Index, I) {}
unsigned getSourceIndex() const { return first; }
Instruction *getInstruction() { return second; }
const Instruction *getInstruction() const { return second; }
/// Returns true if this InstRef has been populated.
bool isValid() const { return second != nullptr; }
#ifndef NDEBUG
void print(llvm::raw_ostream &OS) const { OS << getSourceIndex(); }
#endif
};
#ifndef NDEBUG
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InstRef &IR) {
IR.print(OS);
return OS;
}
#endif
} // namespace mca
#endif