aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp348
1 files changed, 169 insertions, 179 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 5f67d3daa97f..272baceeed89 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -12,11 +12,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/AsmPrinter.h"
+#include "CodeViewDebug.h"
#include "DwarfDebug.h"
#include "DwarfException.h"
#include "WinException.h"
-#include "WinCodeViewLineTables.h"
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/CodeGen/Analysis.h"
@@ -125,6 +124,10 @@ AsmPrinter::~AsmPrinter() {
}
}
+bool AsmPrinter::isPositionIndependent() const {
+ return TM.isPositionIndependent();
+}
+
/// getFunctionNumber - Return a unique ID for the current function.
///
unsigned AsmPrinter::getFunctionNumber() const {
@@ -248,12 +251,13 @@ bool AsmPrinter::doInitialization(Module &M) {
if (MAI->doesSupportDebugInformation()) {
bool EmitCodeView = MMI->getModule()->getCodeViewFlag();
if (EmitCodeView && TM.getTargetTriple().isKnownWindowsMSVCEnvironment()) {
- Handlers.push_back(HandlerInfo(new WinCodeViewLineTables(this),
+ Handlers.push_back(HandlerInfo(new CodeViewDebug(this),
DbgTimerName,
CodeViewLineTablesGroupName));
}
if (!EmitCodeView || MMI->getModule()->getDwarfVersion()) {
DD = new DwarfDebug(this, &M);
+ DD->beginModule();
Handlers.push_back(HandlerInfo(DD, DbgTimerName, DWARFGroupName));
}
}
@@ -319,21 +323,17 @@ void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Weak);
}
return;
- case GlobalValue::AppendingLinkage:
- // FIXME: appending linkage variables should go into a section of
- // their name or something. For now, just emit them as external.
case GlobalValue::ExternalLinkage:
- // If external or appending, declare as a global symbol.
- // .globl _foo
+ // If external, declare as a global symbol: .globl _foo
OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
return;
case GlobalValue::PrivateLinkage:
case GlobalValue::InternalLinkage:
return;
+ case GlobalValue::AppendingLinkage:
case GlobalValue::AvailableExternallyLinkage:
- llvm_unreachable("Should never emit this");
case GlobalValue::ExternalWeakLinkage:
- llvm_unreachable("Don't know how to emit these");
+ llvm_unreachable("Should never emit this");
}
llvm_unreachable("Unknown linkage type!");
}
@@ -347,51 +347,17 @@ MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const {
return TM.getSymbol(GV, *Mang);
}
-static MCSymbol *getOrCreateEmuTLSControlSym(MCSymbol *GVSym, MCContext &C) {
- return C.getOrCreateSymbol(Twine("__emutls_v.") + GVSym->getName());
-}
-
-static MCSymbol *getOrCreateEmuTLSInitSym(MCSymbol *GVSym, MCContext &C) {
- return C.getOrCreateSymbol(Twine("__emutls_t.") + GVSym->getName());
-}
-
-/// EmitEmulatedTLSControlVariable - Emit the control variable for an emulated TLS variable.
-void AsmPrinter::EmitEmulatedTLSControlVariable(const GlobalVariable *GV,
- MCSymbol *EmittedSym,
- bool AllZeroInitValue) {
- MCSection *TLSVarSection = getObjFileLowering().getDataSection();
- OutStreamer->SwitchSection(TLSVarSection);
- MCSymbol *GVSym = getSymbol(GV);
- EmitLinkage(GV, EmittedSym); // same linkage as GV
- const DataLayout &DL = GV->getParent()->getDataLayout();
- uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
- unsigned AlignLog = getGVAlignmentLog2(GV, DL);
- unsigned WordSize = DL.getPointerSize();
- unsigned Alignment = DL.getPointerABIAlignment();
- EmitAlignment(Log2_32(Alignment));
- OutStreamer->EmitLabel(EmittedSym);
- OutStreamer->EmitIntValue(Size, WordSize);
- OutStreamer->EmitIntValue((1 << AlignLog), WordSize);
- OutStreamer->EmitIntValue(0, WordSize);
- if (GV->hasInitializer() && !AllZeroInitValue) {
- OutStreamer->EmitSymbolValue(
- getOrCreateEmuTLSInitSym(GVSym, OutContext), WordSize);
- } else
- OutStreamer->EmitIntValue(0, WordSize);
- if (MAI->hasDotTypeDotSizeDirective())
- OutStreamer->emitELFSize(cast<MCSymbolELF>(EmittedSym),
- MCConstantExpr::create(4 * WordSize, OutContext));
- OutStreamer->AddBlankLine(); // End of the __emutls_v.* variable.
-}
-
/// EmitGlobalVariable - Emit the specified global variable to the .s file.
void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
- bool IsEmuTLSVar =
- GV->getThreadLocalMode() != llvm::GlobalVariable::NotThreadLocal &&
- TM.Options.EmulatedTLS;
+ bool IsEmuTLSVar = TM.Options.EmulatedTLS && GV->isThreadLocal();
assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) &&
"No emulated TLS variables in the common section");
+ // Never emit TLS variable xyz in emulated TLS model.
+ // The initialization value is in __emutls_t.xyz instead of xyz.
+ if (IsEmuTLSVar)
+ return;
+
if (GV->hasInitializer()) {
// Check to see if this is a special global used by LLVM, if so, emit it.
if (EmitSpecialLLVMGlobal(GV))
@@ -402,7 +368,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
if (GlobalGOTEquivs.count(getSymbol(GV)))
return;
- if (isVerbose() && !IsEmuTLSVar) {
+ if (isVerbose()) {
// When printing the control variable __emutls_v.*,
// we don't need to print the original TLS variable name.
GV->printAsOperand(OutStreamer->GetCommentOS(),
@@ -412,11 +378,11 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
}
MCSymbol *GVSym = getSymbol(GV);
- MCSymbol *EmittedSym = IsEmuTLSVar ?
- getOrCreateEmuTLSControlSym(GVSym, OutContext) : GVSym;
- // getOrCreateEmuTLSControlSym only creates the symbol with name and default attributes.
- // GV's or GVSym's attributes will be used for the EmittedSym.
+ MCSymbol *EmittedSym = GVSym;
+ // getOrCreateEmuTLSControlSym only creates the symbol with name and default
+ // attributes.
+ // GV's or GVSym's attributes will be used for the EmittedSym.
EmitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration());
if (!GV->hasInitializer()) // External globals require no extra code.
@@ -440,48 +406,47 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// sections and expected to be contiguous (e.g. ObjC metadata).
unsigned AlignLog = getGVAlignmentLog2(GV, DL);
- bool AllZeroInitValue = false;
- const Constant *InitValue = GV->getInitializer();
- if (isa<ConstantAggregateZero>(InitValue))
- AllZeroInitValue = true;
- else {
- const ConstantInt *InitIntValue = dyn_cast<ConstantInt>(InitValue);
- if (InitIntValue && InitIntValue->isZero())
- AllZeroInitValue = true;
- }
- if (IsEmuTLSVar)
- EmitEmulatedTLSControlVariable(GV, EmittedSym, AllZeroInitValue);
-
for (const HandlerInfo &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled);
HI.Handler->setSymbolSize(GVSym, Size);
}
- // Handle common and BSS local symbols (.lcomm).
- if (GVKind.isCommon() || GVKind.isBSSLocal()) {
- assert(!(IsEmuTLSVar && GVKind.isCommon()) &&
- "No emulated TLS variables in the common section");
+ // Handle common symbols
+ if (GVKind.isCommon()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
unsigned Align = 1 << AlignLog;
+ if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
+ Align = 0;
- // Handle common symbols.
- if (GVKind.isCommon()) {
- if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
- Align = 0;
+ // .comm _foo, 42, 4
+ OutStreamer->EmitCommonSymbol(GVSym, Size, Align);
+ return;
+ }
- // .comm _foo, 42, 4
- OutStreamer->EmitCommonSymbol(GVSym, Size, Align);
- return;
- }
+ // Determine to which section this global should be emitted.
+ MCSection *TheSection =
+ getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);
- // Handle local BSS symbols.
- if (MAI->hasMachoZeroFillDirective()) {
- MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);
- // .zerofill __DATA, __bss, _foo, 400, 5
- OutStreamer->EmitZerofill(TheSection, GVSym, Size, Align);
- return;
- }
+ // If we have a bss global going to a section that supports the
+ // zerofill directive, do so here.
+ if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective() &&
+ TheSection->isVirtualSection()) {
+ if (Size == 0)
+ Size = 1; // zerofill of 0 bytes is undefined.
+ unsigned Align = 1 << AlignLog;
+ EmitLinkage(GV, GVSym);
+ // .zerofill __DATA, __bss, _foo, 400, 5
+ OutStreamer->EmitZerofill(TheSection, GVSym, Size, Align);
+ return;
+ }
+
+ // If this is a BSS local symbol and we are emitting in the BSS
+ // section use .lcomm/.comm directive.
+ if (GVKind.isBSSLocal() &&
+ getObjFileLowering().getBSSSection() == TheSection) {
+ if (Size == 0)
+ Size = 1; // .comm Foo, 0 is undefined, avoid it.
+ unsigned Align = 1 << AlignLog;
// Use .lcomm only if it supports user-specified alignment.
// Otherwise, while it would still be correct to use .lcomm in some
@@ -505,30 +470,6 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
}
- if (IsEmuTLSVar && AllZeroInitValue)
- return; // No need of initialization values.
-
- MCSymbol *EmittedInitSym = IsEmuTLSVar ?
- getOrCreateEmuTLSInitSym(GVSym, OutContext) : GVSym;
- // getOrCreateEmuTLSInitSym only creates the symbol with name and default attributes.
- // GV's or GVSym's attributes will be used for the EmittedInitSym.
-
- MCSection *TheSection = IsEmuTLSVar ?
- getObjFileLowering().getReadOnlySection() :
- getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM);
-
- // Handle the zerofill directive on darwin, which is a special form of BSS
- // emission.
- if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective() && !IsEmuTLSVar) {
- if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined.
-
- // .globl _foo
- OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
- // .zerofill __DATA, __common, _foo, 400, 5
- OutStreamer->EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
- return;
- }
-
// Handle thread local data for mach-o which requires us to output an
// additional structure of data and mangle the original symbol so that we
// can reference it later.
@@ -539,7 +480,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// TLOF class. This will also make it more obvious that stuff like
// MCStreamer::EmitTBSSSymbol is macho specific and only called from macho
// specific code.
- if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective() && !IsEmuTLSVar) {
+ if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) {
// Emit the .tbss symbol
MCSymbol *MangSym =
OutContext.getOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));
@@ -581,11 +522,11 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return;
}
+ MCSymbol *EmittedInitSym = GVSym;
+
OutStreamer->SwitchSection(TheSection);
- // emutls_t.* symbols are only used in the current compilation unit.
- if (!IsEmuTLSVar)
- EmitLinkage(GV, EmittedInitSym);
+ EmitLinkage(GV, EmittedInitSym);
EmitAlignment(AlignLog, GV);
OutStreamer->EmitLabel(EmittedInitSym);
@@ -696,20 +637,20 @@ static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
// We assume a single instruction only has a spill or reload, not
// both.
const MachineMemOperand *MMO;
- if (TII->isLoadFromStackSlotPostFE(&MI, FI)) {
+ if (TII->isLoadFromStackSlotPostFE(MI, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
MMO = *MI.memoperands_begin();
CommentOS << MMO->getSize() << "-byte Reload\n";
}
- } else if (TII->hasLoadFromStackSlot(&MI, MMO, FI)) {
+ } else if (TII->hasLoadFromStackSlot(MI, MMO, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI))
CommentOS << MMO->getSize() << "-byte Folded Reload\n";
- } else if (TII->isStoreToStackSlotPostFE(&MI, FI)) {
+ } else if (TII->isStoreToStackSlotPostFE(MI, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI)) {
MMO = *MI.memoperands_begin();
CommentOS << MMO->getSize() << "-byte Spill\n";
}
- } else if (TII->hasStoreToStackSlot(&MI, MMO, FI)) {
+ } else if (TII->hasStoreToStackSlot(MI, MMO, FI)) {
if (FrameInfo->isSpillSlotObjectIndex(FI))
CommentOS << MMO->getSize() << "-byte Folded Spill\n";
}
@@ -745,7 +686,7 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {
AP.MF->getSubtarget().getRegisterInfo())
<< (Op.isDef() ? "<def>" : "<kill>");
}
- AP.OutStreamer->AddComment(Str);
+ AP.OutStreamer->AddComment(OS.str());
AP.OutStreamer->AddBlankLine();
}
@@ -1065,8 +1006,9 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
// Global GOT equivalents are unnamed private globals with a constant
// pointer initializer to another global symbol. They must point to a
// GlobalVariable or Function, i.e., as GlobalValue.
- if (!GV->hasUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
- !GV->isDiscardableIfUnused() || !dyn_cast<GlobalValue>(GV->getOperand(0)))
+ if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() ||
+ !GV->isConstant() || !GV->isDiscardableIfUnused() ||
+ !dyn_cast<GlobalValue>(GV->getOperand(0)))
return false;
// To be a got equivalent, at least one of its users need to be a constant
@@ -1118,6 +1060,52 @@ void AsmPrinter::emitGlobalGOTEquivs() {
EmitGlobalVariable(GV);
}
+void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
+ const GlobalIndirectSymbol& GIS) {
+ MCSymbol *Name = getSymbol(&GIS);
+
+ if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective())
+ OutStreamer->EmitSymbolAttribute(Name, MCSA_Global);
+ else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
+ OutStreamer->EmitSymbolAttribute(Name, MCSA_WeakReference);
+ else
+ assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage");
+
+ // Set the symbol type to function if the alias has a function type.
+ // This affects codegen when the aliasee is not a function.
+ if (GIS.getType()->getPointerElementType()->isFunctionTy()) {
+ OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
+ if (isa<GlobalIFunc>(GIS))
+ OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction);
+ }
+
+ EmitVisibility(Name, GIS.getVisibility());
+
+ const MCExpr *Expr = lowerConstant(GIS.getIndirectSymbol());
+
+ if (isa<GlobalAlias>(&GIS) && MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))
+ OutStreamer->EmitSymbolAttribute(Name, MCSA_AltEntry);
+
+ // Emit the directives as assignments aka .set:
+ OutStreamer->EmitAssignment(Name, Expr);
+
+ if (auto *GA = dyn_cast<GlobalAlias>(&GIS)) {
+ // If the aliasee does not correspond to a symbol in the output, i.e. the
+ // alias is not of an object or the aliased object is private, then set the
+ // size of the alias symbol from the type of the alias. We don't do this in
+ // other situations as the alias and aliasee having differing types but same
+ // size may be intentional.
+ const GlobalObject *BaseObject = GA->getBaseObject();
+ if (MAI->hasDotTypeDotSizeDirective() && GA->getValueType()->isSized() &&
+ (!BaseObject || BaseObject->hasPrivateLinkage())) {
+ const DataLayout &DL = M.getDataLayout();
+ uint64_t Size = DL.getTypeAllocSize(GA->getValueType());
+ OutStreamer->emitELFSize(cast<MCSymbolELF>(Name),
+ MCConstantExpr::create(Size, OutContext));
+ }
+ }
+}
+
bool AsmPrinter::doFinalization(Module &M) {
// Set the MachineFunction to nullptr so that we can catch attempted
// accesses to MF specific features at the module level and so that
@@ -1191,55 +1179,35 @@ bool AsmPrinter::doFinalization(Module &M) {
// to notice uses in operands (due to constant exprs etc). This should
// happen with the MC stuff eventually.
- // Print out module-level global variables here.
- for (const auto &G : M.globals()) {
- if (!G.hasExternalWeakLinkage())
+ // Print out module-level global objects here.
+ for (const auto &GO : M.global_objects()) {
+ if (!GO.hasExternalWeakLinkage())
continue;
- OutStreamer->EmitSymbolAttribute(getSymbol(&G), MCSA_WeakReference);
- }
-
- for (const auto &F : M) {
- if (!F.hasExternalWeakLinkage())
- continue;
- OutStreamer->EmitSymbolAttribute(getSymbol(&F), MCSA_WeakReference);
+ OutStreamer->EmitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference);
}
}
OutStreamer->AddBlankLine();
- for (const auto &Alias : M.aliases()) {
- MCSymbol *Name = getSymbol(&Alias);
-
- if (Alias.hasExternalLinkage() || !MAI->getWeakRefDirective())
- OutStreamer->EmitSymbolAttribute(Name, MCSA_Global);
- else if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage())
- OutStreamer->EmitSymbolAttribute(Name, MCSA_WeakReference);
- else
- assert(Alias.hasLocalLinkage() && "Invalid alias linkage");
-
- // Set the symbol type to function if the alias has a function type.
- // This affects codegen when the aliasee is not a function.
- if (Alias.getType()->getPointerElementType()->isFunctionTy())
- OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
-
- EmitVisibility(Name, Alias.getVisibility());
- // Emit the directives as assignments aka .set:
- OutStreamer->EmitAssignment(Name, lowerConstant(Alias.getAliasee()));
-
- // If the aliasee does not correspond to a symbol in the output, i.e. the
- // alias is not of an object or the aliased object is private, then set the
- // size of the alias symbol from the type of the alias. We don't do this in
- // other situations as the alias and aliasee having differing types but same
- // size may be intentional.
- const GlobalObject *BaseObject = Alias.getBaseObject();
- if (MAI->hasDotTypeDotSizeDirective() && Alias.getValueType()->isSized() &&
- (!BaseObject || BaseObject->hasPrivateLinkage())) {
- const DataLayout &DL = M.getDataLayout();
- uint64_t Size = DL.getTypeAllocSize(Alias.getValueType());
- OutStreamer->emitELFSize(cast<MCSymbolELF>(Name),
- MCConstantExpr::create(Size, OutContext));
+ // Print aliases in topological order, that is, for each alias a = b,
+ // b must be printed before a.
+ // This is because on some targets (e.g. PowerPC) linker expects aliases in
+ // such an order to generate correct TOC information.
+ SmallVector<const GlobalAlias *, 16> AliasStack;
+ SmallPtrSet<const GlobalAlias *, 16> AliasVisited;
+ for (const auto &Alias : M.aliases()) {
+ for (const GlobalAlias *Cur = &Alias; Cur;
+ Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {
+ if (!AliasVisited.insert(Cur).second)
+ break;
+ AliasStack.push_back(Cur);
}
+ for (const GlobalAlias *AncestorAlias : reverse(AliasStack))
+ emitGlobalIndirectSymbol(M, *AncestorAlias);
+ AliasStack.clear();
}
+ for (const auto &IFunc : M.ifuncs())
+ emitGlobalIndirectSymbol(M, IFunc);
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
@@ -1252,9 +1220,10 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit __morestack address if needed for indirect calls.
if (MMI->usesMorestackAddr()) {
+ unsigned Align = 1;
MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant(
getDataLayout(), SectionKind::getReadOnly(),
- /*C=*/nullptr);
+ /*C=*/nullptr, Align);
OutStreamer->SwitchSection(ReadOnlySection);
MCSymbol *AddrSymbol =
@@ -1344,8 +1313,8 @@ void AsmPrinter::EmitConstantPool() {
if (!CPE.isMachineConstantPoolEntry())
C = CPE.Val.ConstVal;
- MCSection *S =
- getObjFileLowering().getSectionForConstant(getDataLayout(), Kind, C);
+ MCSection *S = getObjFileLowering().getSectionForConstant(getDataLayout(),
+ Kind, C, Align);
// The number of sections are small, just do a linear search from the
// last section to the first.
@@ -1443,7 +1412,7 @@ void AsmPrinter::EmitJumpTableInfo() {
// For the EK_LabelDifference32 entry, if using .set avoids a relocation,
/// emit a .set directive for each unique entry.
if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&
- MAI->doesSetDirectiveSuppressesReloc()) {
+ MAI->doesSetDirectiveSuppressReloc()) {
SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets;
const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext);
@@ -1524,7 +1493,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
// If the .set directive avoids relocations, this is emitted as:
// .set L4_5_set_123, LBB123 - LJTI1_2
// .word L4_5_set_123
- if (MAI->doesSetDirectiveSuppressesReloc()) {
+ if (MAI->doesSetDirectiveSuppressReloc()) {
Value = MCSymbolRefExpr::create(GetJTSetSymbol(UID, MBB->getNumber()),
OutContext);
break;
@@ -1555,7 +1524,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
}
// Ignore debug and non-emitted data. This handles llvm.compiler.used.
- if (StringRef(GV->getSection()) == "llvm.metadata" ||
+ if (GV->getSection() == "llvm.metadata" ||
GV->hasAvailableExternallyLinkage())
return true;
@@ -1589,7 +1558,7 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
return true;
}
- return false;
+ report_fatal_error("unknown special variable");
}
/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each
@@ -1648,7 +1617,8 @@ void AsmPrinter::EmitXXStructorList(const DataLayout &DL, const Constant *List,
S.Priority = Priority->getLimitedValue(65535);
S.Func = CS->getOperand(1);
if (ETy->getNumElements() == 3 && !CS->getOperand(2)->isNullValue())
- S.ComdatKey = dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());
+ S.ComdatKey =
+ dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());
}
// Emit the function pointers in the target-specific order
@@ -1789,10 +1759,6 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
llvm_unreachable("Unknown constant value to lower!");
}
- if (const MCExpr *RelocExpr
- = getObjFileLowering().getExecutableRelativeSymbol(CE, *Mang, TM))
- return RelocExpr;
-
switch (CE->getOpcode()) {
default:
// If the code isn't optimized, there may be outstanding folding
@@ -1868,10 +1834,34 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
return MCBinaryExpr::createAnd(OpExpr, MaskExpr, Ctx);
}
+ case Instruction::Sub: {
+ GlobalValue *LHSGV;
+ APInt LHSOffset;
+ if (IsConstantOffsetFromGlobal(CE->getOperand(0), LHSGV, LHSOffset,
+ getDataLayout())) {
+ GlobalValue *RHSGV;
+ APInt RHSOffset;
+ if (IsConstantOffsetFromGlobal(CE->getOperand(1), RHSGV, RHSOffset,
+ getDataLayout())) {
+ const MCExpr *RelocExpr = getObjFileLowering().lowerRelativeReference(
+ LHSGV, RHSGV, *Mang, TM);
+ if (!RelocExpr)
+ RelocExpr = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx),
+ MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx);
+ int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();
+ if (Addend != 0)
+ RelocExpr = MCBinaryExpr::createAdd(
+ RelocExpr, MCConstantExpr::create(Addend, Ctx), Ctx);
+ return RelocExpr;
+ }
+ }
+ }
+ // else fallthrough
+
// The MC library also has a right-shift operator, but it isn't consistently
// signed or unsigned between different targets.
case Instruction::Add:
- case Instruction::Sub:
case Instruction::Mul:
case Instruction::SDiv:
case Instruction::SRem:
@@ -1964,7 +1954,7 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
uint64_t Bytes = DL.getTypeAllocSize(CDS->getType());
// Don't emit a 1-byte object as a .fill.
if (Bytes > 1)
- return AP.OutStreamer->EmitFill(Bytes, Value);
+ return AP.OutStreamer->emitFill(Bytes, Value);
}
// If this can be emitted with .ascii/.asciz, emit it as such.
@@ -2003,7 +1993,7 @@ static void emitGlobalConstantArray(const DataLayout &DL,
if (Value != -1) {
uint64_t Bytes = DL.getTypeAllocSize(CA->getType());
- AP.OutStreamer->EmitFill(Bytes, Value);
+ AP.OutStreamer->emitFill(Bytes, Value);
}
else {
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
@@ -2582,7 +2572,7 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
// If we are the operands of one of the branches, this is not a fall
// through. Note that targets with delay slots will usually bundle
// terminators with the delay slot instruction.
- for (ConstMIBundleOperands OP(&MI); OP.isValid(); ++OP) {
+ for (ConstMIBundleOperands OP(MI); OP.isValid(); ++OP) {
if (OP->isJTI())
return false;
if (OP->isMBB() && OP->getMBB() == MBB)