[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