[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 <rdar://problem/14687488>. 


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191916 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Quentin Colombet 2013-10-03 17:51:49 +00:00
parent 45fae28db7
commit 4b3685de23
2 changed files with 34 additions and 1 deletions

View File

@ -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());

View File

@ -75,6 +75,8 @@ private:
llvm::OwningPtr<llvm::MCInstPrinter> 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