llvm.org GIT mirror llvm / b71b909
reintroduce support for Mips "small" section handling. This is implemented somewhat differently than before, but it should have the same functionality and the previous testcase passes again. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78900 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
8 changed file(s) with 172 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
1818 MipsSubtarget.cpp
1919 MipsTargetAsmInfo.cpp
2020 MipsTargetMachine.cpp
21 MipsTargetObjectFile.cpp
2122 )
2223
2324 target_link_libraries (LLVMMipsCodeGen LLVMSelectionDAG)
1212 //===----------------------------------------------------------------------===//
1313
1414 #define DEBUG_TYPE "mips-lower"
15
1615 #include "MipsISelLowering.h"
1716 #include "MipsMachineFunction.h"
1817 #include "MipsTargetMachine.h"
18 #include "MipsTargetObjectFile.h"
1919 #include "MipsSubtarget.h"
2020 #include "llvm/DerivedTypes.h"
2121 #include "llvm/Function.h"
2929 #include "llvm/CodeGen/MachineRegisterInfo.h"
3030 #include "llvm/CodeGen/SelectionDAGISel.h"
3131 #include "llvm/CodeGen/ValueTypes.h"
32 #include "llvm/Target/TargetLoweringObjectFile.h"
3332 #include "llvm/Support/Debug.h"
3433 #include "llvm/Support/ErrorHandling.h"
3534 using namespace llvm;
5352
5453 MipsTargetLowering::
5554 MipsTargetLowering(MipsTargetMachine &TM)
56 : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
55 : TargetLowering(TM, new MipsTargetObjectFile()) {
5756 Subtarget = &TM.getSubtarget();
5857
5958 // Mips does not have i1 type, so use i32 for
209208 return VReg;
210209 }
211210
212 // A address must be loaded from a small section if its size is less than the
213 // small section size threshold. Data in this section must be addressed using
214 // gp_rel operator.
215 bool MipsTargetLowering::IsInSmallSection(unsigned Size) {
216 return (Size > 0 && (Size <= Subtarget->getSSectionThreshold()));
217 }
218
219 // Discover if this global address can be placed into small data/bss section.
220 bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
221 {
222 const TargetData *TD = getTargetData();
223 const GlobalVariable *GVA = dyn_cast(GV);
224
225 if (!GVA)
226 return false;
227
228 const Type *Ty = GV->getType()->getElementType();
229 unsigned Size = TD->getTypeAllocSize(Ty);
230
231 // if this is a internal constant string, there is a special
232 // section for it, but not in small data/bss.
233 if (GVA->hasInitializer() && GV->hasLocalLinkage()) {
234 Constant *C = GVA->getInitializer();
235 const ConstantArray *CVA = dyn_cast(C);
236 if (CVA && CVA->isCString())
237 return false;
238 }
239
240 return IsInSmallSection(Size);
241 }
242
243211 // Get fp branch code (not opcode) from condition code.
244212 static Mips::FPBranchCode GetFPBranchCodeFromCond(Mips::CondCode CC) {
245213 if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT)
524492 if (getTargetMachine().getRelocationModel() != Reloc::PIC_) {
525493 SDVTList VTs = DAG.getVTList(MVT::i32);
526494
495 MipsTargetObjectFile &TLOF = (MipsTargetObjectFile&)getObjFileLowering();
496
527497 // %gp_rel relocation
528 if (!isa(GV) && IsGlobalInSmallSection(GV)) {
498 if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) {
529499 SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
530500 SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
531501 return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode);
8787 // Subtarget Info
8888 const MipsSubtarget *Subtarget;
8989
90 bool IsGlobalInSmallSection(GlobalValue *GV);
91 bool IsInSmallSection(unsigned Size);
9290
9391 // Lower Operand helpers
9492 SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
1313 #include "MipsSubtarget.h"
1414 #include "Mips.h"
1515 #include "MipsGenSubtarget.inc"
16 #include "llvm/Support/CommandLine.h"
1716 using namespace llvm;
18
19 static cl::opt
20 SSThreshold("mips-ssection-threshold", cl::Hidden,
21 cl::desc("Small data and bss section threshold size (default=8)"),
22 cl::init(8));
2317
2418 MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &FS,
2519 bool little) :
3327
3428 // Parse features string.
3529 ParseSubtargetFeatures(FS, CPU);
36
37 // Small section size threshold
38 SSectionThreshold = SSThreshold;
3930
4031 // Is the target system Linux ?
4132 if (TT.find("linux") == std::string::npos)
5959 // isLinux - Target system is Linux. Is false we consider ELFOS for now.
6060 bool IsLinux;
6161
62 // Put global and static items less than or equal to SSectionThreshold
63 // bytes into the small data or bss section. The default is 8.
64 unsigned SSectionThreshold;
65
6662 /// Features related to the presence of specific instructions.
6763
6864 // HasSEInReg - SEB and SEH (signext in register) instructions.
112108 bool isNotSingleFloat() const { return !IsSingleFloat; };
113109 bool hasVFPU() const { return HasVFPU; };
114110 bool isLinux() const { return IsLinux; };
115 unsigned getSSectionThreshold() const { return SSectionThreshold; }
116111
117112 /// Features related to the presence of specific instructions.
118113 bool hasSEInReg() const { return HasSEInReg; };
0 //===-- MipsTargetObjectFile.cpp - Mips object files ----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MipsTargetObjectFile.h"
10 #include "llvm/DerivedTypes.h"
11 #include "llvm/GlobalVariable.h"
12 #include "llvm/MC/MCSectionELF.h"
13 #include "llvm/Target/TargetData.h"
14 #include "llvm/Target/TargetMachine.h"
15 #include "llvm/Support/CommandLine.h"
16 using namespace llvm;
17
18 static cl::opt
19 SSThreshold("mips-ssection-threshold", cl::Hidden,
20 cl::desc("Small data and bss section threshold size (default=8)"),
21 cl::init(8));
22
23 void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
24 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
25
26 SmallDataSection =
27 getELFSection(".sdata", MCSectionELF::SHT_PROGBITS,
28 MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
29 SectionKind::getDataRel());
30
31 SmallBSSSection =
32 getELFSection(".sbss", MCSectionELF::SHT_NOBITS,
33 MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
34 SectionKind::getBSS());
35
36 }
37
38 // A address must be loaded from a small section if its size is less than the
39 // small section size threshold. Data in this section must be addressed using
40 // gp_rel operator.
41 static bool IsInSmallSection(uint64_t Size) {
42 return Size > 0 && Size <= SSThreshold;
43 }
44
45 bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV,
46 const TargetMachine &TM) const {
47 if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
48 return false;
49
50 return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
51 }
52
53 /// IsGlobalInSmallSection - Return true if this global address should be
54 /// placed into small data/bss section.
55 bool MipsTargetObjectFile::
56 IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
57 SectionKind Kind) const {
58 // Only global variables, not functions.
59 const GlobalVariable *GVA = dyn_cast(GV);
60 if (!GVA)
61 return false;
62
63 // We can only do this for datarel or BSS objects for now.
64 if (!Kind.isBSS() && !Kind.isDataRel())
65 return false;
66
67 // If this is a internal constant string, there is a special
68 // section for it, but not in small data/bss.
69 if (Kind.isMergeable1ByteCString())
70 return false;
71
72 const Type *Ty = GV->getType()->getElementType();
73 return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
74 }
75
76
77
78 const MCSection *MipsTargetObjectFile::
79 SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
80 Mangler *Mang, const TargetMachine &TM) const {
81 // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
82 // sections?
83
84 // Handle Small Section classification here.
85 if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
86 return SmallBSSSection;
87 if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
88 return SmallDataSection;
89
90 // Otherwise, we work the same as ELF.
91 return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
92 }
0 //===-- llvm/Target/MipsTargetObjectFile.h - Mips Object Info ---*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
10 #define LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
11
12 #include "llvm/Target/TargetLoweringObjectFile.h"
13
14 namespace llvm {
15
16 class MipsTargetObjectFile : public TargetLoweringObjectFileELF {
17 const MCSection *SmallDataSection;
18 const MCSection *SmallBSSSection;
19 public:
20
21 void Initialize(MCContext &Ctx, const TargetMachine &TM);
22
23
24 /// IsGlobalInSmallSection - Return true if this global address should be
25 /// placed into small data/bss section.
26 bool IsGlobalInSmallSection(const GlobalValue *GV,
27 const TargetMachine &TM, SectionKind Kind)const;
28 bool IsGlobalInSmallSection(const GlobalValue *GV,
29 const TargetMachine &TM) const;
30
31 const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
32 SectionKind Kind,
33 Mangler *Mang,
34 const TargetMachine &TM) const;
35
36 // TODO: Classify globals as mips wishes.
37 };
38 } // end namespace llvm
39
40 #endif
0 ; RUN: llvm-as < %s | llc -mips-ssection-threshold=8 -march=mips -f -o %t0
1 ; RUN: llvm-as < %s | llc -mips-ssection-threshold=0 -march=mips -f -o %t1
2 ; RUN: grep {sdata} %t0 | count 1
3 ; RUN: grep {sbss} %t0 | count 1
4 ; RUN: grep {gp_rel} %t0 | count 2
5 ; RUN: not grep {sdata} %t1
6 ; RUN: not grep {sbss} %t1
7 ; RUN: not grep {gp_rel} %t1
8 ; RUN: grep {\%hi} %t1 | count 2
9 ; RUN: grep {\%lo} %t1 | count 2
10
11 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
12 target triple = "mipsallegrexel-psp-elf"
13
14 %struct.anon = type { i32, i32 }
15 @s0 = global [8 x i8] c"AAAAAAA\00", align 4
16 @foo = global %struct.anon { i32 2, i32 3 }
17 @bar = global %struct.anon zeroinitializer
18
19 define i8* @A0() nounwind {
20 entry:
21 ret i8* getelementptr ([8 x i8]* @s0, i32 0, i32 0)
22 }
23
24 define i32 @A1() nounwind {
25 entry:
26 load i32* getelementptr (%struct.anon* @foo, i32 0, i32 0), align 8
27 load i32* getelementptr (%struct.anon* @foo, i32 0, i32 1), align 4
28 add i32 %1, %0
29 ret i32 %2
30 }
31