LLVM API Documentation

MipsISelDAGToDAG.cpp

Go to the documentation of this file.
00001 //===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===//
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 defines an instruction selector for the MIPS target.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #define DEBUG_TYPE "mips-isel"
00015 #include "Mips.h"
00016 #include "MipsISelLowering.h"
00017 #include "MipsMachineFunction.h"
00018 #include "MipsRegisterInfo.h"
00019 #include "MipsSubtarget.h"
00020 #include "MipsTargetMachine.h"
00021 #include "llvm/GlobalValue.h"
00022 #include "llvm/Instructions.h"
00023 #include "llvm/Intrinsics.h"
00024 #include "llvm/Support/CFG.h"
00025 #include "llvm/Type.h"
00026 #include "llvm/CodeGen/MachineConstantPool.h"
00027 #include "llvm/CodeGen/MachineFunction.h"
00028 #include "llvm/CodeGen/MachineFrameInfo.h"
00029 #include "llvm/CodeGen/MachineInstrBuilder.h"
00030 #include "llvm/CodeGen/MachineRegisterInfo.h"
00031 #include "llvm/CodeGen/SelectionDAGISel.h"
00032 #include "llvm/Target/TargetMachine.h"
00033 #include "llvm/Support/Compiler.h"
00034 #include "llvm/Support/Debug.h"
00035 using namespace llvm;
00036 
00037 //===----------------------------------------------------------------------===//
00038 // Instruction Selector Implementation
00039 //===----------------------------------------------------------------------===//
00040 
00041 //===----------------------------------------------------------------------===//
00042 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
00043 // instructions for SelectionDAG operations.
00044 //===----------------------------------------------------------------------===//
00045 namespace {
00046 
00047 class VISIBILITY_HIDDEN MipsDAGToDAGISel : public SelectionDAGISel {
00048 
00049   /// TM - Keep a reference to MipsTargetMachine.
00050   MipsTargetMachine &TM;
00051 
00052   /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
00053   /// make the right decision when generating code for different targets.
00054   const MipsSubtarget &Subtarget;
00055  
00056 public:
00057   explicit MipsDAGToDAGISel(MipsTargetMachine &tm) :
00058   SelectionDAGISel(tm),
00059   TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
00060   
00061   virtual void InstructionSelect();
00062 
00063   // Pass Name
00064   virtual const char *getPassName() const {
00065     return "MIPS DAG->DAG Pattern Instruction Selection";
00066   } 
00067   
00068 
00069 private:  
00070   // Include the pieces autogenerated from the target description.
00071   #include "MipsGenDAGISel.inc"
00072 
00073   SDValue getGlobalBaseReg();
00074   SDNode *Select(SDValue N);
00075 
00076   // Complex Pattern.
00077   bool SelectAddr(SDValue Op, SDValue N, 
00078                   SDValue &Base, SDValue &Offset);
00079 
00080 
00081   // getI32Imm - Return a target constant with the specified
00082   // value, of type i32.
00083   inline SDValue getI32Imm(unsigned Imm) {
00084     return CurDAG->getTargetConstant(Imm, MVT::i32);
00085   }
00086 
00087 
00088   #ifndef NDEBUG
00089   unsigned Indent;
00090   #endif
00091 };
00092 
00093 }
00094 
00095 /// InstructionSelect - This callback is invoked by
00096 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
00097 void MipsDAGToDAGISel::
00098 InstructionSelect() 
00099 {
00100   DEBUG(BB->dump());
00101   // Codegen the basic block.
00102   #ifndef NDEBUG
00103   DOUT << "===== Instruction selection begins:\n";
00104   Indent = 0;
00105   #endif
00106 
00107   // Select target instructions for the DAG.
00108   SelectRoot(*CurDAG);
00109 
00110   #ifndef NDEBUG
00111   DOUT << "===== Instruction selection ends:\n";
00112   #endif
00113 
00114   CurDAG->RemoveDeadNodes();
00115 }
00116 
00117 /// getGlobalBaseReg - Output the instructions required to put the
00118 /// GOT address into a register.
00119 SDValue MipsDAGToDAGISel::getGlobalBaseReg() {
00120   MachineFunction* MF = BB->getParent();
00121   unsigned GP = 0;
00122   for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(),
00123         ee = MF->getRegInfo().livein_end(); ii != ee; ++ii)
00124     if (ii->first == Mips::GP) {
00125       GP = ii->second;
00126       break;
00127     }
00128   assert(GP && "GOT PTR not in liveins");
00129   return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 
00130                                 GP, MVT::i32);
00131 }
00132 
00133 /// ComplexPattern used on MipsInstrInfo
00134 /// Used on Mips Load/Store instructions
00135 bool MipsDAGToDAGISel::
00136 SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base)
00137 {
00138   // if Address is FI, get the TargetFrameIndex.
00139   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
00140     Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
00141     Offset = CurDAG->getTargetConstant(0, MVT::i32);
00142     return true;
00143   }
00144     
00145   // on PIC code Load GA
00146   if (TM.getRelocationModel() == Reloc::PIC_) {
00147     if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || 
00148         (Addr.getOpcode() == ISD::TargetJumpTable)){
00149       Base   = CurDAG->getRegister(Mips::GP, MVT::i32);
00150       Offset = Addr;
00151       return true;
00152     }
00153   } else {
00154     if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
00155         Addr.getOpcode() == ISD::TargetGlobalAddress))
00156       return false;
00157   }    
00158   
00159   // Operand is a result from an ADD.
00160   if (Addr.getOpcode() == ISD::ADD) {
00161     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
00162       if (Predicate_immSExt16(CN)) {
00163 
00164         // If the first operand is a FI, get the TargetFI Node
00165         if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
00166                                     (Addr.getOperand(0))) {
00167           Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
00168         } else {
00169           Base = Addr.getOperand(0);
00170         }
00171 
00172         Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
00173         return true;
00174       }
00175     }
00176   }
00177 
00178   Base   = Addr;
00179   Offset = CurDAG->getTargetConstant(0, MVT::i32);
00180   return true;
00181 }
00182 
00183 /// Select instructions not customized! Used for
00184 /// expanded, promoted and normal instructions
00185 SDNode* MipsDAGToDAGISel::
00186 Select(SDValue N) 
00187 {
00188   SDNode *Node = N.getNode();
00189   unsigned Opcode = Node->getOpcode();
00190 
00191   // Dump information about the Node being selected
00192   #ifndef NDEBUG
00193   DOUT << std::string(Indent, ' ') << "Selecting: ";
00194   DEBUG(Node->dump(CurDAG));
00195   DOUT << "\n";
00196   Indent += 2;
00197   #endif
00198 
00199   // If we have a custom node, we already have selected!
00200   if (Node->isMachineOpcode()) {
00201     #ifndef NDEBUG
00202     DOUT << std::string(Indent-2, ' ') << "== ";
00203     DEBUG(Node->dump(CurDAG));
00204     DOUT << "\n";
00205     Indent -= 2;
00206     #endif
00207     return NULL;
00208   }
00209 
00210   ///
00211   // Instruction Selection not handled by the auto-generated 
00212   // tablegen selection should be handled here.
00213   /// 
00214   switch(Opcode) {
00215 
00216     default: break;
00217 
00218     case ISD::SUBE: 
00219     case ISD::ADDE: {
00220       SDValue InFlag = Node->getOperand(2), CmpLHS;
00221       unsigned Opc = InFlag.getOpcode(); Opc=Opc;
00222       assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 
00223               (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&  
00224              "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
00225 
00226       unsigned MOp;
00227       if (Opcode == ISD::ADDE) {
00228         CmpLHS = InFlag.getValue(0);
00229         MOp = Mips::ADDu;
00230       } else { 
00231         CmpLHS = InFlag.getOperand(0);
00232         MOp = Mips::SUBu;
00233       }
00234 
00235       SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
00236 
00237       SDValue LHS = Node->getOperand(0);
00238       SDValue RHS = Node->getOperand(1);
00239 
00240       MVT VT = LHS.getValueType();
00241       SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, VT, Ops, 2);
00242       SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, VT, 
00243                                                SDValue(Carry,0), RHS);
00244 
00245       return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag, 
00246                                   LHS, SDValue(AddCarry,0));
00247     }
00248 
00249     /// Mul/Div with two results
00250     case ISD::SDIVREM:
00251     case ISD::UDIVREM:
00252     case ISD::SMUL_LOHI:
00253     case ISD::UMUL_LOHI: {
00254       SDValue Op1 = Node->getOperand(0);
00255       SDValue Op2 = Node->getOperand(1);
00256 
00257       unsigned Op;
00258       if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI)
00259         Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
00260       else
00261         Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
00262 
00263       SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2);
00264 
00265       SDValue InFlag = SDValue(Node, 0);
00266       SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, MVT::i32, 
00267                                          MVT::Flag, InFlag);
00268       InFlag = SDValue(Lo,1);
00269       SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag);
00270 
00271       if (!N.getValue(0).use_empty()) 
00272         ReplaceUses(N.getValue(0), SDValue(Lo,0));
00273 
00274       if (!N.getValue(1).use_empty()) 
00275         ReplaceUses(N.getValue(1), SDValue(Hi,0));
00276 
00277       return NULL;
00278     }
00279 
00280     /// Special Muls
00281     case ISD::MUL: 
00282     case ISD::MULHS:
00283     case ISD::MULHU: {
00284       SDValue MulOp1 = Node->getOperand(0);
00285       SDValue MulOp2 = Node->getOperand(1);
00286 
00287       unsigned MulOp  = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
00288       SDNode *MulNode = CurDAG->getTargetNode(MulOp, MVT::Flag, MulOp1, MulOp2);
00289 
00290       SDValue InFlag = SDValue(MulNode, 0);
00291 
00292       if (MulOp == ISD::MUL)
00293         return CurDAG->getTargetNode(Mips::MFLO, MVT::i32, InFlag);
00294       else
00295         return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag);
00296     }
00297 
00298     /// Div/Rem operations
00299     case ISD::SREM:
00300     case ISD::UREM:
00301     case ISD::SDIV: 
00302     case ISD::UDIV: {
00303       SDValue Op1 = Node->getOperand(0);
00304       SDValue Op2 = Node->getOperand(1);
00305 
00306       unsigned Op, MOp;
00307       if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) {
00308         Op  = (Opcode == ISD::SDIV ? Mips::DIV : Mips::DIVu);
00309         MOp = Mips::MFLO;
00310       } else {
00311         Op  = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu);
00312         MOp = Mips::MFHI;
00313       }
00314       SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2);
00315 
00316       SDValue InFlag = SDValue(Node, 0);
00317       return CurDAG->getTargetNode(MOp, MVT::i32, InFlag);
00318     }
00319 
00320     // Get target GOT address.
00321     case ISD::GLOBAL_OFFSET_TABLE: {
00322       SDValue Result = getGlobalBaseReg();
00323       ReplaceUses(N, Result);
00324       return NULL;
00325     }
00326 
00327     /// Handle direct and indirect calls when using PIC. On PIC, when 
00328     /// GOT is smaller than about 64k (small code) the GA target is 
00329     /// loaded with only one instruction. Otherwise GA's target must 
00330     /// be loaded with 3 instructions. 
00331     case MipsISD::JmpLink: {
00332       if (TM.getRelocationModel() == Reloc::PIC_) {
00333         //bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
00334         SDValue Chain  = Node->getOperand(0);
00335         SDValue Callee = Node->getOperand(1);
00336         SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
00337         SDValue InFlag(0, 0);
00338 
00339         if ( (isa<GlobalAddressSDNode>(Callee)) ||
00340              (isa<ExternalSymbolSDNode>(Callee)) )
00341         {
00342           /// Direct call for global addresses and external symbols
00343           SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);
00344 
00345           // Use load to get GOT target
00346           SDValue Ops[] = { Callee, GPReg, Chain };
00347           SDValue Load = SDValue(CurDAG->getTargetNode(Mips::LW, MVT::i32, 
00348                                      MVT::Other, Ops, 3), 0);
00349           Chain = Load.getValue(1);
00350 
00351           // Call target must be on T9
00352           Chain = CurDAG->getCopyToReg(Chain, T9Reg, Load, InFlag);
00353         } else 
00354           /// Indirect call
00355           Chain = CurDAG->getCopyToReg(Chain, T9Reg, Callee, InFlag);
00356 
00357         // Emit Jump and Link Register
00358         SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, MVT::Other,
00359                                   MVT::Flag, T9Reg, Chain);
00360         Chain  = SDValue(ResNode, 0);
00361         InFlag = SDValue(ResNode, 1);
00362         ReplaceUses(SDValue(Node, 0), Chain);
00363         ReplaceUses(SDValue(Node, 1), InFlag);
00364         return ResNode;
00365       } 
00366     }
00367   }
00368 
00369   // Select the default instruction
00370   SDNode *ResNode = SelectCode(N);
00371 
00372   #ifndef NDEBUG
00373   DOUT << std::string(Indent-2, ' ') << "=> ";
00374   if (ResNode == NULL || ResNode == N.getNode())
00375     DEBUG(N.getNode()->dump(CurDAG));
00376   else
00377     DEBUG(ResNode->dump(CurDAG));
00378   DOUT << "\n";
00379   Indent -= 2;
00380   #endif
00381 
00382   return ResNode;
00383 }
00384 
00385 /// createMipsISelDag - This pass converts a legalized DAG into a 
00386 /// MIPS-specific DAG, ready for instruction scheduling.
00387 FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
00388   return new MipsDAGToDAGISel(TM);
00389 }