X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetInstrInfo.cpp;h=d4b76972e49a751a461f5e6765472e11939098d5;hb=157371f376f817b6cbe48f51a006ece2186a5a4c;hp=d1413510fff27578b3c7a5b1f6a08342fa12dd5e;hpb=d9e9efb253978ce4a3683085d1f75c5734143bf9;p=oota-llvm.git diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp index d1413510fff..d4b76972e49 100644 --- a/lib/Target/TargetInstrInfo.cpp +++ b/lib/Target/TargetInstrInfo.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -12,75 +12,168 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Constant.h" -#include "llvm/DerivedTypes.h" +#include "llvm/Target/TargetInstrItineraries.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include using namespace llvm; -/// findTiedToSrcOperand - Returns the operand that is tied to the specified -/// dest operand. Returns -1 if there isn't one. -int TargetInstrDescriptor::findTiedToSrcOperand(unsigned OpNum) const { - for (unsigned i = 0, e = numOperands; i != e; ++i) { - if (i == OpNum) - continue; - if (getOperandConstraint(i, TOI::TIED_TO) == (int)OpNum) - return i; - } - return -1; +//===----------------------------------------------------------------------===// +// TargetOperandInfo +//===----------------------------------------------------------------------===// + +/// 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()) + 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 TargetInstrDescriptor* Desc, +TargetInstrInfo::TargetInstrInfo(const TargetInstrDesc* Desc, unsigned numOpcodes) - : desc(Desc), NumOpcodes(numOpcodes) { + : Descriptors(Desc), NumOpcodes(numOpcodes) { } TargetInstrInfo::~TargetInstrInfo() { } -// commuteInstruction - The default implementation of this method just exchanges -// operand 1 and 2. -MachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr *MI) const { - assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() && - "This only knows how to commute register operands so far"); - unsigned Reg1 = MI->getOperand(1).getReg(); - unsigned Reg2 = MI->getOperand(2).getReg(); - bool Reg1IsKill = MI->getOperand(1).isKill(); - bool Reg2IsKill = MI->getOperand(2).isKill(); - MI->getOperand(2).setReg(Reg1); - MI->getOperand(1).setReg(Reg2); - if (Reg1IsKill) - MI->getOperand(2).setIsKill(); - else - MI->getOperand(2).unsetIsKill(); - if (Reg2IsKill) - MI->getOperand(1).setIsKill(); - else - MI->getOperand(1).unsetIsKill(); - return MI; +unsigned +TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData, + const MachineInstr *MI) const { + if (!ItinData || ItinData->isEmpty()) + return 1; + + unsigned Class = MI->getDesc().getSchedClass(); + unsigned UOps = ItinData->Itineraries[Class].NumMicroOps; + if (UOps) + return UOps; + + // The # of u-ops is dynamically determined. The specific target should + // override this function to return the right number. + 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()); } -bool TargetInstrInfo::PredicateInstruction(MachineInstr *MI, - std::vector &Cond) const { - bool MadeChange = false; - const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); - if (TID->Flags & M_PREDICABLE) { - for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) { - if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) { - MachineOperand &MO = MI->getOperand(i); - if (MO.isReg()) { - MO.setReg(Cond[j].getReg()); - MadeChange = true; - } else if (MO.isImm()) { - MO.setImm(Cond[j].getImmedValue()); - MadeChange = true; - } else if (MO.isMBB()) { - MO.setMachineBasicBlock(Cond[j].getMachineBasicBlock()); - MadeChange = true; - } - ++j; - } +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, + 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; + + // Conditional branch is a special case. + if (TID.isBranch() && !TID.isBarrier()) + return true; + if (!TID.isPredicable()) + return true; + return !isPredicated(MI); +} + + +/// Measure the specified inline asm to determine an approximation of its +/// length. +/// 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 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' || strncmp(Str, MAI.getSeparatorString(), + strlen(MAI.getSeparatorString())) == 0) + atInsnStart = true; + if (atInsnStart && !std::isspace(*Str)) { + Length += MAI.getMaxInstLength(); + atInsnStart = false; } + if (atInsnStart && strncmp(Str, MAI.getCommentString(), + strlen(MAI.getCommentString())) == 0) + atInsnStart = false; } - return MadeChange; + + return Length; }