LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

SparcV9PeepholeOpts.cpp

Go to the documentation of this file.
00001 //===-- SparcV9PeepholeOpts.cpp -------------------------------------------===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 // 
00010 // Support for performing several peephole opts in one or a few passes over the
00011 // machine code of a method.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "SparcV9Internals.h"
00016 #include "llvm/BasicBlock.h"
00017 #include "llvm/Pass.h"
00018 #include "llvm/CodeGen/MachineFunction.h"
00019 #include "llvm/CodeGen/MachineInstr.h"
00020 #include "llvm/Target/TargetInstrInfo.h"
00021 #include "llvm/Target/TargetMachine.h"
00022 #include "llvm/ADT/STLExtras.h"
00023 
00024 namespace llvm {
00025 
00026 //************************* Internal Functions *****************************/
00027 
00028 static inline void
00029 DeleteInstruction(MachineBasicBlock& mvec,
00030                   MachineBasicBlock::iterator& BBI,
00031                   const TargetMachine& target) {
00032   // Check if this instruction is in a delay slot of its predecessor.
00033   if (BBI != mvec.begin()) {
00034       const TargetInstrInfo& mii = *target.getInstrInfo();
00035       MachineBasicBlock::iterator predMI = prior(BBI);
00036       if (unsigned ndelay = mii.getNumDelaySlots(predMI->getOpcode())) {
00037         // This instruction is in a delay slot of its predecessor, so
00038         // replace it with a nop. By replacing in place, we save having
00039         // to update the I-I maps.
00040         // 
00041         assert(ndelay == 1 && "Not yet handling multiple-delay-slot targets");
00042         BBI->replace(V9::NOP, 0);
00043         return;
00044       }
00045   }
00046   
00047   // The instruction is not in a delay slot, so we can simply erase it.
00048   mvec.erase(BBI);
00049   BBI = mvec.end();
00050 }
00051 
00052 //******************* Individual Peephole Optimizations ********************/
00053 
00054 //----------------------------------------------------------------------------
00055 // Function: IsUselessCopy
00056 // Decide whether a machine instruction is a redundant copy:
00057 // -- ADD    with g0 and result and operand are identical, or
00058 // -- OR     with g0 and result and operand are identical, or
00059 // -- FMOVS or FMOVD and result and operand are identical.
00060 // Other cases are possible but very rare that they would be useless copies,
00061 // so it's not worth analyzing them.
00062 //----------------------------------------------------------------------------
00063 
00064 static bool IsUselessCopy(const TargetMachine &target, const MachineInstr* MI) {
00065   if (MI->getOpcode() == V9::FMOVS || MI->getOpcode() == V9::FMOVD) {
00066     return (// both operands are allocated to the same register
00067             MI->getOperand(0).getReg() ==  MI->getOperand(1).getReg());
00068   } else if (MI->getOpcode() == V9::ADDr || MI->getOpcode() == V9::ORr ||
00069              MI->getOpcode() == V9::ADDi || MI->getOpcode() == V9::ORi) {
00070     unsigned srcWithDestReg;
00071     
00072     for (srcWithDestReg = 0; srcWithDestReg < 2; ++srcWithDestReg)
00073       if (MI->getOperand(srcWithDestReg).hasAllocatedReg() &&
00074           MI->getOperand(srcWithDestReg).getReg()
00075           == MI->getOperand(2).getReg())
00076         break;
00077     
00078     if (srcWithDestReg == 2)
00079       return false;
00080     else {
00081       // else source and dest are allocated to the same register
00082       unsigned otherOp = 1 - srcWithDestReg;
00083       return (// either operand otherOp is register %g0
00084               (MI->getOperand(otherOp).hasAllocatedReg() &&
00085                MI->getOperand(otherOp).getReg() ==
00086                target.getRegInfo()->getZeroRegNum()) ||
00087               
00088               // or operand otherOp == 0
00089               (MI->getOperand(otherOp).getType()
00090                == MachineOperand::MO_SignExtendedImmed &&
00091                MI->getOperand(otherOp).getImmedValue() == 0));
00092     }
00093   }
00094   else
00095     return false;
00096 }
00097 
00098 inline bool
00099 RemoveUselessCopies(MachineBasicBlock& mvec,
00100                     MachineBasicBlock::iterator& BBI,
00101                     const TargetMachine& target) {
00102   if (IsUselessCopy(target, BBI)) {
00103     DeleteInstruction(mvec, BBI, target);
00104     return true;
00105   }
00106   return false;
00107 }
00108 
00109 
00110 //************************ Class Implementations **************************/
00111 
00112 class PeepholeOpts: public BasicBlockPass {
00113   const TargetMachine &target;
00114   bool visit(MachineBasicBlock& mvec,
00115              MachineBasicBlock::iterator BBI) const;
00116 public:
00117   PeepholeOpts(const TargetMachine &TM): target(TM) { }
00118   bool runOnBasicBlock(BasicBlock &BB); // apply this pass to each BB
00119   virtual const char *getPassName() const { return "Peephole Optimization"; }
00120 
00121   // getAnalysisUsage - this pass preserves the CFG
00122   void getAnalysisUsage(AnalysisUsage &AU) const {
00123     AU.setPreservesCFG();
00124   }
00125 };
00126 
00127 // Apply a list of peephole optimizations to this machine instruction
00128 // within its local context.  They are allowed to delete MI or any
00129 // instruction before MI, but not 
00130 //
00131 bool PeepholeOpts::visit(MachineBasicBlock& mvec,
00132                          MachineBasicBlock::iterator BBI) const {
00133   // Remove redundant copy instructions
00134   return RemoveUselessCopies(mvec, BBI, target);
00135 }
00136 
00137 
00138 bool PeepholeOpts::runOnBasicBlock(BasicBlock &BB) {
00139   // Get the machine instructions for this BB
00140   // FIXME: MachineBasicBlock::get() is deprecated, hence inlining the function
00141   const Function *F = BB.getParent();
00142   MachineFunction &MF = MachineFunction::get(F);
00143   MachineBasicBlock *MBB = NULL;
00144   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
00145     if (I->getBasicBlock() == &BB)
00146       MBB = I;
00147 
00148   assert(MBB && "MachineBasicBlock object not found for specified block!");
00149   MachineBasicBlock &mvec = *MBB;
00150 
00151   for (MachineBasicBlock::iterator I = mvec.begin(), E = mvec.end(); I != E; )
00152     visit(mvec, I++);
00153 
00154   return true;
00155 }
00156 
00157 /// createPeepholeOptsPass - Public entry point for peephole optimization
00158 ///
00159 FunctionPass* createPeepholeOptsPass(const TargetMachine &TM) {
00160   return new PeepholeOpts(TM);
00161 }
00162 
00163 } // End llvm namespace