aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp458
1 files changed, 313 insertions, 145 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 3e8e190eecc3..4a31bf85446b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -27,6 +27,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/ConstantFolding.h"
@@ -48,7 +49,6 @@
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
@@ -82,33 +82,26 @@
#include "llvm/IR/PseudoProbe.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
-#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
-#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
-#include "llvm/MC/MCSymbolXCOFF.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/SectionKind.h"
-#include "llvm/MC/TargetRegistry.h"
#include "llvm/Pass.h"
-#include "llvm/Remarks/Remark.h"
-#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Remarks/RemarkStreamer.h"
-#include "llvm/Remarks/RemarkStringTable.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
@@ -125,7 +118,6 @@
#include <cinttypes>
#include <cstdint>
#include <iterator>
-#include <limits>
#include <memory>
#include <string>
#include <utility>
@@ -135,11 +127,6 @@ using namespace llvm;
#define DEBUG_TYPE "asm-printer"
-// FIXME: this option currently only applies to DWARF, and not CodeView, tables
-static cl::opt<bool>
- DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
- cl::desc("Disable debug info printing"));
-
const char DWARFGroupName[] = "dwarf";
const char DWARFGroupDescription[] = "DWARF Emission";
const char DbgTimerName[] = "emit";
@@ -167,6 +154,178 @@ static gcp_map_type &getGCMap(void *&P) {
return *(gcp_map_type*)P;
}
+namespace {
+class AddrLabelMapCallbackPtr final : CallbackVH {
+ AddrLabelMap *Map = nullptr;
+
+public:
+ AddrLabelMapCallbackPtr() = default;
+ AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {}
+
+ void setPtr(BasicBlock *BB) {
+ ValueHandleBase::operator=(BB);
+ }
+
+ void setMap(AddrLabelMap *map) { Map = map; }
+
+ void deleted() override;
+ void allUsesReplacedWith(Value *V2) override;
+};
+} // namespace
+
+class llvm::AddrLabelMap {
+ MCContext &Context;
+ struct AddrLabelSymEntry {
+ /// The symbols for the label.
+ TinyPtrVector<MCSymbol *> Symbols;
+
+ Function *Fn; // The containing function of the BasicBlock.
+ unsigned Index; // The index in BBCallbacks for the BasicBlock.
+ };
+
+ DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;
+
+ /// Callbacks for the BasicBlock's that we have entries for. We use this so
+ /// we get notified if a block is deleted or RAUWd.
+ std::vector<AddrLabelMapCallbackPtr> BBCallbacks;
+
+ /// This is a per-function list of symbols whose corresponding BasicBlock got
+ /// deleted. These symbols need to be emitted at some point in the file, so
+ /// AsmPrinter emits them after the function body.
+ DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>
+ DeletedAddrLabelsNeedingEmission;
+
+public:
+ AddrLabelMap(MCContext &context) : Context(context) {}
+
+ ~AddrLabelMap() {
+ assert(DeletedAddrLabelsNeedingEmission.empty() &&
+ "Some labels for deleted blocks never got emitted");
+ }
+
+ ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);
+
+ void takeDeletedSymbolsForFunction(Function *F,
+ std::vector<MCSymbol *> &Result);
+
+ void UpdateForDeletedBlock(BasicBlock *BB);
+ void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);
+};
+
+ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {
+ assert(BB->hasAddressTaken() &&
+ "Shouldn't get label for block without address taken");
+ AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
+
+ // If we already had an entry for this block, just return it.
+ if (!Entry.Symbols.empty()) {
+ assert(BB->getParent() == Entry.Fn && "Parent changed");
+ return Entry.Symbols;
+ }
+
+ // Otherwise, this is a new entry, create a new symbol for it and add an
+ // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.
+ BBCallbacks.emplace_back(BB);
+ BBCallbacks.back().setMap(this);
+ Entry.Index = BBCallbacks.size() - 1;
+ Entry.Fn = BB->getParent();
+ MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol()
+ : Context.createTempSymbol();
+ Entry.Symbols.push_back(Sym);
+ return Entry.Symbols;
+}
+
+/// If we have any deleted symbols for F, return them.
+void AddrLabelMap::takeDeletedSymbolsForFunction(
+ Function *F, std::vector<MCSymbol *> &Result) {
+ DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I =
+ DeletedAddrLabelsNeedingEmission.find(F);
+
+ // If there are no entries for the function, just return.
+ if (I == DeletedAddrLabelsNeedingEmission.end())
+ return;
+
+ // Otherwise, take the list.
+ std::swap(Result, I->second);
+ DeletedAddrLabelsNeedingEmission.erase(I);
+}
+
+//===- Address of Block Management ----------------------------------------===//
+
+ArrayRef<MCSymbol *>
+AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) {
+ // Lazily create AddrLabelSymbols.
+ if (!AddrLabelSymbols)
+ AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext);
+ return AddrLabelSymbols->getAddrLabelSymbolToEmit(
+ const_cast<BasicBlock *>(BB));
+}
+
+void AsmPrinter::takeDeletedSymbolsForFunction(
+ const Function *F, std::vector<MCSymbol *> &Result) {
+ // If no blocks have had their addresses taken, we're done.
+ if (!AddrLabelSymbols)
+ return;
+ return AddrLabelSymbols->takeDeletedSymbolsForFunction(
+ const_cast<Function *>(F), Result);
+}
+
+void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {
+ // If the block got deleted, there is no need for the symbol. If the symbol
+ // was already emitted, we can just forget about it, otherwise we need to
+ // queue it up for later emission when the function is output.
+ AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
+ AddrLabelSymbols.erase(BB);
+ assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");
+ BBCallbacks[Entry.Index] = nullptr; // Clear the callback.
+
+#if !LLVM_MEMORY_SANITIZER_BUILD
+ // BasicBlock is destroyed already, so this access is UB detectable by msan.
+ assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&
+ "Block/parent mismatch");
+#endif
+
+ for (MCSymbol *Sym : Entry.Symbols) {
+ if (Sym->isDefined())
+ return;
+
+ // If the block is not yet defined, we need to emit it at the end of the
+ // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list
+ // for the containing Function. Since the block is being deleted, its
+ // parent may already be removed, we have to get the function from 'Entry'.
+ DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
+ }
+}
+
+void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
+ // Get the entry for the RAUW'd block and remove it from our map.
+ AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
+ AddrLabelSymbols.erase(Old);
+ assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");
+
+ AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
+
+ // If New is not address taken, just move our symbol over to it.
+ if (NewEntry.Symbols.empty()) {
+ BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.
+ NewEntry = std::move(OldEntry); // Set New's entry.
+ return;
+ }
+
+ BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.
+
+ // Otherwise, we need to add the old symbols to the new block's set.
+ llvm::append_range(NewEntry.Symbols, OldEntry.Symbols);
+}
+
+void AddrLabelMapCallbackPtr::deleted() {
+ Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
+}
+
+void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {
+ Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
+}
+
/// getGVAlignment - Return the alignment to use for the specified global
/// value. This rounds up to the preferred alignment if possible and legal.
Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
@@ -271,6 +430,10 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
bool AsmPrinter::doInitialization(Module &M) {
auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
MMI = MMIWP ? &MMIWP->getMMI() : nullptr;
+ HasSplitStack = false;
+ HasNoSplitStack = false;
+
+ AddrLabelSymbols = nullptr;
// Initialize TargetLoweringObjectFile.
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
@@ -281,9 +444,6 @@ bool AsmPrinter::doInitialization(Module &M) {
OutStreamer->initSections(false, *TM.getMCSubtargetInfo());
- if (DisableDebugInfoPrinting)
- MMI->setDebugInfoAvailability(false);
-
// Emit the version-min deployment target directive if needed.
//
// FIXME: If we end up with a collection of these sorts of Darwin-specific
@@ -335,11 +495,11 @@ bool AsmPrinter::doInitialization(Module &M) {
// Emit module-level inline asm if it exists.
if (!M.getModuleInlineAsm().empty()) {
OutStreamer->AddComment("Start of file scope inline assembly");
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
emitInlineAsm(M.getModuleInlineAsm() + "\n", *TM.getMCSubtargetInfo(),
TM.Options.MCOptions);
OutStreamer->AddComment("End of file scope inline assembly");
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
}
if (MAI->doesSupportDebugInformation()) {
@@ -351,7 +511,7 @@ bool AsmPrinter::doInitialization(Module &M) {
CodeViewLineTablesGroupDescription);
}
if (!EmitCodeView || M.getDwarfVersion()) {
- if (!DisableDebugInfoPrinting) {
+ if (MMI->hasDebugInfo()) {
DD = new DwarfDebug(this);
Handlers.emplace_back(std::unique_ptr<DwarfDebug>(DD), DbgTimerName,
DbgTimerDescription, DWARFGroupName,
@@ -536,9 +696,9 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
if (isVerbose()) {
// When printing the control variable __emutls_v.*,
// we don't need to print the original TLS variable name.
- GV->printAsOperand(OutStreamer->GetCommentOS(),
- /*PrintType=*/false, GV->getParent());
- OutStreamer->GetCommentOS() << '\n';
+ GV->printAsOperand(OutStreamer->getCommentOS(),
+ /*PrintType=*/false, GV->getParent());
+ OutStreamer->getCommentOS() << '\n';
}
}
@@ -652,7 +812,7 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
TheSection = getObjFileLowering().getTLSBSSSection();
OutStreamer->emitTBSSSymbol(TheSection, MangSym, Size, Alignment.value());
} else if (GVKind.isThreadData()) {
- OutStreamer->SwitchSection(TheSection);
+ OutStreamer->switchSection(TheSection);
emitAlignment(Alignment, GV);
OutStreamer->emitLabel(MangSym);
@@ -661,12 +821,12 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
GV->getInitializer());
}
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
// Emit the variable struct for the runtime.
MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection();
- OutStreamer->SwitchSection(TLVSect);
+ OutStreamer->switchSection(TLVSect);
// Emit the linkage here.
emitLinkage(GV, GVSym);
OutStreamer->emitLabel(GVSym);
@@ -681,13 +841,13 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
OutStreamer->emitIntValue(0, PtrSize);
OutStreamer->emitSymbolValue(MangSym, PtrSize);
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
return;
}
MCSymbol *EmittedInitSym = GVSym;
- OutStreamer->SwitchSection(TheSection);
+ OutStreamer->switchSection(TheSection);
emitLinkage(GV, EmittedInitSym);
emitAlignment(Alignment, GV);
@@ -704,7 +864,7 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
OutStreamer->emitELFSize(EmittedInitSym,
MCConstantExpr::create(Size, OutContext));
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
}
/// Emit the directive and value for debug thread local expression
@@ -723,7 +883,7 @@ void AsmPrinter::emitFunctionHeader() {
const Function &F = MF->getFunction();
if (isVerbose())
- OutStreamer->GetCommentOS()
+ OutStreamer->getCommentOS()
<< "-- Begin function "
<< GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';
@@ -737,7 +897,7 @@ void AsmPrinter::emitFunctionHeader() {
MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM));
else
MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM));
- OutStreamer->SwitchSection(MF->getSection());
+ OutStreamer->switchSection(MF->getSection());
if (!MAI->hasVisibilityOnlyWithLinkage())
emitVisibility(CurrentFnSym, F.getVisibility());
@@ -756,10 +916,10 @@ void AsmPrinter::emitFunctionHeader() {
OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);
if (isVerbose()) {
- F.printAsOperand(OutStreamer->GetCommentOS(),
- /*PrintType=*/false, F.getParent());
+ F.printAsOperand(OutStreamer->getCommentOS(),
+ /*PrintType=*/false, F.getParent());
emitFunctionHeaderComment();
- OutStreamer->GetCommentOS() << '\n';
+ OutStreamer->getCommentOS() << '\n';
}
// Emit the prefix data.
@@ -817,7 +977,7 @@ void AsmPrinter::emitFunctionHeader() {
// references to the dangling symbols. Emit them at the start of the function
// so that we don't get references to undefined symbols.
std::vector<MCSymbol*> DeadBlockSyms;
- MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms);
+ takeDeletedSymbolsForFunction(&F, DeadBlockSyms);
for (MCSymbol *DeadBlockSym : DeadBlockSyms) {
OutStreamer->AddComment("Address taken block that was later removed");
OutStreamer->emitLabel(DeadBlockSym);
@@ -844,6 +1004,24 @@ void AsmPrinter::emitFunctionHeader() {
// Emit the prologue data.
if (F.hasPrologueData())
emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData());
+
+ // Emit the function prologue data for the indirect call sanitizer.
+ if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {
+ assert(TM.getTargetTriple().getArch() == Triple::x86 ||
+ TM.getTargetTriple().getArch() == Triple::x86_64);
+ assert(MD->getNumOperands() == 2);
+
+ auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
+ auto *FTRTTIProxy = mdconst::extract<Constant>(MD->getOperand(1));
+ assert(PrologueSig && FTRTTIProxy);
+ emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
+
+ const MCExpr *Proxy = lowerConstant(FTRTTIProxy);
+ const MCExpr *FnExp = MCSymbolRefExpr::create(CurrentFnSym, OutContext);
+ const MCExpr *PCRel = MCBinaryExpr::createSub(Proxy, FnExp, OutContext);
+ // Use 32 bit since only small code model is supported.
+ OutStreamer->emitValue(PCRel, 4u);
+ }
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
@@ -912,7 +1090,7 @@ void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const {
<< printReg(RegNo, MF->getSubtarget().getRegisterInfo());
OutStreamer->AddComment(OS.str());
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
}
static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {
@@ -925,7 +1103,7 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {
<< printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo());
}
AP.OutStreamer->AddComment(OS.str());
- AP.OutStreamer->AddBlankLine();
+ AP.OutStreamer->addBlankLine();
}
/// emitDebugValueComment - This method handles the target-independent form
@@ -1147,32 +1325,42 @@ void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {
const MCSymbol *FunctionSymbol = getFunctionBegin();
- OutStreamer->PushSection();
- OutStreamer->SwitchSection(BBAddrMapSection);
+ OutStreamer->pushSection();
+ OutStreamer->switchSection(BBAddrMapSection);
+ OutStreamer->AddComment("version");
+ OutStreamer->emitInt8(OutStreamer->getContext().getBBAddrMapVersion());
+ OutStreamer->AddComment("feature");
+ OutStreamer->emitInt8(0);
+ OutStreamer->AddComment("function address");
OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());
- // Emit the total number of basic blocks in this function.
+ OutStreamer->AddComment("number of basic blocks");
OutStreamer->emitULEB128IntValue(MF.size());
+ const MCSymbol *PrevMBBEndSymbol = FunctionSymbol;
// Emit BB Information for each basic block in the funciton.
for (const MachineBasicBlock &MBB : MF) {
const MCSymbol *MBBSymbol =
MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();
- // Emit the basic block offset.
- emitLabelDifferenceAsULEB128(MBBSymbol, FunctionSymbol);
+ // Emit the basic block offset relative to the end of the previous block.
+ // This is zero unless the block is padded due to alignment.
+ emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol);
// Emit the basic block size. When BBs have alignments, their size cannot
// always be computed from their offsets.
emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);
OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));
+ PrevMBBEndSymbol = MBB.getEndSymbol();
}
- OutStreamer->PopSection();
+ OutStreamer->popSection();
}
void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) {
- auto GUID = MI.getOperand(0).getImm();
- auto Index = MI.getOperand(1).getImm();
- auto Type = MI.getOperand(2).getImm();
- auto Attr = MI.getOperand(3).getImm();
- DILocation *DebugLoc = MI.getDebugLoc();
- PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc);
+ if (PP) {
+ auto GUID = MI.getOperand(0).getImm();
+ auto Index = MI.getOperand(1).getImm();
+ auto Type = MI.getOperand(2).getImm();
+ auto Attr = MI.getOperand(3).getImm();
+ DILocation *DebugLoc = MI.getDebugLoc();
+ PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc);
+ }
}
void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
@@ -1189,15 +1377,16 @@ void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
if (FrameInfo.hasVarSizedObjects())
return;
- OutStreamer->PushSection();
- OutStreamer->SwitchSection(StackSizeSection);
+ OutStreamer->pushSection();
+ OutStreamer->switchSection(StackSizeSection);
const MCSymbol *FunctionSymbol = getFunctionBegin();
- uint64_t StackSize = FrameInfo.getStackSize();
+ uint64_t StackSize =
+ FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize();
OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());
OutStreamer->emitULEB128IntValue(StackSize);
- OutStreamer->PopSection();
+ OutStreamer->popSection();
}
void AsmPrinter::emitStackUsage(const MachineFunction &MF) {
@@ -1208,7 +1397,8 @@ void AsmPrinter::emitStackUsage(const MachineFunction &MF) {
return;
const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
- uint64_t StackSize = FrameInfo.getStackSize();
+ uint64_t StackSize =
+ FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize();
if (StackUsageStream == nullptr) {
std::error_code EC;
@@ -1298,7 +1488,7 @@ void AsmPrinter::emitFunctionBody() {
}
if (isVerbose())
- emitComments(MI, OutStreamer->GetCommentOS());
+ emitComments(MI, OutStreamer->getCommentOS());
switch (MI.getOpcode()) {
case TargetOpcode::CFI_INSTRUCTION:
@@ -1460,7 +1650,7 @@ void AsmPrinter::emitFunctionBody() {
}
// Switch to the original section in case basic block sections was used.
- OutStreamer->SwitchSection(MF->getSection());
+ OutStreamer->switchSection(MF->getSection());
const Function &F = MF->getFunction();
for (const auto &BB : F) {
@@ -1527,9 +1717,9 @@ void AsmPrinter::emitFunctionBody() {
emitPatchableFunctionEntries();
if (isVerbose())
- OutStreamer->GetCommentOS() << "-- End function\n";
+ OutStreamer->getCommentOS() << "-- End function\n";
- OutStreamer->AddBlankLine();
+ OutStreamer->addBlankLine();
}
/// Compute the number of Global Variables that uses a Constant.
@@ -1617,10 +1807,7 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
// Treat bitcasts of functions as functions also. This is important at least
// on WebAssembly where object and function addresses can't alias each other.
if (!IsFunction)
- if (auto *CE = dyn_cast<ConstantExpr>(GA.getAliasee()))
- if (CE->getOpcode() == Instruction::BitCast)
- IsFunction =
- CE->getOperand(0)->getType()->getPointerElementType()->isFunctionTy();
+ IsFunction = isa<Function>(GA.getAliasee()->stripPointerCasts());
// AIX's assembly directive `.set` is not usable for aliasing purpose,
// so AIX has to use the extra-label-at-definition strategy. At this
@@ -1650,13 +1837,13 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
if (IsFunction) {
OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
if (TM.getTargetTriple().isOSBinFormatCOFF()) {
- OutStreamer->BeginCOFFSymbolDef(Name);
- OutStreamer->EmitCOFFSymbolStorageClass(
+ OutStreamer->beginCOFFSymbolDef(Name);
+ OutStreamer->emitCOFFSymbolStorageClass(
GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC
: COFF::IMAGE_SYM_CLASS_EXTERNAL);
- OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+ OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
<< COFF::SCT_COMPLEX_TYPE_SHIFT);
- OutStreamer->EndCOFFSymbolDef();
+ OutStreamer->endCOFFSymbolDef();
}
}
@@ -1734,7 +1921,7 @@ void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
// Switch to the remarks section.
MCSection *RemarksSection =
OutContext.getObjectFileInfo()->getRemarksSection();
- OutStreamer->SwitchSection(RemarksSection);
+ OutStreamer->switchSection(RemarksSection);
OutStreamer->emitBinaryData(OS.str());
}
@@ -1805,7 +1992,7 @@ bool AsmPrinter::doFinalization(Module &M) {
// Output stubs for external and common global variables.
MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
if (!Stubs.empty()) {
- OutStreamer->SwitchSection(TLOF.getDataSection());
+ OutStreamer->switchSection(TLOF.getDataSection());
const DataLayout &DL = M.getDataLayout();
emitAlignment(Align(DL.getPointerSize()));
@@ -1829,7 +2016,7 @@ bool AsmPrinter::doFinalization(Module &M) {
for (const auto &Stub : Stubs) {
SmallString<256> SectionName = StringRef(".rdata$");
SectionName += Stub.first->getName();
- OutStreamer->SwitchSection(OutContext.getCOFFSection(
+ OutStreamer->switchSection(OutContext.getCOFFSection(
SectionName,
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_LNK_COMDAT,
@@ -1920,31 +2107,14 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit bytes for llvm.commandline metadata.
emitModuleCommandLines(M);
- // Emit __morestack address if needed for indirect calls.
- if (MMI->usesMorestackAddr()) {
- Align Alignment(1);
- MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant(
- getDataLayout(), SectionKind::getReadOnly(),
- /*C=*/nullptr, Alignment);
- OutStreamer->SwitchSection(ReadOnlySection);
-
- MCSymbol *AddrSymbol =
- OutContext.getOrCreateSymbol(StringRef("__morestack_addr"));
- OutStreamer->emitLabel(AddrSymbol);
-
- unsigned PtrSize = MAI->getCodePointerSize();
- OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"),
- PtrSize);
- }
-
// Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if
// split-stack is used.
- if (TM.getTargetTriple().isOSBinFormatELF() && MMI->hasSplitStack()) {
- OutStreamer->SwitchSection(
- OutContext.getELFSection(".note.GNU-split-stack", ELF::SHT_PROGBITS, 0));
- if (MMI->hasNosplitStack())
- OutStreamer->SwitchSection(
- OutContext.getELFSection(".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));
+ if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) {
+ OutStreamer->switchSection(OutContext.getELFSection(".note.GNU-split-stack",
+ ELF::SHT_PROGBITS, 0));
+ if (HasNoSplitStack)
+ OutStreamer->switchSection(OutContext.getELFSection(
+ ".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));
}
// If we don't have any trampolines, then we don't require stack memory
@@ -1952,7 +2122,7 @@ bool AsmPrinter::doFinalization(Module &M) {
Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
if (MCSection *S = MAI->getNonexecutableStackSection(OutContext))
- OutStreamer->SwitchSection(S);
+ OutStreamer->switchSection(S);
if (TM.Options.EmitAddrsig) {
// Emit address-significance attributes for all globals.
@@ -1973,7 +2143,7 @@ bool AsmPrinter::doFinalization(Module &M) {
GV.getVisibility() != GlobalValue::DefaultVisibility)
continue;
- OutStreamer->SwitchSection(
+ OutStreamer->switchSection(
OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0,
"", false, ++UniqueID, nullptr));
OutStreamer->emitBytes(GV.getPartition());
@@ -1989,8 +2159,9 @@ bool AsmPrinter::doFinalization(Module &M) {
emitEndOfAsmFile(M);
MMI = nullptr;
+ AddrLabelSymbols = nullptr;
- OutStreamer->Finish();
+ OutStreamer->finish();
OutStreamer->reset();
OwnedMLI.reset();
OwnedMDT.reset();
@@ -2009,6 +2180,16 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
this->MF = &MF;
const Function &F = MF.getFunction();
+ // Record that there are split-stack functions, so we will emit a special
+ // section to tell the linker.
+ if (MF.shouldSplitStack()) {
+ HasSplitStack = true;
+
+ if (!MF.getFrameInfo().needsSplitStackProlog())
+ HasNoSplitStack = true;
+ } else
+ HasNoSplitStack = true;
+
// Get the function symbol.
if (!MAI->needsFunctionDescriptors()) {
CurrentFnSym = getSymbol(&MF.getFunction());
@@ -2113,7 +2294,7 @@ void AsmPrinter::emitConstantPool() {
continue;
if (CurSection != CPSections[i].S) {
- OutStreamer->SwitchSection(CPSections[i].S);
+ OutStreamer->switchSection(CPSections[i].S);
emitAlignment(Align(CPSections[i].Alignment));
CurSection = CPSections[i].S;
Offset = 0;
@@ -2156,7 +2337,7 @@ void AsmPrinter::emitJumpTableInfo() {
if (JTInDiffSection) {
// Drop it in the readonly section.
MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM);
- OutStreamer->SwitchSection(ReadOnlySection);
+ OutStreamer->switchSection(ReadOnlySection);
}
emitAlignment(Align(MJTI->getEntryAlignment(DL)));
@@ -2392,7 +2573,7 @@ void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,
MCSection *OutputSection =
(IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)
: Obj.getStaticDtorSection(S.Priority, KeySym));
- OutStreamer->SwitchSection(OutputSection);
+ OutStreamer->switchSection(OutputSection);
if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())
emitAlignment(Align);
emitXXStructor(DL, S.Func);
@@ -2423,8 +2604,8 @@ void AsmPrinter::emitModuleCommandLines(Module &M) {
if (!NMD || !NMD->getNumOperands())
return;
- OutStreamer->PushSection();
- OutStreamer->SwitchSection(CommandLine);
+ OutStreamer->pushSection();
+ OutStreamer->switchSection(CommandLine);
OutStreamer->emitZeros(1);
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
const MDNode *N = NMD->getOperand(i);
@@ -2434,7 +2615,7 @@ void AsmPrinter::emitModuleCommandLines(Module &M) {
OutStreamer->emitBytes(S->getString());
OutStreamer->emitZeros(1);
}
- OutStreamer->PopSection();
+ OutStreamer->popSection();
}
//===--------------------------------------------------------------------===//
@@ -2471,7 +2652,7 @@ void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
unsigned Size,
bool IsSectionRelative) const {
if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) {
- OutStreamer->EmitCOFFSecRel32(Label, Offset);
+ OutStreamer->emitCOFFSecRel32(Label, Offset);
if (Size > 4)
OutStreamer->emitZeros(Size - 4);
return;
@@ -2541,6 +2722,9 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
llvm_unreachable("Unknown constant value to lower!");
}
+ // The constant expression opcodes are limited to those that are necessary
+ // to represent relocations on supported targets. Expressions involving only
+ // constant addresses are constant folded instead.
switch (CE->getOpcode()) {
case Instruction::AddrSpaceCast: {
const Constant *Op = CE->getOperand(0);
@@ -2658,34 +2842,17 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
return RelocExpr;
}
}
+
+ const MCExpr *LHS = lowerConstant(CE->getOperand(0));
+ const MCExpr *RHS = lowerConstant(CE->getOperand(1));
+ return MCBinaryExpr::createSub(LHS, RHS, Ctx);
+ break;
}
- // else fallthrough
- LLVM_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::Mul:
- case Instruction::SDiv:
- case Instruction::SRem:
- case Instruction::Shl:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor: {
+ case Instruction::Add: {
const MCExpr *LHS = lowerConstant(CE->getOperand(0));
const MCExpr *RHS = lowerConstant(CE->getOperand(1));
- switch (CE->getOpcode()) {
- default: llvm_unreachable("Unknown binary operator constant cast expr");
- case Instruction::Add: return MCBinaryExpr::createAdd(LHS, RHS, Ctx);
- case Instruction::Sub: return MCBinaryExpr::createSub(LHS, RHS, Ctx);
- case Instruction::Mul: return MCBinaryExpr::createMul(LHS, RHS, Ctx);
- case Instruction::SDiv: return MCBinaryExpr::createDiv(LHS, RHS, Ctx);
- case Instruction::SRem: return MCBinaryExpr::createMod(LHS, RHS, Ctx);
- case Instruction::Shl: return MCBinaryExpr::createShl(LHS, RHS, Ctx);
- case Instruction::And: return MCBinaryExpr::createAnd(LHS, RHS, Ctx);
- case Instruction::Or: return MCBinaryExpr::createOr (LHS, RHS, Ctx);
- case Instruction::Xor: return MCBinaryExpr::createXor(LHS, RHS, Ctx);
- }
+ return MCBinaryExpr::createAdd(LHS, RHS, Ctx);
}
}
}
@@ -2719,7 +2886,7 @@ static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) {
assert(Size % 8 == 0);
// Extend the element to take zero padding into account.
- APInt Value = CI->getValue().zextOrSelf(Size);
+ APInt Value = CI->getValue().zext(Size);
if (!Value.isSplat(8))
return -1;
@@ -2768,8 +2935,8 @@ static void emitGlobalConstantDataSequential(const DataLayout &DL,
if (isa<IntegerType>(CDS->getElementType())) {
for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
if (AP.isVerbose())
- AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n",
- CDS->getElementAsInteger(i));
+ AP.OutStreamer->getCommentOS()
+ << format("0x%" PRIx64 "\n", CDS->getElementAsInteger(i));
AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(i),
ElementByteSize);
}
@@ -2855,8 +3022,8 @@ static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) {
if (AP.isVerbose()) {
SmallString<8> StrVal;
APF.toString(StrVal);
- ET->print(AP.OutStreamer->GetCommentOS());
- AP.OutStreamer->GetCommentOS() << ' ' << StrVal << '\n';
+ ET->print(AP.OutStreamer->getCommentOS());
+ AP.OutStreamer->getCommentOS() << ' ' << StrVal << '\n';
}
// Now iterate through the APInt chunks, emitting them in endian-correct
@@ -3061,8 +3228,8 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,
if (StoreSize <= 8) {
if (AP.isVerbose())
- AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n",
- CI->getZExtValue());
+ AP.OutStreamer->getCommentOS()
+ << format("0x%" PRIx64 "\n", CI->getZExtValue());
AP.OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize);
} else {
emitGlobalConstantLargeInt(CI, AP);
@@ -3163,11 +3330,12 @@ MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const {
}
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
- return MMI->getAddrLabelSymbol(BA->getBasicBlock());
+ return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(
+ BA->getBasicBlock());
}
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {
- return MMI->getAddrLabelSymbol(BB);
+ return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB);
}
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
@@ -3272,7 +3440,7 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
// Otherwise, it is a loop header. Print out information about child and
// parent loops.
- raw_ostream &OS = AP.OutStreamer->GetCommentOS();
+ raw_ostream &OS = AP.OutStreamer->getCommentOS();
PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());
@@ -3308,7 +3476,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
// entry block is always placed in the function section and is handled
// separately.
if (MBB.isBeginSection() && !MBB.isEntryBlock()) {
- OutStreamer->SwitchSection(
+ OutStreamer->switchSection(
getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),
MBB, TM));
CurrentSectionBeginSym = MBB.getSymbol();
@@ -3326,7 +3494,7 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
// MBBs can have their address taken as part of CodeGen without having
// their corresponding BB's address taken in IR
if (BB && BB->hasAddressTaken())
- for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB))
+ for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))
OutStreamer->emitLabel(Sym);
}
@@ -3334,9 +3502,9 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {
if (isVerbose()) {
if (BB) {
if (BB->hasName()) {
- BB->printAsOperand(OutStreamer->GetCommentOS(),
+ BB->printAsOperand(OutStreamer->getCommentOS(),
/*PrintType=*/false, BB->getModule());
- OutStreamer->GetCommentOS() << '\n';
+ OutStreamer->getCommentOS() << '\n';
}
}
@@ -3563,7 +3731,7 @@ void AsmPrinter::emitXRayTable() {
// range of sleds associated with a function.
auto &Ctx = OutContext;
MCSymbol *SledsStart = OutContext.createTempSymbol("xray_sleds_start", true);
- OutStreamer->SwitchSection(InstMap);
+ OutStreamer->switchSection(InstMap);
OutStreamer->emitLabel(SledsStart);
for (const auto &Sled : Sleds) {
MCSymbol *Dot = Ctx.createTempSymbol();
@@ -3590,11 +3758,11 @@ void AsmPrinter::emitXRayTable() {
// Each entry here will be 2 * word size aligned, as we're writing down two
// pointers. This should work for both 32-bit and 64-bit platforms.
if (FnSledIndex) {
- OutStreamer->SwitchSection(FnSledIndex);
+ OutStreamer->switchSection(FnSledIndex);
OutStreamer->emitCodeAlignment(2 * WordSizeBytes, &getSubtargetInfo());
OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes, false);
OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes, false);
- OutStreamer->SwitchSection(PrevSection);
+ OutStreamer->switchSection(PrevSection);
}
Sleds.clear();
}
@@ -3639,7 +3807,7 @@ void AsmPrinter::emitPatchableFunctionEntries() {
}
LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);
}
- OutStreamer->SwitchSection(OutContext.getELFSection(
+ OutStreamer->switchSection(OutContext.getELFSection(
"__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName,
F.hasComdat(), MCSection::NonUniqueID, LinkedToSym));
emitAlignment(Align(PointerSize));