X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachineInstr.cpp;h=911d5caa1d331d5267a569acd336552d00db3582;hb=420cdebbcb95f3881ab3518fd3bb670837669e43;hp=0de5501b78d30ed65c1824d8db014c7b38f3ebba;hpb=e138b3dd1ff02d826233482831318708a166ed93;p=oota-llvm.git diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 0de5501b78d..911d5caa1d3 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -11,13 +11,17 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constants.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/Value.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/MRegisterInfo.h" +#include "llvm/Target/TargetInstrDesc.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/Streams.h" #include @@ -42,17 +46,23 @@ void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) { } // Otherwise, add this operand to the head of the registers use/def list. - MachineOperand *&Head = RegInfo->getRegUseDefListHead(getReg()); + MachineOperand **Head = &RegInfo->getRegUseDefListHead(getReg()); - Contents.Reg.Next = Head; + // For SSA values, we prefer to keep the definition at the start of the list. + // we do this by skipping over the definition if it is at the head of the + // list. + if (*Head && (*Head)->isDef()) + Head = &(*Head)->Contents.Reg.Next; + + Contents.Reg.Next = *Head; if (Contents.Reg.Next) { assert(getReg() == Contents.Reg.Next->getReg() && "Different regs on the same list!"); Contents.Reg.Next->Contents.Reg.Prev = &Contents.Reg.Next; } - Contents.Reg.Prev = &Head; - Head = this; + Contents.Reg.Prev = Head; + *Head = this; } void MachineOperand::setReg(unsigned Reg) { @@ -129,6 +139,8 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { getSubReg() == Other.getSubReg(); case MachineOperand::MO_Immediate: return getImm() == Other.getImm(); + case MachineOperand::MO_FPImmediate: + return getFPImm() == Other.getFPImm(); case MachineOperand::MO_MachineBasicBlock: return getMBB() == Other.getMBB(); case MachineOperand::MO_FrameIndex: @@ -150,7 +162,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { void MachineOperand::print(std::ostream &OS, const TargetMachine *TM) const { switch (getType()) { case MachineOperand::MO_Register: - if (getReg() == 0 || MRegisterInfo::isVirtualRegister(getReg())) { + if (getReg() == 0 || TargetRegisterInfo::isVirtualRegister(getReg())) { OS << "%reg" << getReg(); } else { // If the instruction is embedded into a basic block, we can find the @@ -188,6 +200,13 @@ void MachineOperand::print(std::ostream &OS, const TargetMachine *TM) const { case MachineOperand::MO_Immediate: OS << getImm(); break; + case MachineOperand::MO_FPImmediate: + if (getFPImm()->getType() == Type::FloatTy) { + OS << getFPImm()->getValueAPF().convertToFloat(); + } else { + OS << getFPImm()->getValueAPF().convertToDouble(); + } + break; case MachineOperand::MO_MachineBasicBlock: OS << "mbb<" << ((Value*)getMBB()->getBasicBlock())->getName() @@ -242,17 +261,17 @@ void MachineInstr::addImplicitDefUseOperands() { /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by -/// TargetInstrDescriptor or the numOperands if it is not zero. (for +/// TargetInstrDesc or the numOperands if it is not zero. (for /// instructions with variable number of operands). -MachineInstr::MachineInstr(const TargetInstrDescriptor &tid, bool NoImp) +MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) : TID(&tid), NumImplicitOps(0), Parent(0) { - if (!NoImp && TID->ImplicitDefs) - for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) + if (!NoImp && TID->getImplicitDefs()) + for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) NumImplicitOps++; - if (!NoImp && TID->ImplicitUses) - for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + if (!NoImp && TID->getImplicitUses()) + for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses) NumImplicitOps++; - Operands.reserve(NumImplicitOps + TID->numOperands); + Operands.reserve(NumImplicitOps + TID->getNumOperands()); if (!NoImp) addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock @@ -263,16 +282,16 @@ MachineInstr::MachineInstr(const TargetInstrDescriptor &tid, bool NoImp) /// MachineInstr is created and added to the end of the specified basic block. /// MachineInstr::MachineInstr(MachineBasicBlock *MBB, - const TargetInstrDescriptor &tid) + const TargetInstrDesc &tid) : TID(&tid), NumImplicitOps(0), Parent(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); if (TID->ImplicitDefs) - for (const unsigned *ImpDefs = TID->ImplicitDefs; *ImpDefs; ++ImpDefs) + for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) NumImplicitOps++; if (TID->ImplicitUses) - for (const unsigned *ImpUses = TID->ImplicitUses; *ImpUses; ++ImpUses) + for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses) NumImplicitOps++; - Operands.reserve(NumImplicitOps + TID->numOperands); + Operands.reserve(NumImplicitOps + TID->getNumOperands()); addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); @@ -282,9 +301,10 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(const MachineInstr &MI) { - TID = MI.getInstrDescriptor(); + TID = &MI.getDesc(); NumImplicitOps = MI.NumImplicitOps; Operands.reserve(MI.getNumOperands()); + MemOperands = MI.MemOperands; // Add operands for (unsigned i = 0; i != MI.getNumOperands(); ++i) { @@ -481,9 +501,8 @@ MachineInstr *MachineInstr::removeFromParent() { /// OperandComplete - Return true if it's illegal to add a new operand /// bool MachineInstr::OperandsComplete() const { - unsigned short NumOperands = TID->numOperands; - if ((TID->Flags & M_VARIABLE_OPS) == 0 && - getNumOperands()-NumImplicitOps >= NumOperands) + unsigned short NumOperands = TID->getNumOperands(); + if (!TID->isVariadic() && getNumOperands()-NumImplicitOps >= NumOperands) return true; // Broken: we have all the operands of this instruction! return false; } @@ -491,8 +510,8 @@ bool MachineInstr::OperandsComplete() const { /// getNumExplicitOperands - Returns the number of non-implicit operands. /// unsigned MachineInstr::getNumExplicitOperands() const { - unsigned NumOperands = TID->numOperands; - if ((TID->Flags & M_VARIABLE_OPS) == 0) + unsigned NumOperands = TID->getNumOperands(); + if (!TID->isVariadic()) return NumOperands; for (unsigned e = getNumOperands(); NumOperands != e; ++NumOperands) { @@ -504,6 +523,12 @@ unsigned MachineInstr::getNumExplicitOperands() const { } +/// isDebugLabel - Returns true if the MachineInstr represents a debug label. +/// +bool MachineInstr::isDebugLabel() const { + return getOpcode() == TargetInstrInfo::LABEL && getOperand(1).getImm() == 0; +} + /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of /// the specific register or -1 if it is not found. It further tightening /// the search criteria to a use that kills the register if isKill is true. @@ -532,10 +557,10 @@ MachineOperand *MachineInstr::findRegisterDefOperand(unsigned Reg) { /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int MachineInstr::findFirstPredOperandIdx() const { - const TargetInstrDescriptor *TID = getInstrDescriptor(); - if (TID->Flags & M_PREDICABLE) { + const TargetInstrDesc &TID = getDesc(); + if (TID.isPredicable()) { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) + if (TID.OpInfo[i].isPredicate()) return i; } @@ -545,14 +570,14 @@ int MachineInstr::findFirstPredOperandIdx() const { /// isRegReDefinedByTwoAddr - Returns true if the Reg re-definition is due /// to two addr elimination. bool MachineInstr::isRegReDefinedByTwoAddr(unsigned Reg) const { - const TargetInstrDescriptor *TID = getInstrDescriptor(); + const TargetInstrDesc &TID = getDesc(); for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { const MachineOperand &MO1 = getOperand(i); if (MO1.isRegister() && MO1.isDef() && MO1.getReg() == Reg) { for (unsigned j = i+1; j < e; ++j) { const MachineOperand &MO2 = getOperand(j); if (MO2.isRegister() && MO2.isUse() && MO2.getReg() == Reg && - TID->getOperandConstraint(j, TOI::TIED_TO) == (int)i) + TID.getOperandConstraint(j, TOI::TIED_TO) == (int)i) return true; } } @@ -582,10 +607,10 @@ void MachineInstr::copyKillDeadInfo(const MachineInstr *MI) { /// copyPredicates - Copies predicate operand(s) from MI. void MachineInstr::copyPredicates(const MachineInstr *MI) { - const TargetInstrDescriptor *TID = MI->getInstrDescriptor(); - if (TID->Flags & M_PREDICABLE) { + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.isPredicable()) { for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - if ((TID->OpInfo[i].Flags & M_PREDICATE_OPERAND)) { + if (TID.OpInfo[i].isPredicate()) { // Predicated operands must be last operands. addOperand(MI->getOperand(i)); } @@ -606,7 +631,7 @@ void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { ++StartOp; // Don't print this operand again! } - OS << getInstrDescriptor()->Name; + OS << getDesc().getName(); for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { if (i != StartOp) @@ -615,6 +640,128 @@ void MachineInstr::print(std::ostream &OS, const TargetMachine *TM) const { getOperand(i).print(OS, TM); } + if (getNumMemOperands() > 0) { + OS << ", Mem:"; + for (unsigned i = 0; i < getNumMemOperands(); i++) { + const MemOperand &MRO = getMemOperand(i); + const Value *V = MRO.getValue(); + + assert((MRO.isLoad() || MRO.isStore()) && + "SV has to be a load, store or both."); + + if (MRO.isVolatile()) + OS << "Volatile "; + + if (MRO.isLoad()) + OS << "LD"; + if (MRO.isStore()) + OS << "ST"; + + OS << "(" << MRO.getSize() << "," << MRO.getAlignment() << ") ["; + + if (!V) + OS << ""; + else if (!V->getName().empty()) + OS << V->getName(); + else if (isa(V)) + OS << *V; + else + OS << V; + + OS << " + " << MRO.getOffset() << "]"; + } + } + OS << "\n"; } +bool MachineInstr::addRegisterKilled(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo, + bool AddIfNotFound) { + bool Found = false; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isUse()) { + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (Reg == IncomingReg) { + MO.setIsKill(); + Found = true; + break; + } else if (TargetRegisterInfo::isPhysicalRegister(Reg) && + TargetRegisterInfo::isPhysicalRegister(IncomingReg) && + RegInfo->isSuperRegister(IncomingReg, Reg) && + MO.isKill()) + // A super-register kill already exists. + Found = true; + } + } + + // If not found, this means an alias of one of the operand is killed. Add a + // new implicit operand if required. + if (!Found && AddIfNotFound) { + addOperand(MachineOperand::CreateReg(IncomingReg, false/*IsDef*/, + true/*IsImp*/,true/*IsKill*/)); + return true; + } + return Found; +} + +bool MachineInstr::addRegisterDead(unsigned IncomingReg, + const TargetRegisterInfo *RegInfo, + bool AddIfNotFound) { + bool Found = false; + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + MachineOperand &MO = getOperand(i); + if (MO.isRegister() && MO.isDef()) { + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + if (Reg == IncomingReg) { + MO.setIsDead(); + Found = true; + break; + } else if (TargetRegisterInfo::isPhysicalRegister(Reg) && + TargetRegisterInfo::isPhysicalRegister(IncomingReg) && + RegInfo->isSuperRegister(IncomingReg, Reg) && + MO.isDead()) + // There exists a super-register that's marked dead. + return true; + } + } + + // If not found, this means an alias of one of the operand is dead. Add a + // new implicit operand. + if (!Found && AddIfNotFound) { + addOperand(MachineOperand::CreateReg(IncomingReg, true/*IsDef*/, + true/*IsImp*/,false/*IsKill*/, + true/*IsDead*/)); + return true; + } + return Found; +} + +/// copyKillDeadInfo - copies killed/dead information from one instr to another +void MachineInstr::copyKillDeadInfo(MachineInstr *OldMI, + const TargetRegisterInfo *RegInfo) { + // If the instruction defines any virtual registers, update the VarInfo, + // kill and dead information for the instruction. + for (unsigned i = 0, e = OldMI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = OldMI->getOperand(i); + if (MO.isRegister() && MO.getReg() && + TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + unsigned Reg = MO.getReg(); + if (MO.isDef()) { + if (MO.isDead()) { + MO.setIsDead(false); + addRegisterDead(Reg, RegInfo); + } + } + if (MO.isKill()) { + MO.setIsKill(false); + addRegisterKilled(Reg, RegInfo); + } + } + } +}