From 4b3685de23b4a1b3199a06e4bb2ccd1e316396c3 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Thu, 3 Oct 2013 17:51:49 +0000 Subject: [llvm-c][Disassembler] When printing latency information, fall back to the itinerary model in case the target does not supply a scheduling model. By doing this, targets like cortex-a8 can benefit from the latency printing feature added in r191859. This part of . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191916 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCDisassembler/Disassembler.cpp | 31 ++++++++++++++++++++++++++++++- lib/MC/MCDisassembler/Disassembler.h | 4 ++++ 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'lib/MC') diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp index 115af8d..a0066c8 100644 --- a/lib/MC/MCDisassembler/Disassembler.cpp +++ b/lib/MC/MCDisassembler/Disassembler.cpp @@ -102,6 +102,7 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, if (!DC) return 0; + DC->setCPU(CPU); return DC; } @@ -174,6 +175,32 @@ static void emitComments(LLVMDisasmContext *DC, DC->CommentStream.resync(); } +/// \brief Gets latency information for \p Inst form the itinerary +/// scheduling model, based on \p DC information. +/// \return The maximum expected latency over all the operands or -1 +/// if no information are available. +static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) { + const int NoInformationAvailable = -1; + + // Check if we have a CPU to get the itinerary information. + if (DC->getCPU().empty()) + return NoInformationAvailable; + + // Get itinerary information. + const MCSubtargetInfo *STI = DC->getSubtargetInfo(); + InstrItineraryData IID = STI->getInstrItineraryForCPU(DC->getCPU()); + // Get the scheduling class of the requested instruction. + const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode()); + unsigned SCClass = Desc.getSchedClass(); + + int Latency = 0; + for (unsigned OpIdx = 0, OpIdxEnd = Inst.getNumOperands(); OpIdx != OpIdxEnd; + ++OpIdx) + Latency = std::max(Latency, IID.getOperandCycle(SCClass, OpIdx)); + + return Latency; +} + /// \brief Gets latency information for \p Inst, based on \p DC information. /// \return The maximum expected latency over all the definitions or -1 /// if no information are available. @@ -185,7 +212,9 @@ static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) { // Check if we have a scheduling model for instructions. if (!SCModel || !SCModel->hasInstrSchedModel()) - return NoInformationAvailable; + // Try to fall back to the itinerary model if we do not have a + // scheduling model. + return getItineraryLatency(DC, Inst); // Get the scheduling class of the requested instruction. const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode()); diff --git a/lib/MC/MCDisassembler/Disassembler.h b/lib/MC/MCDisassembler/Disassembler.h index 05c92df..4855af2 100644 --- a/lib/MC/MCDisassembler/Disassembler.h +++ b/lib/MC/MCDisassembler/Disassembler.h @@ -75,6 +75,8 @@ private: llvm::OwningPtr IP; // The options used to set up the disassembler. uint64_t Options; + // The CPU string. + std::string CPU; public: // Comment stream and backing vector. @@ -119,6 +121,8 @@ public: void setIP(MCInstPrinter *NewIP) { IP.reset(NewIP); } uint64_t getOptions() const { return Options; } void addOptions(uint64_t Options) { this->Options |= Options; } + StringRef getCPU() const { return CPU; } + void setCPU(const char *CPU) { this->CPU = CPU; } }; } // namespace llvm -- cgit v1.1