diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 129 |
1 files changed, 75 insertions, 54 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index e528d33b5f8c..cc848d28a9a7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -71,7 +71,6 @@ #include "llvm/IR/GCStrategy.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalIFunc.h" -#include "llvm/IR/GlobalIndirectSymbol.h" #include "llvm/IR/GlobalObject.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" @@ -102,6 +101,7 @@ #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" @@ -115,7 +115,6 @@ #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -275,7 +274,7 @@ bool AsmPrinter::doInitialization(Module &M) { const_cast<TargetLoweringObjectFile &>(getObjFileLowering()) .getModuleMetadata(M); - OutStreamer->InitSections(false); + OutStreamer->initSections(false, *TM.getMCSubtargetInfo()); if (DisableDebugInfoPrinting) MMI->setDebugInfoAvailability(false); @@ -326,16 +325,10 @@ bool AsmPrinter::doInitialization(Module &M) { // Emit module-level inline asm if it exists. if (!M.getModuleInlineAsm().empty()) { - // We're at the module level. Construct MCSubtarget from the default CPU - // and target triple. - std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo( - TM.getTargetTriple().str(), TM.getTargetCPU(), - TM.getTargetFeatureString())); - assert(STI && "Unable to create subtarget info"); OutStreamer->AddComment("Start of file scope inline assembly"); OutStreamer->AddBlankLine(); - emitInlineAsm(M.getModuleInlineAsm() + "\n", - OutContext.getSubtargetCopy(*STI), TM.Options.MCOptions); + emitInlineAsm(M.getModuleInlineAsm() + "\n", *TM.getMCSubtargetInfo(), + TM.Options.MCOptions); OutStreamer->AddComment("End of file scope inline assembly"); OutStreamer->AddBlankLine(); } @@ -1422,7 +1415,7 @@ void AsmPrinter::emitFunctionBody() { }); R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n"; for (auto &KV : MnemonicVec) { - auto Name = (Twine("INST_") + KV.first.trim()).str(); + auto Name = (Twine("INST_") + getToken(KV.first.trim()).first).str(); R << KV.first << ": " << ore::NV(Name, KV.second) << "\n"; } ORE->emit(R); @@ -1610,14 +1603,13 @@ void AsmPrinter::emitGlobalGOTEquivs() { emitGlobalVariable(GV); } -void AsmPrinter::emitGlobalIndirectSymbol(Module &M, - const GlobalIndirectSymbol& GIS) { - MCSymbol *Name = getSymbol(&GIS); - bool IsFunction = GIS.getValueType()->isFunctionTy(); +void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) { + MCSymbol *Name = getSymbol(&GA); + bool IsFunction = GA.getValueType()->isFunctionTy(); // 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>(GIS.getIndirectSymbol())) + if (auto *CE = dyn_cast<ConstantExpr>(GA.getAliasee())) if (CE->getOpcode() == Instruction::BitCast) IsFunction = CE->getOperand(0)->getType()->getPointerElementType()->isFunctionTy(); @@ -1627,61 +1619,80 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M, // point, all the extra label is emitted, we just have to emit linkage for // those labels. if (TM.getTargetTriple().isOSBinFormatXCOFF()) { - assert(!isa<GlobalIFunc>(GIS) && "IFunc is not supported on AIX."); assert(MAI->hasVisibilityOnlyWithLinkage() && "Visibility should be handled with emitLinkage() on AIX."); - emitLinkage(&GIS, Name); + emitLinkage(&GA, Name); // If it's a function, also emit linkage for aliases of function entry // point. if (IsFunction) - emitLinkage(&GIS, - getObjFileLowering().getFunctionEntryPointSymbol(&GIS, TM)); + emitLinkage(&GA, + getObjFileLowering().getFunctionEntryPointSymbol(&GA, TM)); return; } - if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective()) + if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective()) OutStreamer->emitSymbolAttribute(Name, MCSA_Global); - else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage()) + else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage()) OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference); else - assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage"); + assert(GA.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 (IsFunction) - OutStreamer->emitSymbolAttribute(Name, isa<GlobalIFunc>(GIS) - ? MCSA_ELF_TypeIndFunction - : MCSA_ELF_TypeFunction); + OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction); - emitVisibility(Name, GIS.getVisibility()); + emitVisibility(Name, GA.getVisibility()); - const MCExpr *Expr = lowerConstant(GIS.getIndirectSymbol()); + const MCExpr *Expr = lowerConstant(GA.getAliasee()); - if (isa<GlobalAlias>(&GIS) && MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr)) + if (MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr)) OutStreamer->emitSymbolAttribute(Name, MCSA_AltEntry); // Emit the directives as assignments aka .set: OutStreamer->emitAssignment(Name, Expr); - MCSymbol *LocalAlias = getSymbolPreferLocal(GIS); + MCSymbol *LocalAlias = getSymbolPreferLocal(GA); if (LocalAlias != Name) OutStreamer->emitAssignment(LocalAlias, 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(Name, MCConstantExpr::create(Size, OutContext)); - } + // 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.getAliaseeObject(); + if (MAI->hasDotTypeDotSizeDirective() && GA.getValueType()->isSized() && + (!BaseObject || BaseObject->hasPrivateLinkage())) { + const DataLayout &DL = M.getDataLayout(); + uint64_t Size = DL.getTypeAllocSize(GA.getValueType()); + OutStreamer->emitELFSize(Name, MCConstantExpr::create(Size, OutContext)); } } +void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) { + assert(!TM.getTargetTriple().isOSBinFormatXCOFF() && + "IFunc is not supported on AIX."); + + MCSymbol *Name = getSymbol(&GI); + + if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) + OutStreamer->emitSymbolAttribute(Name, MCSA_Global); + else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) + OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference); + else + assert(GI.hasLocalLinkage() && "Invalid ifunc linkage"); + + OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction); + emitVisibility(Name, GI.getVisibility()); + + // Emit the directives as assignments aka .set: + const MCExpr *Expr = lowerConstant(GI.getResolver()); + OutStreamer->emitAssignment(Name, Expr); + MCSymbol *LocalAlias = getSymbolPreferLocal(GI); + if (LocalAlias != Name) + OutStreamer->emitAssignment(LocalAlias, Expr); +} + void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) { if (!RS.needsSection()) return; @@ -1815,6 +1826,11 @@ bool AsmPrinter::doFinalization(Module &M) { } } + // This needs to happen before emitting debug information since that can end + // arbitrary sections. + if (auto *TS = OutStreamer->getTargetStreamer()) + TS->emitConstantPools(); + // Finalize debug and EH information. for (const HandlerInfo &HI : Handlers) { NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, @@ -1857,11 +1873,11 @@ bool AsmPrinter::doFinalization(Module &M) { AliasStack.push_back(Cur); } for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) - emitGlobalIndirectSymbol(M, *AncestorAlias); + emitGlobalAlias(M, *AncestorAlias); AliasStack.clear(); } for (const auto &IFunc : M.ifuncs()) - emitGlobalIndirectSymbol(M, IFunc); + emitGlobalIFunc(M, IFunc); GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); assert(MI && "AsmPrinter didn't require GCModuleInfo?"); @@ -2455,9 +2471,14 @@ void AsmPrinter::emitAlignment(Align Alignment, const GlobalObject *GV) const { if (Alignment == Align(1)) return; // 1-byte aligned: no need to emit alignment. - if (getCurrentSection()->getKind().isText()) - OutStreamer->emitCodeAlignment(Alignment.value()); - else + if (getCurrentSection()->getKind().isText()) { + const MCSubtargetInfo *STI = nullptr; + if (this->MF) + STI = &getSubtargetInfo(); + else + STI = TM.getMCSubtargetInfo(); + OutStreamer->emitCodeAlignment(Alignment.value(), STI); + } else OutStreamer->emitValueToAlignment(Alignment.value()); } @@ -2513,7 +2534,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { OS << "Unsupported expression in static initializer: "; CE->printAsOperand(OS, /*PrintType=*/false, !MF ? nullptr : MF->getFunction().getParent()); - report_fatal_error(OS.str()); + report_fatal_error(Twine(OS.str())); } case Instruction::GetElementPtr: { // Generate a symbolic expression for the byte address @@ -3265,21 +3286,21 @@ void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) { // reference the block. It is possible that there is more than one label // here, because multiple LLVM BB's may have been RAUW'd to this block after // the references were generated. + const BasicBlock *BB = MBB.getBasicBlock(); if (MBB.hasAddressTaken()) { - const BasicBlock *BB = MBB.getBasicBlock(); if (isVerbose()) OutStreamer->AddComment("Block address taken"); // MBBs can have their address taken as part of CodeGen without having // their corresponding BB's address taken in IR - if (BB->hasAddressTaken()) + if (BB && BB->hasAddressTaken()) for (MCSymbol *Sym : MMI->getAddrLabelSymbolToEmit(BB)) OutStreamer->emitLabel(Sym); } // Print some verbose block comments. if (isVerbose()) { - if (const BasicBlock *BB = MBB.getBasicBlock()) { + if (BB) { if (BB->hasName()) { BB->printAsOperand(OutStreamer->GetCommentOS(), /*PrintType=*/false, BB->getModule()); @@ -3538,7 +3559,7 @@ void AsmPrinter::emitXRayTable() { // pointers. This should work for both 32-bit and 64-bit platforms. if (FnSledIndex) { OutStreamer->SwitchSection(FnSledIndex); - OutStreamer->emitCodeAlignment(2 * WordSizeBytes); + OutStreamer->emitCodeAlignment(2 * WordSizeBytes, &getSubtargetInfo()); OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes, false); OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes, false); OutStreamer->SwitchSection(PrevSection); |
