From e0f992ea7d99e3e70c39cafd33829c00a8552521 Mon Sep 17 00:00:00 2001 From: Andrea Di Biagio Date: Fri, 22 Jun 2018 16:37:05 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335363 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-mca/InstrBuilder.cpp | 8 ++--- tools/llvm-mca/Instruction.h | 71 ++++++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/tools/llvm-mca/InstrBuilder.cpp b/tools/llvm-mca/InstrBuilder.cpp index 6399708b9fa..fd849bb7240 100644 --- a/tools/llvm-mca/InstrBuilder.cpp +++ b/tools/llvm-mca/InstrBuilder.cpp @@ -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; diff --git a/tools/llvm-mca/Instruction.h b/tools/llvm-mca/Instruction.h index dc21e889df8..0837c50506c 100644 --- a/tools/llvm-mca/Instruction.h +++ b/tools/llvm-mca/Instruction.h @@ -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 { -public: - InstRef() : std::pair(0, nullptr) {} - InstRef(unsigned Index, Instruction *I) - : std::pair(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 { +public: + InstRef() : std::pair(0, nullptr) {} + InstRef(unsigned Index, Instruction *I) + : std::pair(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 -- 2.11.0