X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetInstrInfo.cpp;h=d52ecb32cf752e98faa30aa34aa4aa286fb503ac;hb=91b60c14872883e8dbad73c55ec141ae9f7d4537;hp=47cd0fbe163369f0e95707c5aff6835ba617e30f;hpb=3ef1c8759a20167457eb7fd82ebcaffe7ccaa1d1;p=oota-llvm.git diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp index 47cd0fbe163..d52ecb32cf7 100644 --- a/lib/Target/TargetInstrInfo.cpp +++ b/lib/Target/TargetInstrInfo.cpp @@ -12,50 +12,47 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInstrItineraries.h" #include "llvm/Support/ErrorHandling.h" +#include using namespace llvm; //===----------------------------------------------------------------------===// -// TargetOperandInfo +// TargetInstrInfo //===----------------------------------------------------------------------===// -/// getRegClass - Get the register class for the operand, handling resolution -/// of "symbolic" pointer register classes etc. If this is not a register -/// operand, this returns null. -const TargetRegisterClass * -TargetOperandInfo::getRegClass(const TargetRegisterInfo *TRI) const { - if (isLookupPtrRegClass()) +TargetInstrInfo::~TargetInstrInfo() { +} + +const TargetRegisterClass* +TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum, + const TargetRegisterInfo *TRI) const { + if (OpNum >= MCID.getNumOperands()) + return 0; + + short RegClass = MCID.OpInfo[OpNum].RegClass; + if (MCID.OpInfo[OpNum].isLookupPtrRegClass()) return TRI->getPointerRegClass(RegClass); + // Instructions like INSERT_SUBREG do not have fixed register classes. if (RegClass < 0) return 0; + // Otherwise just look it up normally. return TRI->getRegClass(RegClass); } -//===----------------------------------------------------------------------===// -// TargetInstrInfo -//===----------------------------------------------------------------------===// - -TargetInstrInfo::TargetInstrInfo(const TargetInstrDesc* Desc, - unsigned numOpcodes) - : Descriptors(Desc), NumOpcodes(numOpcodes) { -} - -TargetInstrInfo::~TargetInstrInfo() { -} - unsigned -TargetInstrInfo::getNumMicroOps(const MachineInstr *MI, - const InstrItineraryData *ItinData) const { +TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData, + const MachineInstr *MI) const { if (!ItinData || ItinData->isEmpty()) return 1; unsigned Class = MI->getDesc().getSchedClass(); - unsigned UOps = ItinData->Itineratries[Class].NumMicroOps; + unsigned UOps = ItinData->Itineraries[Class].NumMicroOps; if (UOps) return UOps; @@ -64,22 +61,82 @@ TargetInstrInfo::getNumMicroOps(const MachineInstr *MI, return 1; } +int +TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, + const MachineInstr *DefMI, unsigned DefIdx, + const MachineInstr *UseMI, unsigned UseIdx) const { + if (!ItinData || ItinData->isEmpty()) + return -1; + + unsigned DefClass = DefMI->getDesc().getSchedClass(); + unsigned UseClass = UseMI->getDesc().getSchedClass(); + return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); +} + +int +TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, + SDNode *DefNode, unsigned DefIdx, + SDNode *UseNode, unsigned UseIdx) const { + if (!ItinData || ItinData->isEmpty()) + return -1; + + if (!DefNode->isMachineOpcode()) + return -1; + + unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass(); + if (!UseNode->isMachineOpcode()) + return ItinData->getOperandCycle(DefClass, DefIdx); + unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass(); + return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); +} + +int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, + const MachineInstr *MI, + unsigned *PredCost) const { + if (!ItinData || ItinData->isEmpty()) + return 1; + + return ItinData->getStageLatency(MI->getDesc().getSchedClass()); +} + +int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, + SDNode *N) const { + if (!ItinData || ItinData->isEmpty()) + return 1; + + if (!N->isMachineOpcode()) + return 1; + + return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass()); +} + +bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData, + const MachineInstr *DefMI, + unsigned DefIdx) const { + if (!ItinData || ItinData->isEmpty()) + return false; + + unsigned DefClass = DefMI->getDesc().getSchedClass(); + int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx); + return (DefCycle != -1 && DefCycle <= 1); +} + /// insertNoop - Insert a noop into the instruction stream at the specified /// point. -void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, +void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { llvm_unreachable("Target didn't implement insertNoop!"); } bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { - const TargetInstrDesc &TID = MI->getDesc(); - if (!TID.isTerminator()) return false; - + const MCInstrDesc &MCID = MI->getDesc(); + if (!MCID.isTerminator()) return false; + // Conditional branch is a special case. - if (TID.isBranch() && !TID.isBarrier()) + if (MCID.isBranch() && !MCID.isBarrier()) return true; - if (!TID.isPredicable()) + if (!MCID.isPredicable()) return true; return !isPredicated(MI); } @@ -87,23 +144,24 @@ bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { /// Measure the specified inline asm to determine an approximation of its /// length. -/// Comments (which run till the next SeparatorChar or newline) do not +/// Comments (which run till the next SeparatorString or newline) do not /// count as an instruction. /// Any other non-whitespace text is considered an instruction, with -/// multiple instructions separated by SeparatorChar or newlines. +/// multiple instructions separated by SeparatorString or newlines. /// Variable-length instructions are not handled here; this function /// may be overloaded in the target code to do that. unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const { - - + + // Count the number of instructions in the asm. bool atInsnStart = true; unsigned Length = 0; for (; *Str; ++Str) { - if (*Str == '\n' || *Str == MAI.getSeparatorChar()) + if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), + strlen(MAI.getSeparatorString())) == 0) atInsnStart = true; - if (atInsnStart && !isspace(*Str)) { + if (atInsnStart && !std::isspace(*Str)) { Length += MAI.getMaxInstLength(); atInsnStart = false; } @@ -111,6 +169,6 @@ unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, strlen(MAI.getCommentString())) == 0) atInsnStart = false; } - + return Length; }