X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FTargetInstrInfoImpl.cpp;h=a213400dcbdfba266260d867783fdb3662c39f0d;hb=ef4cfc749a61d0d0252196c957697436ba7ec068;hp=4b8c669a25afdc12873eb8a6ea05c35cbcdd2c69;hpb=ca1267c02b025cc719190b05f9e1a5d174a9caf7;p=oota-llvm.git diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp index 4b8c669a25a..a213400dcbd 100644 --- a/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -13,25 +13,45 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/PseudoSourceValue.h" using namespace llvm; // commuteInstruction - The default implementation of this method just exchanges // operand 1 and 2. -MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI) const { - assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() && +MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI, + bool NewMI) const { + assert(MI->getOperand(1).isReg() && MI->getOperand(2).isReg() && "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(); + bool ChangeReg0 = false; if (MI->getOperand(0).getReg() == Reg1) { // Must be two address instruction! assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) && "Expecting a two-address instruction!"); Reg2IsKill = false; - MI->getOperand(0).setReg(Reg2); + ChangeReg0 = true; + } + + if (NewMI) { + // Create a new instruction. + unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg(); + bool Reg0IsDead = MI->getOperand(0).isDead(); + MachineFunction &MF = *MI->getParent()->getParent(); + return BuildMI(MF, MI->getDebugLoc(), MI->getDesc()) + .addReg(Reg0, true, false, false, Reg0IsDead) + .addReg(Reg2, false, false, Reg2IsKill) + .addReg(Reg1, false, false, Reg1IsKill); } + + if (ChangeReg0) + MI->getOperand(0).setReg(Reg2); MI->getOperand(2).setReg(Reg1); MI->getOperand(1).setReg(Reg2); MI->getOperand(2).setIsKill(Reg1IsKill); @@ -46,7 +66,7 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI) const { /// two-address instruction. bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI, unsigned &OpIdx) const{ - assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() && + assert(MI->getOperand(1).isReg() && MI->getOperand(2).isReg() && "This only knows how to commute register operands so far"); if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) { // Must be two address instruction! @@ -60,7 +80,7 @@ bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI, bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI, - const std::vector &Pred) const { + const SmallVectorImpl &Pred) const { bool MadeChange = false; const TargetInstrDesc &TID = MI->getDesc(); if (!TID.isPredicable()) @@ -89,8 +109,86 @@ void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, const MachineInstr *Orig) const { - MachineInstr *MI = Orig->clone(); + MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig); MI->getOperand(0).setReg(DestReg); MBB.insert(I, MI); } +unsigned +TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const { + unsigned FnSize = 0; + for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end(); + MBBI != E; ++MBBI) { + const MachineBasicBlock &MBB = *MBBI; + for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end(); + I != E; ++I) + FnSize += GetInstSizeInBytes(I); + } + return FnSize; +} + +/// foldMemoryOperand - Attempt to fold a load or store of the specified stack +/// slot into the specified machine instruction for the specified operand(s). +/// If this is possible, a new instruction is returned with the specified +/// operand folded, otherwise NULL is returned. The client is responsible for +/// removing the old instruction and adding the new one in the instruction +/// stream. +MachineInstr* +TargetInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + int FrameIndex) const { + unsigned Flags = 0; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + if (MI->getOperand(Ops[i]).isDef()) + Flags |= MachineMemOperand::MOStore; + else + Flags |= MachineMemOperand::MOLoad; + + // Ask the target to do the actual folding. + MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, FrameIndex); + if (!NewMI) return 0; + + assert((!(Flags & MachineMemOperand::MOStore) || + NewMI->getDesc().mayStore()) && + "Folded a def to a non-store!"); + assert((!(Flags & MachineMemOperand::MOLoad) || + NewMI->getDesc().mayLoad()) && + "Folded a use to a non-load!"); + const MachineFrameInfo &MFI = *MF.getFrameInfo(); + assert(MFI.getObjectOffset(FrameIndex) != -1); + MachineMemOperand MMO(PseudoSourceValue::getFixedStack(FrameIndex), + Flags, + MFI.getObjectOffset(FrameIndex), + MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); + NewMI->addMemOperand(MF, MMO); + + return NewMI; +} + +/// foldMemoryOperand - Same as the previous version except it allows folding +/// of any load and store from / to any address, not just from a specific +/// stack slot. +MachineInstr* +TargetInstrInfo::foldMemoryOperand(MachineFunction &MF, + MachineInstr* MI, + const SmallVectorImpl &Ops, + MachineInstr* LoadMI) const { + assert(LoadMI->getDesc().canFoldAsLoad() && "LoadMI isn't foldable!"); +#ifndef NDEBUG + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + assert(MI->getOperand(Ops[i]).isUse() && "Folding load into def!"); +#endif + + // Ask the target to do the actual folding. + MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI); + if (!NewMI) return 0; + + // Copy the memoperands from the load to the folded instruction. + for (std::list::iterator I = LoadMI->memoperands_begin(), + E = LoadMI->memoperands_end(); I != E; ++I) + NewMI->addMemOperand(MF, *I); + + return NewMI; +}