mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
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
This commit is contained in:
parent
d4c00c0f55
commit
b71b909bc7
@ -19,6 +19,7 @@ add_llvm_target(MipsCodeGen
|
||||
MipsSubtarget.cpp
|
||||
MipsTargetAsmInfo.cpp
|
||||
MipsTargetMachine.cpp
|
||||
MipsTargetObjectFile.cpp
|
||||
)
|
||||
|
||||
target_link_libraries (LLVMMipsCodeGen LLVMSelectionDAG)
|
||||
|
@ -13,10 +13,10 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "mips-lower"
|
||||
|
||||
#include "MipsISelLowering.h"
|
||||
#include "MipsMachineFunction.h"
|
||||
#include "MipsTargetMachine.h"
|
||||
#include "MipsTargetObjectFile.h"
|
||||
#include "MipsSubtarget.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Function.h"
|
||||
@ -30,7 +30,6 @@
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
using namespace llvm;
|
||||
@ -54,7 +53,7 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
|
||||
MipsTargetLowering::
|
||||
MipsTargetLowering(MipsTargetMachine &TM)
|
||||
: TargetLowering(TM, new TargetLoweringObjectFileELF()) {
|
||||
: TargetLowering(TM, new MipsTargetObjectFile()) {
|
||||
Subtarget = &TM.getSubtarget<MipsSubtarget>();
|
||||
|
||||
// Mips does not have i1 type, so use i32 for
|
||||
@ -210,37 +209,6 @@ AddLiveIn(MachineFunction &MF, unsigned PReg, TargetRegisterClass *RC)
|
||||
return VReg;
|
||||
}
|
||||
|
||||
// A address must be loaded from a small section if its size is less than the
|
||||
// small section size threshold. Data in this section must be addressed using
|
||||
// gp_rel operator.
|
||||
bool MipsTargetLowering::IsInSmallSection(unsigned Size) {
|
||||
return (Size > 0 && (Size <= Subtarget->getSSectionThreshold()));
|
||||
}
|
||||
|
||||
// Discover if this global address can be placed into small data/bss section.
|
||||
bool MipsTargetLowering::IsGlobalInSmallSection(GlobalValue *GV)
|
||||
{
|
||||
const TargetData *TD = getTargetData();
|
||||
const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
|
||||
|
||||
if (!GVA)
|
||||
return false;
|
||||
|
||||
const Type *Ty = GV->getType()->getElementType();
|
||||
unsigned Size = TD->getTypeAllocSize(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->hasLocalLinkage()) {
|
||||
Constant *C = GVA->getInitializer();
|
||||
const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
|
||||
if (CVA && CVA->isCString())
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsInSmallSection(Size);
|
||||
}
|
||||
|
||||
// Get fp branch code (not opcode) from condition code.
|
||||
static Mips::FPBranchCode GetFPBranchCodeFromCond(Mips::CondCode CC) {
|
||||
if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT)
|
||||
@ -525,8 +493,10 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
|
||||
if (getTargetMachine().getRelocationModel() != Reloc::PIC_) {
|
||||
SDVTList VTs = DAG.getVTList(MVT::i32);
|
||||
|
||||
MipsTargetObjectFile &TLOF = (MipsTargetObjectFile&)getObjFileLowering();
|
||||
|
||||
// %gp_rel relocation
|
||||
if (!isa<Function>(GV) && IsGlobalInSmallSection(GV)) {
|
||||
if (TLOF.IsGlobalInSmallSection(GV, getTargetMachine())) {
|
||||
SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
|
||||
SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
|
||||
return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode);
|
||||
|
@ -88,8 +88,6 @@ namespace llvm {
|
||||
// Subtarget Info
|
||||
const MipsSubtarget *Subtarget;
|
||||
|
||||
bool IsGlobalInSmallSection(GlobalValue *GV);
|
||||
bool IsInSmallSection(unsigned Size);
|
||||
|
||||
// Lower Operand helpers
|
||||
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||
|
@ -14,14 +14,8 @@
|
||||
#include "MipsSubtarget.h"
|
||||
#include "Mips.h"
|
||||
#include "MipsGenSubtarget.inc"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
using namespace llvm;
|
||||
|
||||
static 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 std::string &TT, const std::string &FS,
|
||||
bool little) :
|
||||
MipsArchVersion(Mips1), MipsABI(O32), IsLittle(little), IsSingleFloat(false),
|
||||
@ -35,9 +29,6 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &FS,
|
||||
// Parse features string.
|
||||
ParseSubtargetFeatures(FS, CPU);
|
||||
|
||||
// Small section size threshold
|
||||
SSectionThreshold = SSThreshold;
|
||||
|
||||
// Is the target system Linux ?
|
||||
if (TT.find("linux") == std::string::npos)
|
||||
IsLinux = false;
|
||||
|
@ -60,10 +60,6 @@ protected:
|
||||
// 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;
|
||||
|
||||
/// Features related to the presence of specific instructions.
|
||||
|
||||
// HasSEInReg - SEB and SEH (signext in register) instructions.
|
||||
@ -113,7 +109,6 @@ public:
|
||||
bool isNotSingleFloat() const { return !IsSingleFloat; };
|
||||
bool hasVFPU() const { return HasVFPU; };
|
||||
bool isLinux() const { return IsLinux; };
|
||||
unsigned getSSectionThreshold() const { return SSectionThreshold; }
|
||||
|
||||
/// Features related to the presence of specific instructions.
|
||||
bool hasSEInReg() const { return HasSEInReg; };
|
||||
|
93
lib/Target/Mips/MipsTargetObjectFile.cpp
Normal file
93
lib/Target/Mips/MipsTargetObjectFile.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
//===-- MipsTargetObjectFile.cpp - Mips object files ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MipsTargetObjectFile.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<unsigned>
|
||||
SSThreshold("mips-ssection-threshold", cl::Hidden,
|
||||
cl::desc("Small data and bss section threshold size (default=8)"),
|
||||
cl::init(8));
|
||||
|
||||
void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
||||
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
|
||||
|
||||
SmallDataSection =
|
||||
getELFSection(".sdata", MCSectionELF::SHT_PROGBITS,
|
||||
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getDataRel());
|
||||
|
||||
SmallBSSSection =
|
||||
getELFSection(".sbss", MCSectionELF::SHT_NOBITS,
|
||||
MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
|
||||
SectionKind::getBSS());
|
||||
|
||||
}
|
||||
|
||||
// A address must be loaded from a small section if its size is less than the
|
||||
// small section size threshold. Data in this section must be addressed using
|
||||
// gp_rel operator.
|
||||
static bool IsInSmallSection(uint64_t Size) {
|
||||
return Size > 0 && Size <= SSThreshold;
|
||||
}
|
||||
|
||||
bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV,
|
||||
const TargetMachine &TM) const {
|
||||
if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
|
||||
return false;
|
||||
|
||||
return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
|
||||
}
|
||||
|
||||
/// IsGlobalInSmallSection - Return true if this global address should be
|
||||
/// placed into small data/bss section.
|
||||
bool MipsTargetObjectFile::
|
||||
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
|
||||
SectionKind Kind) const {
|
||||
// Only global variables, not functions.
|
||||
const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
|
||||
if (!GVA)
|
||||
return false;
|
||||
|
||||
// We can only do this for datarel or BSS objects for now.
|
||||
if (!Kind.isBSS() && !Kind.isDataRel())
|
||||
return false;
|
||||
|
||||
// If this is a internal constant string, there is a special
|
||||
// section for it, but not in small data/bss.
|
||||
if (Kind.isMergeable1ByteCString())
|
||||
return false;
|
||||
|
||||
const Type *Ty = GV->getType()->getElementType();
|
||||
return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
|
||||
}
|
||||
|
||||
|
||||
|
||||
const MCSection *MipsTargetObjectFile::
|
||||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||
Mangler *Mang, const TargetMachine &TM) const {
|
||||
// TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
|
||||
// sections?
|
||||
|
||||
// Handle Small Section classification here.
|
||||
if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
|
||||
return SmallBSSSection;
|
||||
if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
|
||||
return SmallDataSection;
|
||||
|
||||
// Otherwise, we work the same as ELF.
|
||||
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
|
||||
}
|
41
lib/Target/Mips/MipsTargetObjectFile.h
Normal file
41
lib/Target/Mips/MipsTargetObjectFile.h
Normal file
@ -0,0 +1,41 @@
|
||||
//===-- llvm/Target/MipsTargetObjectFile.h - Mips Object Info ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
|
||||
#define LLVM_TARGET_MIPS_TARGETOBJECTFILE_H
|
||||
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MipsTargetObjectFile : public TargetLoweringObjectFileELF {
|
||||
const MCSection *SmallDataSection;
|
||||
const MCSection *SmallBSSSection;
|
||||
public:
|
||||
|
||||
void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
|
||||
|
||||
/// IsGlobalInSmallSection - Return true if this global address should be
|
||||
/// placed into small data/bss section.
|
||||
bool IsGlobalInSmallSection(const GlobalValue *GV,
|
||||
const TargetMachine &TM, SectionKind Kind)const;
|
||||
bool IsGlobalInSmallSection(const GlobalValue *GV,
|
||||
const TargetMachine &TM) const;
|
||||
|
||||
const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
|
||||
SectionKind Kind,
|
||||
Mangler *Mang,
|
||||
const TargetMachine &TM) const;
|
||||
|
||||
// TODO: Classify globals as mips wishes.
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
32
test/CodeGen/Mips/2008-07-15-SmallSection.ll
Normal file
32
test/CodeGen/Mips/2008-07-15-SmallSection.ll
Normal file
@ -0,0 +1,32 @@
|
||||
; RUN: llvm-as < %s | llc -mips-ssection-threshold=8 -march=mips -f -o %t0
|
||||
; RUN: llvm-as < %s | llc -mips-ssection-threshold=0 -march=mips -f -o %t1
|
||||
; RUN: grep {sdata} %t0 | count 1
|
||||
; RUN: grep {sbss} %t0 | count 1
|
||||
; RUN: grep {gp_rel} %t0 | count 2
|
||||
; RUN: not grep {sdata} %t1
|
||||
; RUN: not grep {sbss} %t1
|
||||
; RUN: not grep {gp_rel} %t1
|
||||
; RUN: grep {\%hi} %t1 | count 2
|
||||
; RUN: grep {\%lo} %t1 | count 2
|
||||
|
||||
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"
|
||||
target triple = "mipsallegrexel-psp-elf"
|
||||
|
||||
%struct.anon = type { i32, i32 }
|
||||
@s0 = global [8 x i8] c"AAAAAAA\00", align 4
|
||||
@foo = global %struct.anon { i32 2, i32 3 }
|
||||
@bar = global %struct.anon zeroinitializer
|
||||
|
||||
define i8* @A0() nounwind {
|
||||
entry:
|
||||
ret i8* getelementptr ([8 x i8]* @s0, i32 0, i32 0)
|
||||
}
|
||||
|
||||
define i32 @A1() nounwind {
|
||||
entry:
|
||||
load i32* getelementptr (%struct.anon* @foo, i32 0, i32 0), align 8
|
||||
load i32* getelementptr (%struct.anon* @foo, i32 0, i32 1), align 4
|
||||
add i32 %1, %0
|
||||
ret i32 %2
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user