LLVM API Documentation

TargetInstrInfoImpl.cpp

Go to the documentation of this file.
00001 //===-- TargetInstrInfoImpl.cpp - Target Instruction Information ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the TargetInstrInfoImpl class, it just provides default
00011 // implementations of various methods.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/Target/TargetInstrInfo.h"
00016 #include "llvm/ADT/SmallVector.h"
00017 #include "llvm/CodeGen/MachineFrameInfo.h"
00018 #include "llvm/CodeGen/MachineInstr.h"
00019 #include "llvm/CodeGen/MachineInstrBuilder.h"
00020 #include "llvm/CodeGen/PseudoSourceValue.h"
00021 using namespace llvm;
00022 
00023 // commuteInstruction - The default implementation of this method just exchanges
00024 // operand 1 and 2.
00025 MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI,
00026                                                       bool NewMI) const {
00027   assert(MI->getOperand(1).isReg() && MI->getOperand(2).isReg() &&
00028          "This only knows how to commute register operands so far");
00029   unsigned Reg1 = MI->getOperand(1).getReg();
00030   unsigned Reg2 = MI->getOperand(2).getReg();
00031   bool Reg1IsKill = MI->getOperand(1).isKill();
00032   bool Reg2IsKill = MI->getOperand(2).isKill();
00033   bool ChangeReg0 = false;
00034   if (MI->getOperand(0).getReg() == Reg1) {
00035     // Must be two address instruction!
00036     assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
00037            "Expecting a two-address instruction!");
00038     Reg2IsKill = false;
00039     ChangeReg0 = true;
00040   }
00041 
00042   if (NewMI) {
00043     // Create a new instruction.
00044     unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg();
00045     bool Reg0IsDead = MI->getOperand(0).isDead();
00046     MachineFunction &MF = *MI->getParent()->getParent();
00047     return BuildMI(MF, MI->getDebugLoc(), MI->getDesc())
00048       .addReg(Reg0, true, false, false, Reg0IsDead)
00049       .addReg(Reg2, false, false, Reg2IsKill)
00050       .addReg(Reg1, false, false, Reg1IsKill);
00051   }
00052 
00053   if (ChangeReg0)
00054     MI->getOperand(0).setReg(Reg2);
00055   MI->getOperand(2).setReg(Reg1);
00056   MI->getOperand(1).setReg(Reg2);
00057   MI->getOperand(2).setIsKill(Reg1IsKill);
00058   MI->getOperand(1).setIsKill(Reg2IsKill);
00059   return MI;
00060 }
00061 
00062 /// CommuteChangesDestination - Return true if commuting the specified
00063 /// instruction will also changes the destination operand. Also return the
00064 /// current operand index of the would be new destination register by
00065 /// reference. This can happen when the commutable instruction is also a
00066 /// two-address instruction.
00067 bool TargetInstrInfoImpl::CommuteChangesDestination(MachineInstr *MI,
00068                                                     unsigned &OpIdx) const{
00069   assert(MI->getOperand(1).isReg() && MI->getOperand(2).isReg() &&
00070          "This only knows how to commute register operands so far");
00071   if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) {
00072     // Must be two address instruction!
00073     assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) &&
00074            "Expecting a two-address instruction!");
00075     OpIdx = 2;
00076     return true;
00077   }
00078   return false;
00079 }
00080 
00081 
00082 bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI,
00083                             const SmallVectorImpl<MachineOperand> &Pred) const {
00084   bool MadeChange = false;
00085   const TargetInstrDesc &TID = MI->getDesc();
00086   if (!TID.isPredicable())
00087     return false;
00088   
00089   for (unsigned j = 0, i = 0, e = MI->getNumOperands(); i != e; ++i) {
00090     if (TID.OpInfo[i].isPredicate()) {
00091       MachineOperand &MO = MI->getOperand(i);
00092       if (MO.isReg()) {
00093         MO.setReg(Pred[j].getReg());
00094         MadeChange = true;
00095       } else if (MO.isImm()) {
00096         MO.setImm(Pred[j].getImm());
00097         MadeChange = true;
00098       } else if (MO.isMBB()) {
00099         MO.setMBB(Pred[j].getMBB());
00100         MadeChange = true;
00101       }
00102       ++j;
00103     }
00104   }
00105   return MadeChange;
00106 }
00107 
00108 void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
00109                                         MachineBasicBlock::iterator I,
00110                                         unsigned DestReg,
00111                                         const MachineInstr *Orig) const {
00112   MachineInstr *MI = MBB.getParent()->CloneMachineInstr(Orig);
00113   MI->getOperand(0).setReg(DestReg);
00114   MBB.insert(I, MI);
00115 }
00116 
00117 unsigned
00118 TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
00119   unsigned FnSize = 0;
00120   for (MachineFunction::const_iterator MBBI = MF.begin(), E = MF.end();
00121        MBBI != E; ++MBBI) {
00122     const MachineBasicBlock &MBB = *MBBI;
00123     for (MachineBasicBlock::const_iterator I = MBB.begin(),E = MBB.end();
00124          I != E; ++I)
00125       FnSize += GetInstSizeInBytes(I);
00126   }
00127   return FnSize;
00128 }
00129 
00130 /// foldMemoryOperand - Attempt to fold a load or store of the specified stack
00131 /// slot into the specified machine instruction for the specified operand(s).
00132 /// If this is possible, a new instruction is returned with the specified
00133 /// operand folded, otherwise NULL is returned. The client is responsible for
00134 /// removing the old instruction and adding the new one in the instruction
00135 /// stream.
00136 MachineInstr*
00137 TargetInstrInfo::foldMemoryOperand(MachineFunction &MF,
00138                                    MachineInstr* MI,
00139                                    const SmallVectorImpl<unsigned> &Ops,
00140                                    int FrameIndex) const {
00141   unsigned Flags = 0;
00142   for (unsigned i = 0, e = Ops.size(); i != e; ++i)
00143     if (MI->getOperand(Ops[i]).isDef())
00144       Flags |= MachineMemOperand::MOStore;
00145     else
00146       Flags |= MachineMemOperand::MOLoad;
00147 
00148   // Ask the target to do the actual folding.
00149   MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, FrameIndex);
00150   if (!NewMI) return 0;
00151 
00152   assert((!(Flags & MachineMemOperand::MOStore) ||
00153           NewMI->getDesc().mayStore()) &&
00154          "Folded a def to a non-store!");
00155   assert((!(Flags & MachineMemOperand::MOLoad) ||
00156           NewMI->getDesc().mayLoad()) &&
00157          "Folded a use to a non-load!");
00158   const MachineFrameInfo &MFI = *MF.getFrameInfo();
00159   assert(MFI.getObjectOffset(FrameIndex) != -1);
00160   MachineMemOperand MMO(PseudoSourceValue::getFixedStack(FrameIndex),
00161                         Flags,
00162                         MFI.getObjectOffset(FrameIndex),
00163                         MFI.getObjectSize(FrameIndex),
00164                         MFI.getObjectAlignment(FrameIndex));
00165   NewMI->addMemOperand(MF, MMO);
00166 
00167   return NewMI;
00168 }
00169 
00170 /// foldMemoryOperand - Same as the previous version except it allows folding
00171 /// of any load and store from / to any address, not just from a specific
00172 /// stack slot.
00173 MachineInstr*
00174 TargetInstrInfo::foldMemoryOperand(MachineFunction &MF,
00175                                    MachineInstr* MI,
00176                                    const SmallVectorImpl<unsigned> &Ops,
00177                                    MachineInstr* LoadMI) const {
00178   assert(LoadMI->getDesc().canFoldAsLoad() && "LoadMI isn't foldable!");
00179 #ifndef NDEBUG
00180   for (unsigned i = 0, e = Ops.size(); i != e; ++i)
00181     assert(MI->getOperand(Ops[i]).isUse() && "Folding load into def!");
00182 #endif
00183 
00184   // Ask the target to do the actual folding.
00185   MachineInstr *NewMI = foldMemoryOperandImpl(MF, MI, Ops, LoadMI);
00186   if (!NewMI) return 0;
00187 
00188   // Copy the memoperands from the load to the folded instruction.
00189   for (std::list<MachineMemOperand>::iterator I = LoadMI->memoperands_begin(),
00190        E = LoadMI->memoperands_end(); I != E; ++I)
00191     NewMI->addMemOperand(MF, *I);
00192 
00193   return NewMI;
00194 }