X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetLoweringObjectFile.cpp;h=db543f33392be12cac978b1ec348d3f794cfdeba;hb=ffc045ab802ea542aabf1f1f22f97cb8a0ad6cde;hp=70abe5a05276158722ef0c7014a6151647ec051e;hpb=732f05c41f177a0bc4d47e93a5d02120f146cb4c;p=oota-llvm.git diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 70abe5a0527..db543f33392 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -13,22 +13,24 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Mangler.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/SmallString.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -41,10 +43,11 @@ using namespace llvm; void TargetLoweringObjectFile::Initialize(MCContext &ctx, const TargetMachine &TM) { Ctx = &ctx; + DL = TM.getDataLayout(); InitMCObjectFileInfo(TM.getTargetTriple(), TM.getRelocationModel(), TM.getCodeModel(), *Ctx); } - + TargetLoweringObjectFile::~TargetLoweringObjectFile() { } @@ -60,7 +63,7 @@ static bool isSuitableForBSS(const GlobalVariable *GV, bool NoZerosInBSS) { return false; // If the global has an explicit section specified, don't put it in BSS. - if (!GV->getSection().empty()) + if (GV->hasSection()) return false; // If -nozero-initialized-in-bss is specified, don't ever use BSS. @@ -73,39 +76,47 @@ static bool isSuitableForBSS(const GlobalVariable *GV, bool NoZerosInBSS) { /// IsNullTerminatedString - Return true if the specified constant (which is /// known to have a type that is an array of 1/2/4 byte elements) ends with a -/// nul value and contains no other nuls in it. +/// nul value and contains no other nuls in it. Note that this is more general +/// than ConstantDataSequential::isString because we allow 2 & 4 byte strings. static bool IsNullTerminatedString(const Constant *C) { - ArrayType *ATy = cast(C->getType()); - - // First check: is we have constant array of i8 terminated with zero - if (const ConstantArray *CVA = dyn_cast(C)) { - if (ATy->getNumElements() == 0) return false; - - ConstantInt *Null = - dyn_cast(CVA->getOperand(ATy->getNumElements()-1)); - if (Null == 0 || !Null->isZero()) + // First check: is we have constant array terminated with zero + if (const ConstantDataSequential *CDS = dyn_cast(C)) { + unsigned NumElts = CDS->getNumElements(); + assert(NumElts != 0 && "Can't have an empty CDS"); + + if (CDS->getElementAsInteger(NumElts-1) != 0) return false; // Not null terminated. - + // Verify that the null doesn't occur anywhere else in the string. - for (unsigned i = 0, e = ATy->getNumElements()-1; i != e; ++i) - // Reject constantexpr elements etc. - if (!isa(CVA->getOperand(i)) || - CVA->getOperand(i) == Null) + for (unsigned i = 0; i != NumElts-1; ++i) + if (CDS->getElementAsInteger(i) == 0) return false; return true; } // Another possibility: [1 x i8] zeroinitializer if (isa(C)) - return ATy->getNumElements() == 1; + return cast(C->getType())->getNumElements() == 1; return false; } -MCSymbol *TargetLoweringObjectFile:: -getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI) const { - return Mang->getSymbol(GV); +MCSymbol *TargetLoweringObjectFile::getSymbolWithGlobalValueBase( + const GlobalValue *GV, StringRef Suffix, Mangler &Mang, + const TargetMachine &TM) const { + assert(!Suffix.empty()); + + SmallString<60> NameStr; + NameStr += DL->getPrivateGlobalPrefix(); + TM.getNameWithPrefix(NameStr, GV, Mang); + NameStr.append(Suffix.begin(), Suffix.end()); + return Ctx->GetOrCreateSymbol(NameStr); +} + +MCSymbol *TargetLoweringObjectFile::getCFIPersonalitySymbol( + const GlobalValue *GV, Mangler &Mang, const TargetMachine &TM, + MachineModuleInfo *MMI) const { + return TM.getSymbol(GV, Mang); } void TargetLoweringObjectFile::emitPersonalityValue(MCStreamer &Streamer, @@ -128,7 +139,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, // Early exit - functions should be always in text sections. const GlobalVariable *GVar = dyn_cast(GV); - if (GVar == 0) + if (!GVar) return SectionKind::getText(); // Handle thread-local data first. @@ -157,7 +168,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, // a mergable string section, or general .data if it contains relocations. if (GVar->isConstant()) { // If the initializer for the global contains something that requires a - // relocation, then we may have to drop this into a wriable data section + // relocation, then we may have to drop this into a writable data section // even though it is marked const. switch (C->getRelocationInfo()) { case Constant::NoRelocation: @@ -189,11 +200,12 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, // Otherwise, just drop it into a mergable constant section. If we have // a section for this size, use it, otherwise use the arbitrary sized // mergable section. - switch (TM.getTargetData()->getTypeAllocSize(C->getType())) { + switch (TM.getDataLayout()->getTypeAllocSize(C->getType())) { case 4: return SectionKind::getMergeableConst4(); case 8: return SectionKind::getMergeableConst8(); case 16: return SectionKind::getMergeableConst16(); - default: return SectionKind::getMergeableConst(); + default: + return SectionKind::getReadOnly(); } case Constant::LocalRelocation: @@ -247,7 +259,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, /// the specified global variable or function definition. This should not /// be passed external (or available externally) globals. const MCSection *TargetLoweringObjectFile:: -SectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, +SectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { // Select section name. if (GV->hasSection()) @@ -258,67 +270,82 @@ SectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, return SelectSectionForGlobal(GV, Kind, Mang, TM); } +const MCSection *TargetLoweringObjectFile::getSectionForJumpTable( + const Function &F, Mangler &Mang, const TargetMachine &TM) const { + return getSectionForConstant(SectionKind::getReadOnly(), /*C=*/nullptr); +} -// Lame default implementation. Calculate the section name for global. -const MCSection * -TargetLoweringObjectFile::SelectSectionForGlobal(const GlobalValue *GV, - SectionKind Kind, - Mangler *Mang, - const TargetMachine &TM) const{ - assert(!Kind.isThreadLocal() && "Doesn't support TLS"); - - if (Kind.isText()) - return getTextSection(); - - if (Kind.isBSS() && BSSSection != 0) - return BSSSection; +bool TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( + bool UsesLabelDifference, const Function &F) const { + // In PIC mode, we need to emit the jump table to the same section as the + // function body itself, otherwise the label differences won't make sense. + // FIXME: Need a better predicate for this: what about custom entries? + if (UsesLabelDifference) + return true; - if (Kind.isReadOnly() && ReadOnlySection != 0) - return ReadOnlySection; + // We should also do if the section name is NULL or function is declared + // in discardable section + // FIXME: this isn't the right predicate, should be based on the MCSection + // for the function. + if (F.isWeakForLinker()) + return true; - return getDataSection(); + return false; } /// getSectionForConstant - Given a mergable constant with the /// specified size and relocation information, return a section that it /// should be placed in. const MCSection * -TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const { - if (Kind.isReadOnly() && ReadOnlySection != 0) +TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind, + const Constant *C) const { + if (Kind.isReadOnly() && ReadOnlySection != nullptr) return ReadOnlySection; return DataSection; } -/// getExprForDwarfGlobalReference - Return an MCExpr to use for a +/// getTTypeGlobalReference - Return an MCExpr to use for a /// reference to the specified global variable from exception /// handling information. -const MCExpr *TargetLoweringObjectFile:: -getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, - MCStreamer &Streamer) const { - const MCSymbol *Sym = Mang->getSymbol(GV); - return getExprForDwarfReference(Sym, Encoding, Streamer); +const MCExpr *TargetLoweringObjectFile::getTTypeGlobalReference( + const GlobalValue *GV, unsigned Encoding, Mangler &Mang, + const TargetMachine &TM, MachineModuleInfo *MMI, + MCStreamer &Streamer) const { + const MCSymbolRefExpr *Ref = + MCSymbolRefExpr::Create(TM.getSymbol(GV, Mang), getContext()); + + return getTTypeReference(Ref, Encoding, Streamer); } const MCExpr *TargetLoweringObjectFile:: -getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding, - MCStreamer &Streamer) const { - const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext()); - +getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding, + MCStreamer &Streamer) const { switch (Encoding & 0x70) { default: report_fatal_error("We do not support this DWARF encoding yet!"); case dwarf::DW_EH_PE_absptr: // Do nothing special - return Res; + return Sym; case dwarf::DW_EH_PE_pcrel: { // Emit a label to the streamer for the current position. This gives us // .-foo addressing. MCSymbol *PCSym = getContext().CreateTempSymbol(); Streamer.EmitLabel(PCSym); const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, getContext()); - return MCBinaryExpr::CreateSub(Res, PC, getContext()); + return MCBinaryExpr::CreateSub(Sym, PC, getContext()); } } } + +const MCExpr *TargetLoweringObjectFile::getDebugThreadLocalSymbol(const MCSymbol *Sym) const { + // FIXME: It's not clear what, if any, default this should have - perhaps a + // null return could mean 'no location' & we should just do that here. + return MCSymbolRefExpr::Create(Sym, *Ctx); +} + +void TargetLoweringObjectFile::getNameWithPrefix( + SmallVectorImpl &OutName, const GlobalValue *GV, + bool CannotUsePrivateLabel, Mangler &Mang, const TargetMachine &TM) const { + Mang.getNameWithPrefix(OutName, GV, CannotUsePrivateLabel); +}