[llvm-commits] [llvm] r53869 - in /llvm/trunk/lib/Target/Mips: MipsAsmPrinter.cpp MipsISelLowering.cpp MipsISelLowering.h MipsInstrInfo.td MipsSubtarget.cpp MipsSubtarget.h MipsTargetAsmInfo.cpp

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Mon Jul 21 11:52:34 PDT 2008


Author: bruno
Date: Mon Jul 21 13:52:34 2008
New Revision: 53869

URL: http://llvm.org/viewvc/llvm-project?rev=53869&view=rev
Log:
Added initial support for small sections on Mips.
Added gp_rel relocations to support addressing small section contents.
Added command line to specify small section threshold in bytes.

Modified:
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.h
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
    llvm/trunk/lib/Target/Mips/MipsSubtarget.h
    llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Mon Jul 21 13:52:34 2008
@@ -360,7 +360,11 @@
     closeP = true;
   } else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isRegister() 
              && !MO.isImmediate()) {
-    O << "%lo(";
+    const MachineOperand &firstMO = MI->getOperand(opNum-1);
+    if (firstMO.getReg() == Mips::GP)
+      O << "%gp_rel(";
+    else
+      O << "%lo(";
     closeP = true;
   } else if ((isPIC) && (MI->getOpcode() == Mips::LW)
              && (!MO.isRegister()) && (!MO.isImmediate())) {
@@ -490,14 +494,13 @@
   Constant *C = GVar->getInitializer();
   const Type *CTy = C->getType();
   unsigned Size = TD->getABITypeSize(CTy);
+  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
   bool printSizeAndType = true;
 
   // A data structure or array is aligned in memory to the largest
   // alignment boundary required by any data type inside it (this matches
   // the Preferred Type Alignment). For integral types, the alignment is
   // the type size.
-  //unsigned Align = TD->getPreferredAlignmentLog(I);
-  //unsigned Align = TD->getPrefTypeAlignment(C->getType());
   unsigned Align;
   if (CTy->getTypeID() == Type::IntegerTyID ||
       CTy->getTypeID() == Type::VoidTyID) {
@@ -546,6 +549,8 @@
     O << TAI->getGlobalDirective() << name << '\n';
     // Fall Through
    case GlobalValue::InternalLinkage:
+    if (CVA && CVA->isCString())
+      printSizeAndType = false;  
     break;
    case GlobalValue::GhostLinkage:
     cerr << "Should not have any unmaterialized functions!\n";

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Jul 21 13:52:34 2008
@@ -20,6 +20,7 @@
 #include "MipsSubtarget.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/CallingConv.h"
 #include "llvm/CodeGen/CallingConvLower.h"
@@ -43,6 +44,7 @@
     case MipsISD::JmpLink   : return "MipsISD::JmpLink";
     case MipsISD::Hi        : return "MipsISD::Hi";
     case MipsISD::Lo        : return "MipsISD::Lo";
+    case MipsISD::GPRel     : return "MipsISD::GPRel";
     case MipsISD::Ret       : return "MipsISD::Ret";
     case MipsISD::SelectCC  : return "MipsISD::SelectCC";
     case MipsISD::FPBrcond  : return "MipsISD::FPBrcond";
@@ -89,8 +91,6 @@
   setOperationAction(ISD::SELECT_CC,        MVT::f32,   Custom);
 
   // Operations not directly supported by Mips.
-  setConvertAction(MVT::f64, MVT::f32, Expand);
-
   setOperationAction(ISD::BR_JT,             MVT::Other, Expand);
   setOperationAction(ISD::BR_CC,             MVT::Other, Expand);
   setOperationAction(ISD::SELECT_CC,         MVT::Other, Expand);
@@ -234,34 +234,71 @@
   return VReg;
 }
 
+// Discover if this global address can be placed into small data/bss section. 
+// This should happen for globals with size less than small section size 
+// threshold in no abicall environments. Data in this section must be addressed 
+// using gp_rel operator.
+bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
+{
+  const TargetData *TD = getTargetData();
+  const Value *V = dyn_cast<Value>(GV);
+  const GlobalVariable *GVA = dyn_cast<GlobalVariable>(V);
+  
+  //const PointerType *PTy = GV->getType();
+  const Type *Ty = GV->getType()->getElementType();
+  unsigned Size = TD->getABITypeSize(Ty);
+
+  // if this is a internal constant string, there is a special
+  // section for it, but not in small data/bss.
+  if (GVA->hasInitializer() && GV->hasInternalLinkage()) {
+    Constant *C = GVA->getInitializer();
+    const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+    if (CVA && CVA->isCString()) 
+      return false;
+  }
+
+  if (Size > 0 && (Size <= Subtarget->getSSectionThreshold()))
+    return true;
+
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 //  Misc Lower Operation implementation
 //===----------------------------------------------------------------------===//
 SDOperand MipsTargetLowering::
 LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) 
 {
-  SDOperand ResNode;
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
   SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
-  bool isPIC = (getTargetMachine().getRelocationModel() == Reloc::PIC_);
 
-  SDOperand HiPart; 
-  if (!isPIC) {
+  if (!Subtarget->hasABICall()) {
+    if (isa<Function>(GV)) return GA;
     const MVT *VTs = DAG.getNodeValueTypes(MVT::i32);
     SDOperand Ops[] = { GA };
-    HiPart = DAG.getNode(MipsISD::Hi, VTs, 1, Ops, 1);
-  } else // Emit Load from Global Pointer
-    HiPart = DAG.getLoad(MVT::i32, DAG.getEntryNode(), GA, NULL, 0);
-
-  // On functions and global targets not internal linked only
-  // a load from got/GP is necessary for PIC to work.
-  if ((isPIC) && ((!GV->hasInternalLinkage()) || (isa<Function>(GV))))
-    return HiPart;
 
-  SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
-  ResNode = DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo);
+    if (IsGlobalInSmallSection(GV)) { // %gp_rel relocation
+      SDOperand GPRelNode = DAG.getNode(MipsISD::GPRel, VTs, 1, Ops, 1);
+      SDOperand GOT = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, MVT::i32);
+      return DAG.getNode(ISD::ADD, MVT::i32, GOT, GPRelNode); 
+    }
+    // %hi/%lo relocation
+    SDOperand HiPart = DAG.getNode(MipsISD::Hi, VTs, 1, Ops, 1);
+    SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
+    return DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo);
+
+  } else { // Abicall relocations, TODO: make this cleaner.
+    SDOperand ResNode = DAG.getLoad(MVT::i32, DAG.getEntryNode(), GA, NULL, 0);
+    // On functions and global targets not internal linked only
+    // a load from got/GP is necessary for PIC to work.
+    if (!GV->hasInternalLinkage() || isa<Function>(GV))
+      return ResNode;
+    SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
+    return DAG.getNode(ISD::ADD, MVT::i32, ResNode, Lo);
+  }
 
-  return ResNode;
+  assert(0 && "Dont know how to handle GlobalAddress");
+  return SDOperand(0,0);
 }
 
 SDOperand MipsTargetLowering::
@@ -596,9 +633,8 @@
 
   unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
 
-  // GP holds the GOT address on PIC calls.
-  if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
-    AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass);
+  // GP must be live into PIC and non-PIC call target.
+  AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass);
 
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Mon Jul 21 13:52:34 2008
@@ -37,6 +37,9 @@
       // No relation with Mips Lo register
       Lo, 
 
+      // Handle gp_rel (small data/bss sections) relocation.
+      GPRel,
+
       // Select CC Pseudo Instruction
       SelectCC,
 
@@ -83,7 +86,7 @@
     SDOperand LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC);
     SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall,
                             unsigned CallingConv, SelectionDAG &DAG);
-    SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG);
+    bool IsGlobalInSmallSection(GlobalValue *GV); 
 
     // Lower Operand specifics
     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Mon Jul 21 13:52:34 2008
@@ -31,9 +31,9 @@
 // Hi and Lo nodes are used to handle global addresses. Used on 
 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol 
 // static model. (nothing to do with Mips Registers Hi and Lo)
-//def MipsHi  : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>;
-def MipsHi  : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
-def MipsLo  : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
+def MipsHi    : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
+def MipsLo    : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
+def MipsGPRel : SDNode<"MipsISD::GPRel", SDTIntUnaryOp>;
 
 // Return
 def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, 
@@ -555,13 +555,15 @@
 
 // GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
 def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
-def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
+//def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
 def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
           (ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
 def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
-def : Pat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
+//def : Pat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
 def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
           (ADDiu CPURegs:$hi, tjumptable:$lo)>;
+def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)), 
+          (ADDiu CPURegs:$gp, tglobaladdr:$in)>;
 
 // Mips does not have "not", so we expand our way
 def : Pat<(not CPURegs:$in),

Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp Mon Jul 21 13:52:34 2008
@@ -22,6 +22,9 @@
               cl::desc("Disable code for SVR4-style dynamic objects"));
 cl::opt<bool> AbsoluteCall("enable-mips-absolute-call", cl::Hidden,
               cl::desc("Enable absolute call within abicall"));
+cl::opt<unsigned> SSThreshold("mips-ssection-threshold", cl::Hidden,
+              cl::desc("Small data and bss section threshold size (default=8)"),
+              cl::init(8));
 
 MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M, 
                              const std::string &FS, bool little) : 
@@ -35,6 +38,9 @@
   ParseSubtargetFeatures(FS, CPU);
   const std::string& TT = M.getTargetTriple();
 
+  // Small section size threshold
+  SSectionThreshold = SSThreshold;
+
   // Is the target system Linux ?
   if (TT.find("linux") == std::string::npos)
     IsLinux = false;

Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.h?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSubtarget.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsSubtarget.h Mon Jul 21 13:52:34 2008
@@ -71,6 +71,10 @@
   // isLinux - Target system is Linux. Is false we consider ELFOS for now.
   bool IsLinux;
 
+  // Put global and static items less than or equal to SSectionThreshold 
+  // bytes into the small data or bss section. The default is 8.
+  unsigned SSectionThreshold;
+
   InstrItineraryData InstrItins;
 
 public:
@@ -102,6 +106,7 @@
   bool hasABICall() const { return HasABICall; };
   bool hasAbsoluteCall() const { return HasAbsoluteCall; };
   bool isLinux() const { return IsLinux; };
+  unsigned getSSectionThreshold() const { return SSectionThreshold; }
 
 };
 } // End llvm namespace

Modified: llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp?rev=53869&r1=53868&r2=53869&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsTargetAsmInfo.cpp Mon Jul 21 13:52:34 2008
@@ -31,6 +31,7 @@
   ZeroDirective               = "\t.space\t";
   BSSSection                  = "\t.section\t.bss";
   LCOMMDirective              = "\t.lcomm\t";
+  CStringSection              = ".rodata.str";
 
   if (!TM.getSubtarget<MipsSubtarget>().hasABICall())
     JumpTableDirective = "\t.word\t";





More information about the llvm-commits mailing list