10b57cec5SDimitry Andric //===- AsmPrinter.cpp - Common AsmPrinter code ----------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the AsmPrinter class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 140b57cec5SDimitry Andric #include "CodeViewDebug.h" 150b57cec5SDimitry Andric #include "DwarfDebug.h" 160b57cec5SDimitry Andric #include "DwarfException.h" 17e8d8bef9SDimitry Andric #include "PseudoProbePrinter.h" 180b57cec5SDimitry Andric #include "WasmException.h" 190b57cec5SDimitry Andric #include "WinCFGuard.h" 200b57cec5SDimitry Andric #include "WinException.h" 210b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h" 220b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 230b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 240b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 250b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 260b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 270b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 280b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 2906c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 300b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 3181ad6265SDimitry Andric #include "llvm/ADT/TinyPtrVector.h" 320b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 330b57cec5SDimitry Andric #include "llvm/Analysis/ConstantFolding.h" 34e8d8bef9SDimitry Andric #include "llvm/Analysis/MemoryLocation.h" 350b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h" 360b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 370b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 380b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 390b57cec5SDimitry Andric #include "llvm/CodeGen/GCMetadata.h" 400b57cec5SDimitry Andric #include "llvm/CodeGen/GCMetadataPrinter.h" 4106c3fb27SDimitry Andric #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" 420b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 431db9f3b2SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 440b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h" 450b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 460b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 470b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 480b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 490b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 500b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h" 510b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h" 520b57cec5SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h" 530b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 540b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 550b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 560b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" 570b57cec5SDimitry Andric #include "llvm/CodeGen/StackMaps.h" 580b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 590b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 600b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 610b57cec5SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h" 620b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 635f757f3fSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 64fe6060f1SDimitry Andric #include "llvm/Config/config.h" 650b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 660b57cec5SDimitry Andric #include "llvm/IR/Comdat.h" 670b57cec5SDimitry Andric #include "llvm/IR/Constant.h" 680b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 690b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 700b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 710b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 7206c3fb27SDimitry Andric #include "llvm/IR/EHPersonalities.h" 730b57cec5SDimitry Andric #include "llvm/IR/Function.h" 74fe6060f1SDimitry Andric #include "llvm/IR/GCStrategy.h" 750b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h" 760b57cec5SDimitry Andric #include "llvm/IR/GlobalIFunc.h" 770b57cec5SDimitry Andric #include "llvm/IR/GlobalObject.h" 780b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 790b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 800b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 810b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 820b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 830b57cec5SDimitry Andric #include "llvm/IR/Module.h" 840b57cec5SDimitry Andric #include "llvm/IR/Operator.h" 85e8d8bef9SDimitry Andric #include "llvm/IR/PseudoProbe.h" 860b57cec5SDimitry Andric #include "llvm/IR/Type.h" 870b57cec5SDimitry Andric #include "llvm/IR/Value.h" 8881ad6265SDimitry Andric #include "llvm/IR/ValueHandle.h" 890b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 900b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 910b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h" 920b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 930b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 940b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 950b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 960b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 970b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 985f757f3fSDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 990b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 1000b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 1010b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 1020b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 1030b57cec5SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 1040b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 1050b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 10606c3fb27SDimitry Andric #include "llvm/Object/ELFTypes.h" 1070b57cec5SDimitry Andric #include "llvm/Pass.h" 1085ffd83dbSDimitry Andric #include "llvm/Remarks/RemarkStreamer.h" 1090b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 1100b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 1110b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 112fe6060f1SDimitry Andric #include "llvm/Support/FileSystem.h" 1130b57cec5SDimitry Andric #include "llvm/Support/Format.h" 1140b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 1150b57cec5SDimitry Andric #include "llvm/Support/Path.h" 116*0fca6ea1SDimitry Andric #include "llvm/Support/VCSRevision.h" 1170b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 1180b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h" 1190b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 1200b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 12106c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 1220b57cec5SDimitry Andric #include <algorithm> 1230b57cec5SDimitry Andric #include <cassert> 1240b57cec5SDimitry Andric #include <cinttypes> 1250b57cec5SDimitry Andric #include <cstdint> 1260b57cec5SDimitry Andric #include <iterator> 1270b57cec5SDimitry Andric #include <memory> 128bdd1243dSDimitry Andric #include <optional> 1290b57cec5SDimitry Andric #include <string> 1300b57cec5SDimitry Andric #include <utility> 1310b57cec5SDimitry Andric #include <vector> 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric using namespace llvm; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric #define DEBUG_TYPE "asm-printer" 1360b57cec5SDimitry Andric 1371db9f3b2SDimitry Andric // This is a replication of fields of object::PGOAnalysisMap::Features. It 1381db9f3b2SDimitry Andric // should match the order of the fields so that 1391db9f3b2SDimitry Andric // `object::PGOAnalysisMap::Features::decode(PgoAnalysisMapFeatures.getBits())` 1401db9f3b2SDimitry Andric // succeeds. 1411db9f3b2SDimitry Andric enum class PGOMapFeaturesEnum { 1421db9f3b2SDimitry Andric FuncEntryCount, 1431db9f3b2SDimitry Andric BBFreq, 1441db9f3b2SDimitry Andric BrProb, 1451db9f3b2SDimitry Andric }; 1461db9f3b2SDimitry Andric static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures( 1471db9f3b2SDimitry Andric "pgo-analysis-map", cl::Hidden, cl::CommaSeparated, 1481db9f3b2SDimitry Andric cl::values(clEnumValN(PGOMapFeaturesEnum::FuncEntryCount, 1491db9f3b2SDimitry Andric "func-entry-count", "Function Entry Count"), 1501db9f3b2SDimitry Andric clEnumValN(PGOMapFeaturesEnum::BBFreq, "bb-freq", 1511db9f3b2SDimitry Andric "Basic Block Frequency"), 1521db9f3b2SDimitry Andric clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob", 1531db9f3b2SDimitry Andric "Branch Probability")), 154*0fca6ea1SDimitry Andric cl::desc( 155*0fca6ea1SDimitry Andric "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is " 1561db9f3b2SDimitry Andric "extracted from PGO related analysis.")); 1571db9f3b2SDimitry Andric 1580b57cec5SDimitry Andric STATISTIC(EmittedInsts, "Number of machine instrs printed"); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric char AsmPrinter::ID = 0; 1610b57cec5SDimitry Andric 16281ad6265SDimitry Andric namespace { 16381ad6265SDimitry Andric class AddrLabelMapCallbackPtr final : CallbackVH { 16481ad6265SDimitry Andric AddrLabelMap *Map = nullptr; 16581ad6265SDimitry Andric 16681ad6265SDimitry Andric public: 16781ad6265SDimitry Andric AddrLabelMapCallbackPtr() = default; 16881ad6265SDimitry Andric AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} 16981ad6265SDimitry Andric 17081ad6265SDimitry Andric void setPtr(BasicBlock *BB) { 17181ad6265SDimitry Andric ValueHandleBase::operator=(BB); 17281ad6265SDimitry Andric } 17381ad6265SDimitry Andric 17481ad6265SDimitry Andric void setMap(AddrLabelMap *map) { Map = map; } 17581ad6265SDimitry Andric 17681ad6265SDimitry Andric void deleted() override; 17781ad6265SDimitry Andric void allUsesReplacedWith(Value *V2) override; 17881ad6265SDimitry Andric }; 17981ad6265SDimitry Andric } // namespace 18081ad6265SDimitry Andric 18181ad6265SDimitry Andric class llvm::AddrLabelMap { 18281ad6265SDimitry Andric MCContext &Context; 18381ad6265SDimitry Andric struct AddrLabelSymEntry { 18481ad6265SDimitry Andric /// The symbols for the label. 18581ad6265SDimitry Andric TinyPtrVector<MCSymbol *> Symbols; 18681ad6265SDimitry Andric 18781ad6265SDimitry Andric Function *Fn; // The containing function of the BasicBlock. 18881ad6265SDimitry Andric unsigned Index; // The index in BBCallbacks for the BasicBlock. 18981ad6265SDimitry Andric }; 19081ad6265SDimitry Andric 19181ad6265SDimitry Andric DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; 19281ad6265SDimitry Andric 19381ad6265SDimitry Andric /// Callbacks for the BasicBlock's that we have entries for. We use this so 19481ad6265SDimitry Andric /// we get notified if a block is deleted or RAUWd. 19581ad6265SDimitry Andric std::vector<AddrLabelMapCallbackPtr> BBCallbacks; 19681ad6265SDimitry Andric 19781ad6265SDimitry Andric /// This is a per-function list of symbols whose corresponding BasicBlock got 19881ad6265SDimitry Andric /// deleted. These symbols need to be emitted at some point in the file, so 19981ad6265SDimitry Andric /// AsmPrinter emits them after the function body. 20081ad6265SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>> 20181ad6265SDimitry Andric DeletedAddrLabelsNeedingEmission; 20281ad6265SDimitry Andric 20381ad6265SDimitry Andric public: 20481ad6265SDimitry Andric AddrLabelMap(MCContext &context) : Context(context) {} 20581ad6265SDimitry Andric 20681ad6265SDimitry Andric ~AddrLabelMap() { 20781ad6265SDimitry Andric assert(DeletedAddrLabelsNeedingEmission.empty() && 20881ad6265SDimitry Andric "Some labels for deleted blocks never got emitted"); 20981ad6265SDimitry Andric } 21081ad6265SDimitry Andric 21181ad6265SDimitry Andric ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); 21281ad6265SDimitry Andric 21381ad6265SDimitry Andric void takeDeletedSymbolsForFunction(Function *F, 21481ad6265SDimitry Andric std::vector<MCSymbol *> &Result); 21581ad6265SDimitry Andric 21681ad6265SDimitry Andric void UpdateForDeletedBlock(BasicBlock *BB); 21781ad6265SDimitry Andric void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); 21881ad6265SDimitry Andric }; 21981ad6265SDimitry Andric 22081ad6265SDimitry Andric ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { 22181ad6265SDimitry Andric assert(BB->hasAddressTaken() && 22281ad6265SDimitry Andric "Shouldn't get label for block without address taken"); 22381ad6265SDimitry Andric AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; 22481ad6265SDimitry Andric 22581ad6265SDimitry Andric // If we already had an entry for this block, just return it. 22681ad6265SDimitry Andric if (!Entry.Symbols.empty()) { 22781ad6265SDimitry Andric assert(BB->getParent() == Entry.Fn && "Parent changed"); 22881ad6265SDimitry Andric return Entry.Symbols; 22981ad6265SDimitry Andric } 23081ad6265SDimitry Andric 23181ad6265SDimitry Andric // Otherwise, this is a new entry, create a new symbol for it and add an 23281ad6265SDimitry Andric // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. 23381ad6265SDimitry Andric BBCallbacks.emplace_back(BB); 23481ad6265SDimitry Andric BBCallbacks.back().setMap(this); 23581ad6265SDimitry Andric Entry.Index = BBCallbacks.size() - 1; 23681ad6265SDimitry Andric Entry.Fn = BB->getParent(); 23781ad6265SDimitry Andric MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() 23881ad6265SDimitry Andric : Context.createTempSymbol(); 23981ad6265SDimitry Andric Entry.Symbols.push_back(Sym); 24081ad6265SDimitry Andric return Entry.Symbols; 24181ad6265SDimitry Andric } 24281ad6265SDimitry Andric 24381ad6265SDimitry Andric /// If we have any deleted symbols for F, return them. 24481ad6265SDimitry Andric void AddrLabelMap::takeDeletedSymbolsForFunction( 24581ad6265SDimitry Andric Function *F, std::vector<MCSymbol *> &Result) { 24681ad6265SDimitry Andric DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I = 24781ad6265SDimitry Andric DeletedAddrLabelsNeedingEmission.find(F); 24881ad6265SDimitry Andric 24981ad6265SDimitry Andric // If there are no entries for the function, just return. 25081ad6265SDimitry Andric if (I == DeletedAddrLabelsNeedingEmission.end()) 25181ad6265SDimitry Andric return; 25281ad6265SDimitry Andric 25381ad6265SDimitry Andric // Otherwise, take the list. 25481ad6265SDimitry Andric std::swap(Result, I->second); 25581ad6265SDimitry Andric DeletedAddrLabelsNeedingEmission.erase(I); 25681ad6265SDimitry Andric } 25781ad6265SDimitry Andric 25881ad6265SDimitry Andric //===- Address of Block Management ----------------------------------------===// 25981ad6265SDimitry Andric 26081ad6265SDimitry Andric ArrayRef<MCSymbol *> 26181ad6265SDimitry Andric AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) { 26281ad6265SDimitry Andric // Lazily create AddrLabelSymbols. 26381ad6265SDimitry Andric if (!AddrLabelSymbols) 26481ad6265SDimitry Andric AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext); 26581ad6265SDimitry Andric return AddrLabelSymbols->getAddrLabelSymbolToEmit( 26681ad6265SDimitry Andric const_cast<BasicBlock *>(BB)); 26781ad6265SDimitry Andric } 26881ad6265SDimitry Andric 26981ad6265SDimitry Andric void AsmPrinter::takeDeletedSymbolsForFunction( 27081ad6265SDimitry Andric const Function *F, std::vector<MCSymbol *> &Result) { 27181ad6265SDimitry Andric // If no blocks have had their addresses taken, we're done. 27281ad6265SDimitry Andric if (!AddrLabelSymbols) 27381ad6265SDimitry Andric return; 27481ad6265SDimitry Andric return AddrLabelSymbols->takeDeletedSymbolsForFunction( 27581ad6265SDimitry Andric const_cast<Function *>(F), Result); 27681ad6265SDimitry Andric } 27781ad6265SDimitry Andric 27881ad6265SDimitry Andric void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { 27981ad6265SDimitry Andric // If the block got deleted, there is no need for the symbol. If the symbol 28081ad6265SDimitry Andric // was already emitted, we can just forget about it, otherwise we need to 28181ad6265SDimitry Andric // queue it up for later emission when the function is output. 28281ad6265SDimitry Andric AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); 28381ad6265SDimitry Andric AddrLabelSymbols.erase(BB); 28481ad6265SDimitry Andric assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 28581ad6265SDimitry Andric BBCallbacks[Entry.Index] = nullptr; // Clear the callback. 28681ad6265SDimitry Andric 28781ad6265SDimitry Andric #if !LLVM_MEMORY_SANITIZER_BUILD 28881ad6265SDimitry Andric // BasicBlock is destroyed already, so this access is UB detectable by msan. 28981ad6265SDimitry Andric assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && 29081ad6265SDimitry Andric "Block/parent mismatch"); 29181ad6265SDimitry Andric #endif 29281ad6265SDimitry Andric 29381ad6265SDimitry Andric for (MCSymbol *Sym : Entry.Symbols) { 29481ad6265SDimitry Andric if (Sym->isDefined()) 29581ad6265SDimitry Andric return; 29681ad6265SDimitry Andric 29781ad6265SDimitry Andric // If the block is not yet defined, we need to emit it at the end of the 29881ad6265SDimitry Andric // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list 29981ad6265SDimitry Andric // for the containing Function. Since the block is being deleted, its 30081ad6265SDimitry Andric // parent may already be removed, we have to get the function from 'Entry'. 30181ad6265SDimitry Andric DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym); 30281ad6265SDimitry Andric } 30381ad6265SDimitry Andric } 30481ad6265SDimitry Andric 30581ad6265SDimitry Andric void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { 30681ad6265SDimitry Andric // Get the entry for the RAUW'd block and remove it from our map. 30781ad6265SDimitry Andric AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); 30881ad6265SDimitry Andric AddrLabelSymbols.erase(Old); 30981ad6265SDimitry Andric assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?"); 31081ad6265SDimitry Andric 31181ad6265SDimitry Andric AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; 31281ad6265SDimitry Andric 31381ad6265SDimitry Andric // If New is not address taken, just move our symbol over to it. 31481ad6265SDimitry Andric if (NewEntry.Symbols.empty()) { 31581ad6265SDimitry Andric BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. 31681ad6265SDimitry Andric NewEntry = std::move(OldEntry); // Set New's entry. 31781ad6265SDimitry Andric return; 31881ad6265SDimitry Andric } 31981ad6265SDimitry Andric 32081ad6265SDimitry Andric BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. 32181ad6265SDimitry Andric 32281ad6265SDimitry Andric // Otherwise, we need to add the old symbols to the new block's set. 32381ad6265SDimitry Andric llvm::append_range(NewEntry.Symbols, OldEntry.Symbols); 32481ad6265SDimitry Andric } 32581ad6265SDimitry Andric 32681ad6265SDimitry Andric void AddrLabelMapCallbackPtr::deleted() { 32781ad6265SDimitry Andric Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr())); 32881ad6265SDimitry Andric } 32981ad6265SDimitry Andric 33081ad6265SDimitry Andric void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { 33181ad6265SDimitry Andric Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2)); 33281ad6265SDimitry Andric } 33381ad6265SDimitry Andric 3348bcb0991SDimitry Andric /// getGVAlignment - Return the alignment to use for the specified global 3358bcb0991SDimitry Andric /// value. This rounds up to the preferred alignment if possible and legal. 3365ffd83dbSDimitry Andric Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL, 3378bcb0991SDimitry Andric Align InAlign) { 3388bcb0991SDimitry Andric Align Alignment; 3390b57cec5SDimitry Andric if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 3405ffd83dbSDimitry Andric Alignment = DL.getPreferredAlign(GVar); 3410b57cec5SDimitry Andric 3428bcb0991SDimitry Andric // If InAlign is specified, round it to it. 3438bcb0991SDimitry Andric if (InAlign > Alignment) 3448bcb0991SDimitry Andric Alignment = InAlign; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric // If the GV has a specified alignment, take it into account. 3470eae32dcSDimitry Andric const MaybeAlign GVAlign(GV->getAlign()); 3488bcb0991SDimitry Andric if (!GVAlign) 3498bcb0991SDimitry Andric return Alignment; 3500b57cec5SDimitry Andric 3518bcb0991SDimitry Andric assert(GVAlign && "GVAlign must be set"); 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric // If the GVAlign is larger than NumBits, or if we are required to obey 3540b57cec5SDimitry Andric // NumBits because the GV has an assigned section, obey it. 3558bcb0991SDimitry Andric if (*GVAlign > Alignment || GV->hasSection()) 3568bcb0991SDimitry Andric Alignment = *GVAlign; 3578bcb0991SDimitry Andric return Alignment; 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer) 3610b57cec5SDimitry Andric : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()), 362bdd1243dSDimitry Andric OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)), 363bdd1243dSDimitry Andric SM(*this) { 3640b57cec5SDimitry Andric VerboseAsm = OutStreamer->isVerboseAsm(); 365bdd1243dSDimitry Andric DwarfUsesRelocationsAcrossSections = 366bdd1243dSDimitry Andric MAI->doesDwarfUseRelocationsAcrossSections(); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric AsmPrinter::~AsmPrinter() { 370e8d8bef9SDimitry Andric assert(!DD && Handlers.size() == NumUserHandlers && 371e8d8bef9SDimitry Andric "Debug/EH info didn't get finalized"); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric bool AsmPrinter::isPositionIndependent() const { 3750b57cec5SDimitry Andric return TM.isPositionIndependent(); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric /// getFunctionNumber - Return a unique ID for the current function. 3790b57cec5SDimitry Andric unsigned AsmPrinter::getFunctionNumber() const { 3800b57cec5SDimitry Andric return MF->getFunctionNumber(); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { 3840b57cec5SDimitry Andric return *TM.getObjFileLowering(); 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric const DataLayout &AsmPrinter::getDataLayout() const { 3885f757f3fSDimitry Andric assert(MMI && "MMI could not be nullptr!"); 3890b57cec5SDimitry Andric return MMI->getModule()->getDataLayout(); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric // Do not use the cached DataLayout because some client use it without a Module 3930b57cec5SDimitry Andric // (dsymutil, llvm-dwarfdump). 3940b57cec5SDimitry Andric unsigned AsmPrinter::getPointerSize() const { 3950b57cec5SDimitry Andric return TM.getPointerSize(0); // FIXME: Default address space 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const { 3990b57cec5SDimitry Andric assert(MF && "getSubtargetInfo requires a valid MachineFunction!"); 4000b57cec5SDimitry Andric return MF->getSubtarget<MCSubtargetInfo>(); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { 4045ffd83dbSDimitry Andric S.emitInstruction(Inst, getSubtargetInfo()); 4050b57cec5SDimitry Andric } 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) { 408e8d8bef9SDimitry Andric if (DD) { 409e8d8bef9SDimitry Andric assert(OutStreamer->hasRawTextSupport() && 410e8d8bef9SDimitry Andric "Expected assembly output mode."); 41104eeddc0SDimitry Andric // This is NVPTX specific and it's unclear why. 41204eeddc0SDimitry Andric // PR51079: If we have code without debug information we need to give up. 41304eeddc0SDimitry Andric DISubprogram *MFSP = MF.getFunction().getSubprogram(); 41404eeddc0SDimitry Andric if (!MFSP) 41504eeddc0SDimitry Andric return; 4160b57cec5SDimitry Andric (void)DD->emitInitialLocDirective(MF, /*CUID=*/0); 4170b57cec5SDimitry Andric } 418e8d8bef9SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric /// getCurrentSection() - Return the current section we are emitting to. 4210b57cec5SDimitry Andric const MCSection *AsmPrinter::getCurrentSection() const { 4220b57cec5SDimitry Andric return OutStreamer->getCurrentSectionOnly(); 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { 4260b57cec5SDimitry Andric AU.setPreservesAll(); 4270b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 4280b57cec5SDimitry Andric AU.addRequired<MachineOptimizationRemarkEmitterPass>(); 4290b57cec5SDimitry Andric AU.addRequired<GCModuleInfo>(); 43006c3fb27SDimitry Andric AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); 431*0fca6ea1SDimitry Andric AU.addRequired<MachineBranchProbabilityInfoWrapperPass>(); 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric bool AsmPrinter::doInitialization(Module &M) { 4358bcb0991SDimitry Andric auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>(); 4368bcb0991SDimitry Andric MMI = MMIWP ? &MMIWP->getMMI() : nullptr; 43781ad6265SDimitry Andric HasSplitStack = false; 43881ad6265SDimitry Andric HasNoSplitStack = false; 43981ad6265SDimitry Andric 44081ad6265SDimitry Andric AddrLabelSymbols = nullptr; 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric // Initialize TargetLoweringObjectFile. 4430b57cec5SDimitry Andric const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 4440b57cec5SDimitry Andric .Initialize(OutContext, TM); 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric const_cast<TargetLoweringObjectFile &>(getObjFileLowering()) 4470b57cec5SDimitry Andric .getModuleMetadata(M); 4480b57cec5SDimitry Andric 4495f757f3fSDimitry Andric // On AIX, we delay emitting any section information until 4505f757f3fSDimitry Andric // after emitting the .file pseudo-op. This allows additional 4515f757f3fSDimitry Andric // information (such as the embedded command line) to be associated 4525f757f3fSDimitry Andric // with all sections in the object file rather than a single section. 4535f757f3fSDimitry Andric if (!TM.getTargetTriple().isOSBinFormatXCOFF()) 454349cc55cSDimitry Andric OutStreamer->initSections(false, *TM.getMCSubtargetInfo()); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric // Emit the version-min deployment target directive if needed. 4570b57cec5SDimitry Andric // 4580b57cec5SDimitry Andric // FIXME: If we end up with a collection of these sorts of Darwin-specific 4590b57cec5SDimitry Andric // or ELF-specific things, it may make sense to have a platform helper class 4600b57cec5SDimitry Andric // that will work with the target helper class. For now keep it here, as the 4610b57cec5SDimitry Andric // alternative is duplicated code in each of the target asm printers that 4620b57cec5SDimitry Andric // use the directive, where it would need the same conditionalization 4630b57cec5SDimitry Andric // anyway. 4640b57cec5SDimitry Andric const Triple &Target = TM.getTargetTriple(); 465*0fca6ea1SDimitry Andric if (Target.isOSBinFormatMachO() && Target.isOSDarwin()) { 4660eae32dcSDimitry Andric Triple TVT(M.getDarwinTargetVariantTriple()); 4670eae32dcSDimitry Andric OutStreamer->emitVersionForTarget( 4680eae32dcSDimitry Andric Target, M.getSDKVersion(), 4690eae32dcSDimitry Andric M.getDarwinTargetVariantTriple().empty() ? nullptr : &TVT, 4700eae32dcSDimitry Andric M.getDarwinTargetVariantSDKVersion()); 471*0fca6ea1SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric // Allow the target to emit any magic that it wants at the start of the file. 4745ffd83dbSDimitry Andric emitStartOfAsmFile(M); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // Very minimal debug info. It is ignored if we emit actual debug info. If we 4770b57cec5SDimitry Andric // don't, this at least helps the user find where a global came from. 4780b57cec5SDimitry Andric if (MAI->hasSingleParameterDotFile()) { 4790b57cec5SDimitry Andric // .file "foo.c" 480fe6060f1SDimitry Andric 481fe6060f1SDimitry Andric SmallString<128> FileName; 482fe6060f1SDimitry Andric if (MAI->hasBasenameOnlyForFileDirective()) 483fe6060f1SDimitry Andric FileName = llvm::sys::path::filename(M.getSourceFileName()); 484fe6060f1SDimitry Andric else 485fe6060f1SDimitry Andric FileName = M.getSourceFileName(); 486fe6060f1SDimitry Andric if (MAI->hasFourStringsDotFile()) { 487fe6060f1SDimitry Andric const char VerStr[] = 488*0fca6ea1SDimitry Andric #ifdef PACKAGE_VENDOR 489*0fca6ea1SDimitry Andric PACKAGE_VENDOR " " 490fe6060f1SDimitry Andric #endif 491*0fca6ea1SDimitry Andric PACKAGE_NAME " version " PACKAGE_VERSION 492*0fca6ea1SDimitry Andric #ifdef LLVM_REVISION 493*0fca6ea1SDimitry Andric " (" LLVM_REVISION ")" 494*0fca6ea1SDimitry Andric #endif 495*0fca6ea1SDimitry Andric ; 496fe6060f1SDimitry Andric // TODO: Add timestamp and description. 497fe6060f1SDimitry Andric OutStreamer->emitFileDirective(FileName, VerStr, "", ""); 498fe6060f1SDimitry Andric } else { 499fe6060f1SDimitry Andric OutStreamer->emitFileDirective(FileName); 500fe6060f1SDimitry Andric } 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 50306c3fb27SDimitry Andric // On AIX, emit bytes for llvm.commandline metadata after .file so that the 50406c3fb27SDimitry Andric // C_INFO symbol is preserved if any csect is kept by the linker. 5055f757f3fSDimitry Andric if (TM.getTargetTriple().isOSBinFormatXCOFF()) { 50606c3fb27SDimitry Andric emitModuleCommandLines(M); 5075f757f3fSDimitry Andric // Now we can generate section information. 5085f757f3fSDimitry Andric OutStreamer->initSections(false, *TM.getMCSubtargetInfo()); 5095f757f3fSDimitry Andric 5105f757f3fSDimitry Andric // To work around an AIX assembler and/or linker bug, generate 5115f757f3fSDimitry Andric // a rename for the default text-section symbol name. This call has 5125f757f3fSDimitry Andric // no effect when generating object code directly. 5135f757f3fSDimitry Andric MCSection *TextSection = 5145f757f3fSDimitry Andric OutStreamer->getContext().getObjectFileInfo()->getTextSection(); 5155f757f3fSDimitry Andric MCSymbolXCOFF *XSym = 5165f757f3fSDimitry Andric static_cast<MCSectionXCOFF *>(TextSection)->getQualNameSymbol(); 5175f757f3fSDimitry Andric if (XSym->hasRename()) 5185f757f3fSDimitry Andric OutStreamer->emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName()); 5195f757f3fSDimitry Andric } 52006c3fb27SDimitry Andric 5210b57cec5SDimitry Andric GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 5220b57cec5SDimitry Andric assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 523fcaf7f86SDimitry Andric for (const auto &I : *MI) 524bdd1243dSDimitry Andric if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I)) 5250b57cec5SDimitry Andric MP->beginAssembly(M, *MI, *this); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric // Emit module-level inline asm if it exists. 5280b57cec5SDimitry Andric if (!M.getModuleInlineAsm().empty()) { 5290b57cec5SDimitry Andric OutStreamer->AddComment("Start of file scope inline assembly"); 53081ad6265SDimitry Andric OutStreamer->addBlankLine(); 531*0fca6ea1SDimitry Andric emitInlineAsm( 532*0fca6ea1SDimitry Andric M.getModuleInlineAsm() + "\n", *TM.getMCSubtargetInfo(), 533*0fca6ea1SDimitry Andric TM.Options.MCOptions, nullptr, 534*0fca6ea1SDimitry Andric InlineAsm::AsmDialect(TM.getMCAsmInfo()->getAssemblerDialect())); 5350b57cec5SDimitry Andric OutStreamer->AddComment("End of file scope inline assembly"); 53681ad6265SDimitry Andric OutStreamer->addBlankLine(); 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric if (MAI->doesSupportDebugInformation()) { 5405ffd83dbSDimitry Andric bool EmitCodeView = M.getCodeViewFlag(); 541*0fca6ea1SDimitry Andric if (EmitCodeView && TM.getTargetTriple().isOSWindows()) 542*0fca6ea1SDimitry Andric DebugHandlers.push_back(std::make_unique<CodeViewDebug>(this)); 5435ffd83dbSDimitry Andric if (!EmitCodeView || M.getDwarfVersion()) { 5445f757f3fSDimitry Andric assert(MMI && "MMI could not be nullptr here!"); 54581ad6265SDimitry Andric if (MMI->hasDebugInfo()) { 546e8d8bef9SDimitry Andric DD = new DwarfDebug(this); 547*0fca6ea1SDimitry Andric DebugHandlers.push_back(std::unique_ptr<DwarfDebug>(DD)); 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric } 550e8d8bef9SDimitry Andric } 551e8d8bef9SDimitry Andric 552*0fca6ea1SDimitry Andric if (M.getNamedMetadata(PseudoProbeDescMetadataName)) 553*0fca6ea1SDimitry Andric PP = std::make_unique<PseudoProbeHandler>(this); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric switch (MAI->getExceptionHandlingType()) { 556fe6060f1SDimitry Andric case ExceptionHandling::None: 557fe6060f1SDimitry Andric // We may want to emit CFI for debug. 558bdd1243dSDimitry Andric [[fallthrough]]; 5590b57cec5SDimitry Andric case ExceptionHandling::SjLj: 5600b57cec5SDimitry Andric case ExceptionHandling::DwarfCFI: 5610b57cec5SDimitry Andric case ExceptionHandling::ARM: 5620b57cec5SDimitry Andric for (auto &F : M.getFunctionList()) { 563fe6060f1SDimitry Andric if (getFunctionCFISectionType(F) != CFISection::None) 564fe6060f1SDimitry Andric ModuleCFISection = getFunctionCFISectionType(F); 565fe6060f1SDimitry Andric // If any function needsUnwindTableEntry(), it needs .eh_frame and hence 566fe6060f1SDimitry Andric // the module needs .eh_frame. If we have found that case, we are done. 567fe6060f1SDimitry Andric if (ModuleCFISection == CFISection::EH) 5680b57cec5SDimitry Andric break; 5690b57cec5SDimitry Andric } 570fe6060f1SDimitry Andric assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI || 57106c3fb27SDimitry Andric usesCFIWithoutEH() || ModuleCFISection != CFISection::EH); 5720b57cec5SDimitry Andric break; 5730b57cec5SDimitry Andric default: 5740b57cec5SDimitry Andric break; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric EHStreamer *ES = nullptr; 5780b57cec5SDimitry Andric switch (MAI->getExceptionHandlingType()) { 5790b57cec5SDimitry Andric case ExceptionHandling::None: 58006c3fb27SDimitry Andric if (!usesCFIWithoutEH()) 5810b57cec5SDimitry Andric break; 582bdd1243dSDimitry Andric [[fallthrough]]; 5830b57cec5SDimitry Andric case ExceptionHandling::SjLj: 5840b57cec5SDimitry Andric case ExceptionHandling::DwarfCFI: 585cb14a3feSDimitry Andric case ExceptionHandling::ZOS: 5860b57cec5SDimitry Andric ES = new DwarfCFIException(this); 5870b57cec5SDimitry Andric break; 5880b57cec5SDimitry Andric case ExceptionHandling::ARM: 5890b57cec5SDimitry Andric ES = new ARMException(this); 5900b57cec5SDimitry Andric break; 5910b57cec5SDimitry Andric case ExceptionHandling::WinEH: 5920b57cec5SDimitry Andric switch (MAI->getWinEHEncodingType()) { 5930b57cec5SDimitry Andric default: llvm_unreachable("unsupported unwinding information encoding"); 5940b57cec5SDimitry Andric case WinEH::EncodingType::Invalid: 5950b57cec5SDimitry Andric break; 5960b57cec5SDimitry Andric case WinEH::EncodingType::X86: 5970b57cec5SDimitry Andric case WinEH::EncodingType::Itanium: 5980b57cec5SDimitry Andric ES = new WinException(this); 5990b57cec5SDimitry Andric break; 6000b57cec5SDimitry Andric } 6010b57cec5SDimitry Andric break; 6020b57cec5SDimitry Andric case ExceptionHandling::Wasm: 6030b57cec5SDimitry Andric ES = new WasmException(this); 6040b57cec5SDimitry Andric break; 605e8d8bef9SDimitry Andric case ExceptionHandling::AIX: 606e8d8bef9SDimitry Andric ES = new AIXException(this); 607e8d8bef9SDimitry Andric break; 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric if (ES) 610*0fca6ea1SDimitry Andric Handlers.push_back(std::unique_ptr<EHStreamer>(ES)); 6110b57cec5SDimitry Andric 612480093f4SDimitry Andric // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2). 6135ffd83dbSDimitry Andric if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard"))) 614*0fca6ea1SDimitry Andric Handlers.push_back(std::make_unique<WinCFGuard>(this)); 615e8d8bef9SDimitry Andric 616*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 617*0fca6ea1SDimitry Andric Handler->beginModule(&M); 618*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 619*0fca6ea1SDimitry Andric Handler->beginModule(&M); 620e8d8bef9SDimitry Andric 6210b57cec5SDimitry Andric return false; 6220b57cec5SDimitry Andric } 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI) { 6250b57cec5SDimitry Andric if (!MAI.hasWeakDefCanBeHiddenDirective()) 6260b57cec5SDimitry Andric return false; 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric return GV->canBeOmittedFromSymbolTable(); 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6315ffd83dbSDimitry Andric void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { 6320b57cec5SDimitry Andric GlobalValue::LinkageTypes Linkage = GV->getLinkage(); 6330b57cec5SDimitry Andric switch (Linkage) { 6340b57cec5SDimitry Andric case GlobalValue::CommonLinkage: 6350b57cec5SDimitry Andric case GlobalValue::LinkOnceAnyLinkage: 6360b57cec5SDimitry Andric case GlobalValue::LinkOnceODRLinkage: 6370b57cec5SDimitry Andric case GlobalValue::WeakAnyLinkage: 6380b57cec5SDimitry Andric case GlobalValue::WeakODRLinkage: 6390b57cec5SDimitry Andric if (MAI->hasWeakDefDirective()) { 6400b57cec5SDimitry Andric // .globl _foo 6415ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global); 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric if (!canBeHidden(GV, *MAI)) 6440b57cec5SDimitry Andric // .weak_definition _foo 6455ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefinition); 6460b57cec5SDimitry Andric else 6475ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate); 6485ffd83dbSDimitry Andric } else if (MAI->avoidWeakIfComdat() && GV->hasComdat()) { 6490b57cec5SDimitry Andric // .globl _foo 6505ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global); 6510b57cec5SDimitry Andric //NOTE: linkonce is handled by the section the symbol was assigned to. 6520b57cec5SDimitry Andric } else { 6530b57cec5SDimitry Andric // .weak _foo 6545ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_Weak); 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric return; 6570b57cec5SDimitry Andric case GlobalValue::ExternalLinkage: 6585ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global); 6590b57cec5SDimitry Andric return; 6600b57cec5SDimitry Andric case GlobalValue::PrivateLinkage: 6610b57cec5SDimitry Andric case GlobalValue::InternalLinkage: 6620b57cec5SDimitry Andric return; 6630b57cec5SDimitry Andric case GlobalValue::ExternalWeakLinkage: 6645ffd83dbSDimitry Andric case GlobalValue::AvailableExternallyLinkage: 6655ffd83dbSDimitry Andric case GlobalValue::AppendingLinkage: 6660b57cec5SDimitry Andric llvm_unreachable("Should never emit this"); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric llvm_unreachable("Unknown linkage type!"); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric void AsmPrinter::getNameWithPrefix(SmallVectorImpl<char> &Name, 6720b57cec5SDimitry Andric const GlobalValue *GV) const { 6730b57cec5SDimitry Andric TM.getNameWithPrefix(Name, GV, getObjFileLowering().getMangler()); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const { 6770b57cec5SDimitry Andric return TM.getSymbol(GV); 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric 6805ffd83dbSDimitry Andric MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const { 6815ffd83dbSDimitry Andric // On ELF, use .Lfoo$local if GV is a non-interposable GlobalObject with an 6825ffd83dbSDimitry Andric // exact definion (intersection of GlobalValue::hasExactDefinition() and 6835ffd83dbSDimitry Andric // !isInterposable()). These linkages include: external, appending, internal, 6845ffd83dbSDimitry Andric // private. It may be profitable to use a local alias for external. The 6855ffd83dbSDimitry Andric // assembler would otherwise be conservative and assume a global default 6865ffd83dbSDimitry Andric // visibility symbol can be interposable, even if the code generator already 6875ffd83dbSDimitry Andric // assumed it. 6885ffd83dbSDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) { 6895ffd83dbSDimitry Andric const Module &M = *GV.getParent(); 6905ffd83dbSDimitry Andric if (TM.getRelocationModel() != Reloc::Static && 691e8d8bef9SDimitry Andric M.getPIELevel() == PIELevel::Default && GV.isDSOLocal()) 6925ffd83dbSDimitry Andric return getSymbolWithGlobalValueBase(&GV, "$local"); 6935ffd83dbSDimitry Andric } 6945ffd83dbSDimitry Andric return TM.getSymbol(&GV); 6955ffd83dbSDimitry Andric } 6965ffd83dbSDimitry Andric 6970b57cec5SDimitry Andric /// EmitGlobalVariable - Emit the specified global variable to the .s file. 6985ffd83dbSDimitry Andric void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { 6990b57cec5SDimitry Andric bool IsEmuTLSVar = TM.useEmulatedTLS() && GV->isThreadLocal(); 7000b57cec5SDimitry Andric assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) && 7010b57cec5SDimitry Andric "No emulated TLS variables in the common section"); 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric // Never emit TLS variable xyz in emulated TLS model. 7040b57cec5SDimitry Andric // The initialization value is in __emutls_t.xyz instead of xyz. 7050b57cec5SDimitry Andric if (IsEmuTLSVar) 7060b57cec5SDimitry Andric return; 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric if (GV->hasInitializer()) { 7090b57cec5SDimitry Andric // Check to see if this is a special global used by LLVM, if so, emit it. 7105ffd83dbSDimitry Andric if (emitSpecialLLVMGlobal(GV)) 7110b57cec5SDimitry Andric return; 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric // Skip the emission of global equivalents. The symbol can be emitted later 7140b57cec5SDimitry Andric // on by emitGlobalGOTEquivs in case it turns out to be needed. 7150b57cec5SDimitry Andric if (GlobalGOTEquivs.count(getSymbol(GV))) 7160b57cec5SDimitry Andric return; 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric if (isVerbose()) { 7190b57cec5SDimitry Andric // When printing the control variable __emutls_v.*, 7200b57cec5SDimitry Andric // we don't need to print the original TLS variable name. 72181ad6265SDimitry Andric GV->printAsOperand(OutStreamer->getCommentOS(), 7220b57cec5SDimitry Andric /*PrintType=*/false, GV->getParent()); 72381ad6265SDimitry Andric OutStreamer->getCommentOS() << '\n'; 7240b57cec5SDimitry Andric } 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric MCSymbol *GVSym = getSymbol(GV); 7280b57cec5SDimitry Andric MCSymbol *EmittedSym = GVSym; 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric // getOrCreateEmuTLSControlSym only creates the symbol with name and default 7310b57cec5SDimitry Andric // attributes. 7320b57cec5SDimitry Andric // GV's or GVSym's attributes will be used for the EmittedSym. 7335ffd83dbSDimitry Andric emitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration()); 7340b57cec5SDimitry Andric 735bdd1243dSDimitry Andric if (GV->isTagged()) { 736bdd1243dSDimitry Andric Triple T = TM.getTargetTriple(); 737bdd1243dSDimitry Andric 738bdd1243dSDimitry Andric if (T.getArch() != Triple::aarch64 || !T.isAndroid()) 739bdd1243dSDimitry Andric OutContext.reportError(SMLoc(), 74006c3fb27SDimitry Andric "tagged symbols (-fsanitize=memtag-globals) are " 74106c3fb27SDimitry Andric "only supported on AArch64 Android"); 742bdd1243dSDimitry Andric OutStreamer->emitSymbolAttribute(EmittedSym, MAI->getMemtagAttr()); 743bdd1243dSDimitry Andric } 744bdd1243dSDimitry Andric 7450b57cec5SDimitry Andric if (!GV->hasInitializer()) // External globals require no extra code. 7460b57cec5SDimitry Andric return; 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric GVSym->redefineIfPossible(); 7490b57cec5SDimitry Andric if (GVSym->isDefined() || GVSym->isVariable()) 750e8d8bef9SDimitry Andric OutContext.reportError(SMLoc(), "symbol '" + Twine(GVSym->getName()) + 7510b57cec5SDimitry Andric "' is already defined"); 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric if (MAI->hasDotTypeDotSizeDirective()) 7545ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject); 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); 7570b57cec5SDimitry Andric 758*0fca6ea1SDimitry Andric const DataLayout &DL = GV->getDataLayout(); 7590b57cec5SDimitry Andric uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric // If the alignment is specified, we *must* obey it. Overaligning a global 7620b57cec5SDimitry Andric // with a specified alignment is a prompt way to break globals emitted to 7630b57cec5SDimitry Andric // sections and expected to be contiguous (e.g. ObjC metadata). 7648bcb0991SDimitry Andric const Align Alignment = getGVAlignment(GV, DL); 7650b57cec5SDimitry Andric 766*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 767*0fca6ea1SDimitry Andric Handler->setSymbolSize(GVSym, Size); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric // Handle common symbols 7700b57cec5SDimitry Andric if (GVKind.isCommon()) { 7710b57cec5SDimitry Andric if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. 7720b57cec5SDimitry Andric // .comm _foo, 42, 4 773bdd1243dSDimitry Andric OutStreamer->emitCommonSymbol(GVSym, Size, Alignment); 7740b57cec5SDimitry Andric return; 7750b57cec5SDimitry Andric } 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric // Determine to which section this global should be emitted. 7780b57cec5SDimitry Andric MCSection *TheSection = getObjFileLowering().SectionForGlobal(GV, GVKind, TM); 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric // If we have a bss global going to a section that supports the 7810b57cec5SDimitry Andric // zerofill directive, do so here. 7820b57cec5SDimitry Andric if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective() && 7830b57cec5SDimitry Andric TheSection->isVirtualSection()) { 7840b57cec5SDimitry Andric if (Size == 0) 7850b57cec5SDimitry Andric Size = 1; // zerofill of 0 bytes is undefined. 7865ffd83dbSDimitry Andric emitLinkage(GV, GVSym); 7870b57cec5SDimitry Andric // .zerofill __DATA, __bss, _foo, 400, 5 788bdd1243dSDimitry Andric OutStreamer->emitZerofill(TheSection, GVSym, Size, Alignment); 7890b57cec5SDimitry Andric return; 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric // If this is a BSS local symbol and we are emitting in the BSS 7930b57cec5SDimitry Andric // section use .lcomm/.comm directive. 7940b57cec5SDimitry Andric if (GVKind.isBSSLocal() && 7950b57cec5SDimitry Andric getObjFileLowering().getBSSSection() == TheSection) { 7960b57cec5SDimitry Andric if (Size == 0) 7970b57cec5SDimitry Andric Size = 1; // .comm Foo, 0 is undefined, avoid it. 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric // Use .lcomm only if it supports user-specified alignment. 8000b57cec5SDimitry Andric // Otherwise, while it would still be correct to use .lcomm in some 8010b57cec5SDimitry Andric // cases (e.g. when Align == 1), the external assembler might enfore 8020b57cec5SDimitry Andric // some -unknown- default alignment behavior, which could cause 8030b57cec5SDimitry Andric // spurious differences between external and integrated assembler. 8040b57cec5SDimitry Andric // Prefer to simply fall back to .local / .comm in this case. 8050b57cec5SDimitry Andric if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) { 8060b57cec5SDimitry Andric // .lcomm _foo, 42 807bdd1243dSDimitry Andric OutStreamer->emitLocalCommonSymbol(GVSym, Size, Alignment); 8080b57cec5SDimitry Andric return; 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric // .local _foo 8125ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(GVSym, MCSA_Local); 8130b57cec5SDimitry Andric // .comm _foo, 42, 4 814bdd1243dSDimitry Andric OutStreamer->emitCommonSymbol(GVSym, Size, Alignment); 8150b57cec5SDimitry Andric return; 8160b57cec5SDimitry Andric } 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric // Handle thread local data for mach-o which requires us to output an 8190b57cec5SDimitry Andric // additional structure of data and mangle the original symbol so that we 8200b57cec5SDimitry Andric // can reference it later. 8210b57cec5SDimitry Andric // 8220b57cec5SDimitry Andric // TODO: This should become an "emit thread local global" method on TLOF. 8230b57cec5SDimitry Andric // All of this macho specific stuff should be sunk down into TLOFMachO and 8240b57cec5SDimitry Andric // stuff like "TLSExtraDataSection" should no longer be part of the parent 8250b57cec5SDimitry Andric // TLOF class. This will also make it more obvious that stuff like 8260b57cec5SDimitry Andric // MCStreamer::EmitTBSSSymbol is macho specific and only called from macho 8270b57cec5SDimitry Andric // specific code. 8280b57cec5SDimitry Andric if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { 8290b57cec5SDimitry Andric // Emit the .tbss symbol 8300b57cec5SDimitry Andric MCSymbol *MangSym = 8310b57cec5SDimitry Andric OutContext.getOrCreateSymbol(GVSym->getName() + Twine("$tlv$init")); 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric if (GVKind.isThreadBSS()) { 8340b57cec5SDimitry Andric TheSection = getObjFileLowering().getTLSBSSSection(); 835bdd1243dSDimitry Andric OutStreamer->emitTBSSSymbol(TheSection, MangSym, Size, Alignment); 8360b57cec5SDimitry Andric } else if (GVKind.isThreadData()) { 83781ad6265SDimitry Andric OutStreamer->switchSection(TheSection); 8380b57cec5SDimitry Andric 8395ffd83dbSDimitry Andric emitAlignment(Alignment, GV); 8405ffd83dbSDimitry Andric OutStreamer->emitLabel(MangSym); 8410b57cec5SDimitry Andric 842*0fca6ea1SDimitry Andric emitGlobalConstant(GV->getDataLayout(), 8430b57cec5SDimitry Andric GV->getInitializer()); 8440b57cec5SDimitry Andric } 8450b57cec5SDimitry Andric 84681ad6265SDimitry Andric OutStreamer->addBlankLine(); 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric // Emit the variable struct for the runtime. 8490b57cec5SDimitry Andric MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection(); 8500b57cec5SDimitry Andric 85181ad6265SDimitry Andric OutStreamer->switchSection(TLVSect); 8520b57cec5SDimitry Andric // Emit the linkage here. 8535ffd83dbSDimitry Andric emitLinkage(GV, GVSym); 8545ffd83dbSDimitry Andric OutStreamer->emitLabel(GVSym); 8550b57cec5SDimitry Andric 8560b57cec5SDimitry Andric // Three pointers in size: 8570b57cec5SDimitry Andric // - __tlv_bootstrap - used to make sure support exists 8580b57cec5SDimitry Andric // - spare pointer, used when mapped by the runtime 8590b57cec5SDimitry Andric // - pointer to mangled symbol above with initializer 8600b57cec5SDimitry Andric unsigned PtrSize = DL.getPointerTypeSize(GV->getType()); 8615ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"), 8620b57cec5SDimitry Andric PtrSize); 8635ffd83dbSDimitry Andric OutStreamer->emitIntValue(0, PtrSize); 8645ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(MangSym, PtrSize); 8650b57cec5SDimitry Andric 86681ad6265SDimitry Andric OutStreamer->addBlankLine(); 8670b57cec5SDimitry Andric return; 8680b57cec5SDimitry Andric } 8690b57cec5SDimitry Andric 8700b57cec5SDimitry Andric MCSymbol *EmittedInitSym = GVSym; 8710b57cec5SDimitry Andric 87281ad6265SDimitry Andric OutStreamer->switchSection(TheSection); 8730b57cec5SDimitry Andric 8745ffd83dbSDimitry Andric emitLinkage(GV, EmittedInitSym); 8755ffd83dbSDimitry Andric emitAlignment(Alignment, GV); 8760b57cec5SDimitry Andric 8775ffd83dbSDimitry Andric OutStreamer->emitLabel(EmittedInitSym); 8785ffd83dbSDimitry Andric MCSymbol *LocalAlias = getSymbolPreferLocal(*GV); 8795ffd83dbSDimitry Andric if (LocalAlias != EmittedInitSym) 8805ffd83dbSDimitry Andric OutStreamer->emitLabel(LocalAlias); 8810b57cec5SDimitry Andric 882*0fca6ea1SDimitry Andric emitGlobalConstant(GV->getDataLayout(), GV->getInitializer()); 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric if (MAI->hasDotTypeDotSizeDirective()) 8850b57cec5SDimitry Andric // .size foo, 42 8860b57cec5SDimitry Andric OutStreamer->emitELFSize(EmittedInitSym, 8870b57cec5SDimitry Andric MCConstantExpr::create(Size, OutContext)); 8880b57cec5SDimitry Andric 88981ad6265SDimitry Andric OutStreamer->addBlankLine(); 8900b57cec5SDimitry Andric } 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric /// Emit the directive and value for debug thread local expression 8930b57cec5SDimitry Andric /// 8940b57cec5SDimitry Andric /// \p Value - The value to emit. 8950b57cec5SDimitry Andric /// \p Size - The size of the integer (in bytes) to emit. 8965ffd83dbSDimitry Andric void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const { 8975ffd83dbSDimitry Andric OutStreamer->emitValue(Value, Size); 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 9005ffd83dbSDimitry Andric void AsmPrinter::emitFunctionHeaderComment() {} 9015ffd83dbSDimitry Andric 902*0fca6ea1SDimitry Andric void AsmPrinter::emitFunctionPrefix(ArrayRef<const Constant *> Prefix) { 903*0fca6ea1SDimitry Andric const Function &F = MF->getFunction(); 904*0fca6ea1SDimitry Andric if (!MAI->hasSubsectionsViaSymbols()) { 905*0fca6ea1SDimitry Andric for (auto &C : Prefix) 906*0fca6ea1SDimitry Andric emitGlobalConstant(F.getDataLayout(), C); 907*0fca6ea1SDimitry Andric return; 908*0fca6ea1SDimitry Andric } 909*0fca6ea1SDimitry Andric // Preserving prefix-like data on platforms which use subsections-via-symbols 910*0fca6ea1SDimitry Andric // is a bit tricky. Here we introduce a symbol for the prefix-like data 911*0fca6ea1SDimitry Andric // and use the .alt_entry attribute to mark the function's real entry point 912*0fca6ea1SDimitry Andric // as an alternative entry point to the symbol that precedes the function.. 913*0fca6ea1SDimitry Andric OutStreamer->emitLabel(OutContext.createLinkerPrivateTempSymbol()); 914*0fca6ea1SDimitry Andric 915*0fca6ea1SDimitry Andric for (auto &C : Prefix) { 916*0fca6ea1SDimitry Andric emitGlobalConstant(F.getDataLayout(), C); 917*0fca6ea1SDimitry Andric } 918*0fca6ea1SDimitry Andric 919*0fca6ea1SDimitry Andric // Emit an .alt_entry directive for the actual function symbol. 920*0fca6ea1SDimitry Andric OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry); 921*0fca6ea1SDimitry Andric } 922*0fca6ea1SDimitry Andric 9230b57cec5SDimitry Andric /// EmitFunctionHeader - This method emits the header for the current 9240b57cec5SDimitry Andric /// function. 9255ffd83dbSDimitry Andric void AsmPrinter::emitFunctionHeader() { 9260b57cec5SDimitry Andric const Function &F = MF->getFunction(); 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric if (isVerbose()) 92981ad6265SDimitry Andric OutStreamer->getCommentOS() 9300b57cec5SDimitry Andric << "-- Begin function " 9310b57cec5SDimitry Andric << GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n'; 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric // Print out constants referenced by the function 9345ffd83dbSDimitry Andric emitConstantPool(); 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andric // Print the 'header' of function. 937fe6060f1SDimitry Andric // If basic block sections are desired, explicitly request a unique section 938fe6060f1SDimitry Andric // for this function's entry block. 939fe6060f1SDimitry Andric if (MF->front().isBeginSection()) 940fe6060f1SDimitry Andric MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM)); 941fe6060f1SDimitry Andric else 9425ffd83dbSDimitry Andric MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM)); 94381ad6265SDimitry Andric OutStreamer->switchSection(MF->getSection()); 9440b57cec5SDimitry Andric 9455ffd83dbSDimitry Andric if (!MAI->hasVisibilityOnlyWithLinkage()) 9465ffd83dbSDimitry Andric emitVisibility(CurrentFnSym, F.getVisibility()); 9478bcb0991SDimitry Andric 9485ffd83dbSDimitry Andric if (MAI->needsFunctionDescriptors()) 9495ffd83dbSDimitry Andric emitLinkage(&F, CurrentFnDescSym); 9505ffd83dbSDimitry Andric 9515ffd83dbSDimitry Andric emitLinkage(&F, CurrentFnSym); 9520b57cec5SDimitry Andric if (MAI->hasFunctionAlignment()) 9535ffd83dbSDimitry Andric emitAlignment(MF->getAlignment(), &F); 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric if (MAI->hasDotTypeDotSizeDirective()) 9565ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric if (F.hasFnAttribute(Attribute::Cold)) 9595ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold); 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric // Emit the prefix data. 962*0fca6ea1SDimitry Andric if (F.hasPrefixData()) 963*0fca6ea1SDimitry Andric emitFunctionPrefix({F.getPrefixData()}); 9640b57cec5SDimitry Andric 965bdd1243dSDimitry Andric // Emit KCFI type information before patchable-function-prefix nops. 966bdd1243dSDimitry Andric emitKCFITypeId(*MF); 967bdd1243dSDimitry Andric 96855e4f9d5SDimitry Andric // Emit M NOPs for -fpatchable-function-entry=N,M where M>0. We arbitrarily 96955e4f9d5SDimitry Andric // place prefix data before NOPs. 97055e4f9d5SDimitry Andric unsigned PatchableFunctionPrefix = 0; 97113138422SDimitry Andric unsigned PatchableFunctionEntry = 0; 97255e4f9d5SDimitry Andric (void)F.getFnAttribute("patchable-function-prefix") 97355e4f9d5SDimitry Andric .getValueAsString() 97455e4f9d5SDimitry Andric .getAsInteger(10, PatchableFunctionPrefix); 97513138422SDimitry Andric (void)F.getFnAttribute("patchable-function-entry") 97613138422SDimitry Andric .getValueAsString() 97713138422SDimitry Andric .getAsInteger(10, PatchableFunctionEntry); 97855e4f9d5SDimitry Andric if (PatchableFunctionPrefix) { 97955e4f9d5SDimitry Andric CurrentPatchableFunctionEntrySym = 98055e4f9d5SDimitry Andric OutContext.createLinkerPrivateTempSymbol(); 9815ffd83dbSDimitry Andric OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym); 98255e4f9d5SDimitry Andric emitNops(PatchableFunctionPrefix); 98313138422SDimitry Andric } else if (PatchableFunctionEntry) { 98413138422SDimitry Andric // May be reassigned when emitting the body, to reference the label after 98513138422SDimitry Andric // the initial BTI (AArch64) or endbr32/endbr64 (x86). 98655e4f9d5SDimitry Andric CurrentPatchableFunctionEntrySym = CurrentFnBegin; 98755e4f9d5SDimitry Andric } 98855e4f9d5SDimitry Andric 98906c3fb27SDimitry Andric // Emit the function prologue data for the indirect call sanitizer. 99006c3fb27SDimitry Andric if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) { 99106c3fb27SDimitry Andric assert(MD->getNumOperands() == 2); 99206c3fb27SDimitry Andric 99306c3fb27SDimitry Andric auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0)); 99406c3fb27SDimitry Andric auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1)); 995*0fca6ea1SDimitry Andric emitFunctionPrefix({PrologueSig, TypeHash}); 99606c3fb27SDimitry Andric } 99706c3fb27SDimitry Andric 99806c3fb27SDimitry Andric if (isVerbose()) { 99906c3fb27SDimitry Andric F.printAsOperand(OutStreamer->getCommentOS(), 100006c3fb27SDimitry Andric /*PrintType=*/false, F.getParent()); 100106c3fb27SDimitry Andric emitFunctionHeaderComment(); 100206c3fb27SDimitry Andric OutStreamer->getCommentOS() << '\n'; 100306c3fb27SDimitry Andric } 100406c3fb27SDimitry Andric 10058bcb0991SDimitry Andric // Emit the function descriptor. This is a virtual function to allow targets 10065ffd83dbSDimitry Andric // to emit their specific function descriptor. Right now it is only used by 10075ffd83dbSDimitry Andric // the AIX target. The PowerPC 64-bit V1 ELF target also uses function 10085ffd83dbSDimitry Andric // descriptors and should be converted to use this hook as well. 10098bcb0991SDimitry Andric if (MAI->needsFunctionDescriptors()) 10105ffd83dbSDimitry Andric emitFunctionDescriptor(); 10118bcb0991SDimitry Andric 10128bcb0991SDimitry Andric // Emit the CurrentFnSym. This is a virtual function to allow targets to do 10138bcb0991SDimitry Andric // their wild and crazy things as required. 10145ffd83dbSDimitry Andric emitFunctionEntryLabel(); 10150b57cec5SDimitry Andric 1016fe6060f1SDimitry Andric // If the function had address-taken blocks that got deleted, then we have 1017fe6060f1SDimitry Andric // references to the dangling symbols. Emit them at the start of the function 1018fe6060f1SDimitry Andric // so that we don't get references to undefined symbols. 1019fe6060f1SDimitry Andric std::vector<MCSymbol*> DeadBlockSyms; 102081ad6265SDimitry Andric takeDeletedSymbolsForFunction(&F, DeadBlockSyms); 10214824e7fdSDimitry Andric for (MCSymbol *DeadBlockSym : DeadBlockSyms) { 1022fe6060f1SDimitry Andric OutStreamer->AddComment("Address taken block that was later removed"); 10234824e7fdSDimitry Andric OutStreamer->emitLabel(DeadBlockSym); 1024fe6060f1SDimitry Andric } 1025fe6060f1SDimitry Andric 10260b57cec5SDimitry Andric if (CurrentFnBegin) { 10270b57cec5SDimitry Andric if (MAI->useAssignmentForEHBegin()) { 10280b57cec5SDimitry Andric MCSymbol *CurPos = OutContext.createTempSymbol(); 10295ffd83dbSDimitry Andric OutStreamer->emitLabel(CurPos); 10305ffd83dbSDimitry Andric OutStreamer->emitAssignment(CurrentFnBegin, 10310b57cec5SDimitry Andric MCSymbolRefExpr::create(CurPos, OutContext)); 10320b57cec5SDimitry Andric } else { 10335ffd83dbSDimitry Andric OutStreamer->emitLabel(CurrentFnBegin); 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric // Emit pre-function debug and/or EH information. 1038*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) { 1039*0fca6ea1SDimitry Andric Handler->beginFunction(MF); 1040*0fca6ea1SDimitry Andric Handler->beginBasicBlockSection(MF->front()); 10410b57cec5SDimitry Andric } 1042*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 1043*0fca6ea1SDimitry Andric Handler->beginFunction(MF); 1044*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 1045*0fca6ea1SDimitry Andric Handler->beginBasicBlockSection(MF->front()); 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric // Emit the prologue data. 10480b57cec5SDimitry Andric if (F.hasPrologueData()) 1049*0fca6ea1SDimitry Andric emitGlobalConstant(F.getDataLayout(), F.getPrologueData()); 10500b57cec5SDimitry Andric } 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric /// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the 10530b57cec5SDimitry Andric /// function. This can be overridden by targets as required to do custom stuff. 10545ffd83dbSDimitry Andric void AsmPrinter::emitFunctionEntryLabel() { 10550b57cec5SDimitry Andric CurrentFnSym->redefineIfPossible(); 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric // The function label could have already been emitted if two symbols end up 10580b57cec5SDimitry Andric // conflicting due to asm renaming. Detect this and emit an error. 10590b57cec5SDimitry Andric if (CurrentFnSym->isVariable()) 10600b57cec5SDimitry Andric report_fatal_error("'" + Twine(CurrentFnSym->getName()) + 10610b57cec5SDimitry Andric "' is a protected alias"); 10620b57cec5SDimitry Andric 10635ffd83dbSDimitry Andric OutStreamer->emitLabel(CurrentFnSym); 10645ffd83dbSDimitry Andric 10655ffd83dbSDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF()) { 10665ffd83dbSDimitry Andric MCSymbol *Sym = getSymbolPreferLocal(MF->getFunction()); 1067bdd1243dSDimitry Andric if (Sym != CurrentFnSym) { 1068bdd1243dSDimitry Andric cast<MCSymbolELF>(Sym)->setType(ELF::STT_FUNC); 1069bdd1243dSDimitry Andric CurrentFnBeginLocal = Sym; 10705ffd83dbSDimitry Andric OutStreamer->emitLabel(Sym); 1071bdd1243dSDimitry Andric if (MAI->hasDotTypeDotSizeDirective()) 1072bdd1243dSDimitry Andric OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction); 1073bdd1243dSDimitry Andric } 10745ffd83dbSDimitry Andric } 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric /// emitComments - Pretty-print comments for instructions. 10780b57cec5SDimitry Andric static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS) { 10790b57cec5SDimitry Andric const MachineFunction *MF = MI.getMF(); 10800b57cec5SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric // Check for spills and reloads 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric // We assume a single instruction only has a spill or reload, not 10850b57cec5SDimitry Andric // both. 1086*0fca6ea1SDimitry Andric std::optional<LocationSize> Size; 10870b57cec5SDimitry Andric if ((Size = MI.getRestoreSize(TII))) { 1088*0fca6ea1SDimitry Andric CommentOS << Size->getValue() << "-byte Reload\n"; 10890b57cec5SDimitry Andric } else if ((Size = MI.getFoldedRestoreSize(TII))) { 1090*0fca6ea1SDimitry Andric if (!Size->hasValue()) 1091e8d8bef9SDimitry Andric CommentOS << "Unknown-size Folded Reload\n"; 1092*0fca6ea1SDimitry Andric else if (Size->getValue()) 1093*0fca6ea1SDimitry Andric CommentOS << Size->getValue() << "-byte Folded Reload\n"; 10940b57cec5SDimitry Andric } else if ((Size = MI.getSpillSize(TII))) { 1095*0fca6ea1SDimitry Andric CommentOS << Size->getValue() << "-byte Spill\n"; 10960b57cec5SDimitry Andric } else if ((Size = MI.getFoldedSpillSize(TII))) { 1097*0fca6ea1SDimitry Andric if (!Size->hasValue()) 1098e8d8bef9SDimitry Andric CommentOS << "Unknown-size Folded Spill\n"; 1099*0fca6ea1SDimitry Andric else if (Size->getValue()) 1100*0fca6ea1SDimitry Andric CommentOS << Size->getValue() << "-byte Folded Spill\n"; 1101e8d8bef9SDimitry Andric } 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric // Check for spill-induced copies 11040b57cec5SDimitry Andric if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) 11050b57cec5SDimitry Andric CommentOS << " Reload Reuse\n"; 11060b57cec5SDimitry Andric } 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric /// emitImplicitDef - This method emits the specified machine instruction 11090b57cec5SDimitry Andric /// that is an implicit def. 11100b57cec5SDimitry Andric void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const { 11118bcb0991SDimitry Andric Register RegNo = MI->getOperand(0).getReg(); 11120b57cec5SDimitry Andric 11130b57cec5SDimitry Andric SmallString<128> Str; 11140b57cec5SDimitry Andric raw_svector_ostream OS(Str); 11150b57cec5SDimitry Andric OS << "implicit-def: " 11160b57cec5SDimitry Andric << printReg(RegNo, MF->getSubtarget().getRegisterInfo()); 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric OutStreamer->AddComment(OS.str()); 111981ad6265SDimitry Andric OutStreamer->addBlankLine(); 11200b57cec5SDimitry Andric } 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { 11230b57cec5SDimitry Andric std::string Str; 11240b57cec5SDimitry Andric raw_string_ostream OS(Str); 11250b57cec5SDimitry Andric OS << "kill:"; 11264824e7fdSDimitry Andric for (const MachineOperand &Op : MI->operands()) { 11270b57cec5SDimitry Andric assert(Op.isReg() && "KILL instruction must have only register operands"); 11280b57cec5SDimitry Andric OS << ' ' << (Op.isDef() ? "def " : "killed ") 11290b57cec5SDimitry Andric << printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo()); 11300b57cec5SDimitry Andric } 1131*0fca6ea1SDimitry Andric AP.OutStreamer->AddComment(Str); 113281ad6265SDimitry Andric AP.OutStreamer->addBlankLine(); 11330b57cec5SDimitry Andric } 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andric /// emitDebugValueComment - This method handles the target-independent form 11360b57cec5SDimitry Andric /// of DBG_VALUE, returning true if it was able to do so. A false return 11370b57cec5SDimitry Andric /// means the target will need to handle MI in EmitInstruction. 11380b57cec5SDimitry Andric static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { 11390b57cec5SDimitry Andric // This code handles only the 4-operand target-independent form. 1140fe6060f1SDimitry Andric if (MI->isNonListDebugValue() && MI->getNumOperands() != 4) 11410b57cec5SDimitry Andric return false; 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric SmallString<128> Str; 11440b57cec5SDimitry Andric raw_svector_ostream OS(Str); 11450b57cec5SDimitry Andric OS << "DEBUG_VALUE: "; 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric const DILocalVariable *V = MI->getDebugVariable(); 11480b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(V->getScope())) { 11490b57cec5SDimitry Andric StringRef Name = SP->getName(); 11500b57cec5SDimitry Andric if (!Name.empty()) 11510b57cec5SDimitry Andric OS << Name << ":"; 11520b57cec5SDimitry Andric } 11530b57cec5SDimitry Andric OS << V->getName(); 11540b57cec5SDimitry Andric OS << " <- "; 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric const DIExpression *Expr = MI->getDebugExpression(); 1157bdd1243dSDimitry Andric // First convert this to a non-variadic expression if possible, to simplify 1158bdd1243dSDimitry Andric // the output. 1159bdd1243dSDimitry Andric if (auto NonVariadicExpr = DIExpression::convertToNonVariadicExpression(Expr)) 1160bdd1243dSDimitry Andric Expr = *NonVariadicExpr; 1161bdd1243dSDimitry Andric // Then, output the possibly-simplified expression. 11620b57cec5SDimitry Andric if (Expr->getNumElements()) { 11630b57cec5SDimitry Andric OS << '['; 1164fe6060f1SDimitry Andric ListSeparator LS; 1165bdd1243dSDimitry Andric for (auto &Op : Expr->expr_ops()) { 1166fe6060f1SDimitry Andric OS << LS << dwarf::OperationEncodingString(Op.getOp()); 11670b57cec5SDimitry Andric for (unsigned I = 0; I < Op.getNumArgs(); ++I) 11680b57cec5SDimitry Andric OS << ' ' << Op.getArg(I); 11690b57cec5SDimitry Andric } 11700b57cec5SDimitry Andric OS << "] "; 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric // Register or immediate value. Register 0 means undef. 1174fe6060f1SDimitry Andric for (const MachineOperand &Op : MI->debug_operands()) { 1175fe6060f1SDimitry Andric if (&Op != MI->debug_operands().begin()) 1176fe6060f1SDimitry Andric OS << ", "; 1177fe6060f1SDimitry Andric switch (Op.getType()) { 1178fe6060f1SDimitry Andric case MachineOperand::MO_FPImmediate: { 1179fe6060f1SDimitry Andric APFloat APF = APFloat(Op.getFPImm()->getValueAPF()); 1180fe6060f1SDimitry Andric Type *ImmTy = Op.getFPImm()->getType(); 1181fe6060f1SDimitry Andric if (ImmTy->isBFloatTy() || ImmTy->isHalfTy() || ImmTy->isFloatTy() || 1182fe6060f1SDimitry Andric ImmTy->isDoubleTy()) { 11830b57cec5SDimitry Andric OS << APF.convertToDouble(); 11840b57cec5SDimitry Andric } else { 11850b57cec5SDimitry Andric // There is no good way to print long double. Convert a copy to 11860b57cec5SDimitry Andric // double. Ah well, it's only a comment. 11870b57cec5SDimitry Andric bool ignored; 11880b57cec5SDimitry Andric APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, 11890b57cec5SDimitry Andric &ignored); 11900b57cec5SDimitry Andric OS << "(long double) " << APF.convertToDouble(); 11910b57cec5SDimitry Andric } 1192fe6060f1SDimitry Andric break; 1193fe6060f1SDimitry Andric } 1194fe6060f1SDimitry Andric case MachineOperand::MO_Immediate: { 1195fe6060f1SDimitry Andric OS << Op.getImm(); 1196fe6060f1SDimitry Andric break; 1197fe6060f1SDimitry Andric } 1198fe6060f1SDimitry Andric case MachineOperand::MO_CImmediate: { 1199fe6060f1SDimitry Andric Op.getCImm()->getValue().print(OS, false /*isSigned*/); 1200fe6060f1SDimitry Andric break; 1201fe6060f1SDimitry Andric } 1202fe6060f1SDimitry Andric case MachineOperand::MO_TargetIndex: { 1203480093f4SDimitry Andric OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")"; 1204fe6060f1SDimitry Andric break; 12050b57cec5SDimitry Andric } 1206fe6060f1SDimitry Andric case MachineOperand::MO_Register: 1207fe6060f1SDimitry Andric case MachineOperand::MO_FrameIndex: { 1208fe6060f1SDimitry Andric Register Reg; 1209bdd1243dSDimitry Andric std::optional<StackOffset> Offset; 1210fe6060f1SDimitry Andric if (Op.isReg()) { 1211fe6060f1SDimitry Andric Reg = Op.getReg(); 1212fe6060f1SDimitry Andric } else { 1213fe6060f1SDimitry Andric const TargetFrameLowering *TFI = 1214fe6060f1SDimitry Andric AP.MF->getSubtarget().getFrameLowering(); 1215fe6060f1SDimitry Andric Offset = TFI->getFrameIndexReference(*AP.MF, Op.getIndex(), Reg); 1216fe6060f1SDimitry Andric } 1217fe6060f1SDimitry Andric if (!Reg) { 12180b57cec5SDimitry Andric // Suppress offset, it is not meaningful here. 12190b57cec5SDimitry Andric OS << "undef"; 1220fe6060f1SDimitry Andric break; 12210b57cec5SDimitry Andric } 1222fe6060f1SDimitry Andric // The second operand is only an offset if it's an immediate. 1223fe6060f1SDimitry Andric if (MI->isIndirectDebugValue()) 1224fe6060f1SDimitry Andric Offset = StackOffset::getFixed(MI->getDebugOffset().getImm()); 1225fe6060f1SDimitry Andric if (Offset) 12260b57cec5SDimitry Andric OS << '['; 12270b57cec5SDimitry Andric OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo()); 1228fe6060f1SDimitry Andric if (Offset) 1229fe6060f1SDimitry Andric OS << '+' << Offset->getFixed() << ']'; 1230fe6060f1SDimitry Andric break; 12310b57cec5SDimitry Andric } 1232fe6060f1SDimitry Andric default: 1233fe6060f1SDimitry Andric llvm_unreachable("Unknown operand type"); 1234fe6060f1SDimitry Andric } 1235fe6060f1SDimitry Andric } 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric // NOTE: Want this comment at start of line, don't emit with AddComment. 1238*0fca6ea1SDimitry Andric AP.OutStreamer->emitRawComment(Str); 12390b57cec5SDimitry Andric return true; 12400b57cec5SDimitry Andric } 12410b57cec5SDimitry Andric 12420b57cec5SDimitry Andric /// This method handles the target-independent form of DBG_LABEL, returning 12430b57cec5SDimitry Andric /// true if it was able to do so. A false return means the target will need 12440b57cec5SDimitry Andric /// to handle MI in EmitInstruction. 12450b57cec5SDimitry Andric static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP) { 12460b57cec5SDimitry Andric if (MI->getNumOperands() != 1) 12470b57cec5SDimitry Andric return false; 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric SmallString<128> Str; 12500b57cec5SDimitry Andric raw_svector_ostream OS(Str); 12510b57cec5SDimitry Andric OS << "DEBUG_LABEL: "; 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric const DILabel *V = MI->getDebugLabel(); 12548bcb0991SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>( 12558bcb0991SDimitry Andric V->getScope()->getNonLexicalBlockFileScope())) { 12560b57cec5SDimitry Andric StringRef Name = SP->getName(); 12570b57cec5SDimitry Andric if (!Name.empty()) 12580b57cec5SDimitry Andric OS << Name << ":"; 12590b57cec5SDimitry Andric } 12600b57cec5SDimitry Andric OS << V->getName(); 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric // NOTE: Want this comment at start of line, don't emit with AddComment. 12630b57cec5SDimitry Andric AP.OutStreamer->emitRawComment(OS.str()); 12640b57cec5SDimitry Andric return true; 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric 1267fe6060f1SDimitry Andric AsmPrinter::CFISection 1268fe6060f1SDimitry Andric AsmPrinter::getFunctionCFISectionType(const Function &F) const { 1269fe6060f1SDimitry Andric // Ignore functions that won't get emitted. 1270fe6060f1SDimitry Andric if (F.isDeclarationForLinker()) 1271fe6060f1SDimitry Andric return CFISection::None; 1272fe6060f1SDimitry Andric 12730b57cec5SDimitry Andric if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && 1274fe6060f1SDimitry Andric F.needsUnwindTableEntry()) 1275fe6060f1SDimitry Andric return CFISection::EH; 12760b57cec5SDimitry Andric 127706c3fb27SDimitry Andric if (MAI->usesCFIWithoutEH() && F.hasUWTable()) 127806c3fb27SDimitry Andric return CFISection::EH; 127906c3fb27SDimitry Andric 128006c3fb27SDimitry Andric assert(MMI != nullptr && "Invalid machine module info"); 1281fe6060f1SDimitry Andric if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection) 1282fe6060f1SDimitry Andric return CFISection::Debug; 12830b57cec5SDimitry Andric 1284fe6060f1SDimitry Andric return CFISection::None; 1285fe6060f1SDimitry Andric } 1286fe6060f1SDimitry Andric 1287fe6060f1SDimitry Andric AsmPrinter::CFISection 1288fe6060f1SDimitry Andric AsmPrinter::getFunctionCFISectionType(const MachineFunction &MF) const { 1289fe6060f1SDimitry Andric return getFunctionCFISectionType(MF.getFunction()); 12900b57cec5SDimitry Andric } 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric bool AsmPrinter::needsSEHMoves() { 12930b57cec5SDimitry Andric return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry(); 12940b57cec5SDimitry Andric } 12950b57cec5SDimitry Andric 129606c3fb27SDimitry Andric bool AsmPrinter::usesCFIWithoutEH() const { 129706c3fb27SDimitry Andric return MAI->usesCFIWithoutEH() && ModuleCFISection != CFISection::None; 1298fe6060f1SDimitry Andric } 1299fe6060f1SDimitry Andric 13000b57cec5SDimitry Andric void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) { 13010b57cec5SDimitry Andric ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType(); 130206c3fb27SDimitry Andric if (!usesCFIWithoutEH() && 1303fe6060f1SDimitry Andric ExceptionHandlingType != ExceptionHandling::DwarfCFI && 13040b57cec5SDimitry Andric ExceptionHandlingType != ExceptionHandling::ARM) 13050b57cec5SDimitry Andric return; 13060b57cec5SDimitry Andric 1307fe6060f1SDimitry Andric if (getFunctionCFISectionType(*MF) == CFISection::None) 13080b57cec5SDimitry Andric return; 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric // If there is no "real" instruction following this CFI instruction, skip 13110b57cec5SDimitry Andric // emitting it; it would be beyond the end of the function's FDE range. 13120b57cec5SDimitry Andric auto *MBB = MI.getParent(); 13130b57cec5SDimitry Andric auto I = std::next(MI.getIterator()); 13140b57cec5SDimitry Andric while (I != MBB->end() && I->isTransient()) 13150b57cec5SDimitry Andric ++I; 13160b57cec5SDimitry Andric if (I == MBB->instr_end() && 13170b57cec5SDimitry Andric MBB->getReverseIterator() == MBB->getParent()->rbegin()) 13180b57cec5SDimitry Andric return; 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions(); 13210b57cec5SDimitry Andric unsigned CFIIndex = MI.getOperand(0).getCFIIndex(); 13220b57cec5SDimitry Andric const MCCFIInstruction &CFI = Instrs[CFIIndex]; 13230b57cec5SDimitry Andric emitCFIInstruction(CFI); 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric 13260b57cec5SDimitry Andric void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) { 13270b57cec5SDimitry Andric // The operands are the MCSymbol and the frame offset of the allocation. 13280b57cec5SDimitry Andric MCSymbol *FrameAllocSym = MI.getOperand(0).getMCSymbol(); 13290b57cec5SDimitry Andric int FrameOffset = MI.getOperand(1).getImm(); 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric // Emit a symbol assignment. 13325ffd83dbSDimitry Andric OutStreamer->emitAssignment(FrameAllocSym, 13330b57cec5SDimitry Andric MCConstantExpr::create(FrameOffset, OutContext)); 13340b57cec5SDimitry Andric } 13350b57cec5SDimitry Andric 133606c3fb27SDimitry Andric /// Returns the BB metadata to be emitted in the SHT_LLVM_BB_ADDR_MAP section 133706c3fb27SDimitry Andric /// for a given basic block. This can be used to capture more precise profile 133806c3fb27SDimitry Andric /// information. 133906c3fb27SDimitry Andric static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) { 1340e8d8bef9SDimitry Andric const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); 134106c3fb27SDimitry Andric return object::BBAddrMap::BBEntry::Metadata{ 134206c3fb27SDimitry Andric MBB.isReturnBlock(), !MBB.empty() && TII->isTailCall(MBB.back()), 134306c3fb27SDimitry Andric MBB.isEHPad(), const_cast<MachineBasicBlock &>(MBB).canFallThrough(), 134406c3fb27SDimitry Andric !MBB.empty() && MBB.rbegin()->isIndirectBranch()} 134506c3fb27SDimitry Andric .encode(); 1346e8d8bef9SDimitry Andric } 1347e8d8bef9SDimitry Andric 1348*0fca6ea1SDimitry Andric static llvm::object::BBAddrMap::Features 1349*0fca6ea1SDimitry Andric getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) { 1350*0fca6ea1SDimitry Andric return {PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::FuncEntryCount), 1351*0fca6ea1SDimitry Andric PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BBFreq), 1352*0fca6ea1SDimitry Andric PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb), 1353*0fca6ea1SDimitry Andric MF.hasBBSections() && NumMBBSectionRanges > 1}; 1354*0fca6ea1SDimitry Andric } 1355*0fca6ea1SDimitry Andric 1356e8d8bef9SDimitry Andric void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { 1357e8d8bef9SDimitry Andric MCSection *BBAddrMapSection = 1358e8d8bef9SDimitry Andric getObjFileLowering().getBBAddrMapSection(*MF.getSection()); 1359e8d8bef9SDimitry Andric assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized."); 1360e8d8bef9SDimitry Andric 1361e8d8bef9SDimitry Andric const MCSymbol *FunctionSymbol = getFunctionBegin(); 1362e8d8bef9SDimitry Andric 136381ad6265SDimitry Andric OutStreamer->pushSection(); 136481ad6265SDimitry Andric OutStreamer->switchSection(BBAddrMapSection); 136581ad6265SDimitry Andric OutStreamer->AddComment("version"); 1366bdd1243dSDimitry Andric uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion(); 1367bdd1243dSDimitry Andric OutStreamer->emitInt8(BBAddrMapVersion); 136881ad6265SDimitry Andric OutStreamer->AddComment("feature"); 1369*0fca6ea1SDimitry Andric auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size()); 1370*0fca6ea1SDimitry Andric OutStreamer->emitInt8(Features.encode()); 1371*0fca6ea1SDimitry Andric // Emit BB Information for each basic block in the function. 1372*0fca6ea1SDimitry Andric if (Features.MultiBBRange) { 1373*0fca6ea1SDimitry Andric OutStreamer->AddComment("number of basic block ranges"); 1374*0fca6ea1SDimitry Andric OutStreamer->emitULEB128IntValue(MBBSectionRanges.size()); 1375*0fca6ea1SDimitry Andric } 1376*0fca6ea1SDimitry Andric // Number of blocks in each MBB section. 1377*0fca6ea1SDimitry Andric MapVector<MBBSectionID, unsigned> MBBSectionNumBlocks; 1378*0fca6ea1SDimitry Andric const MCSymbol *PrevMBBEndSymbol = nullptr; 1379*0fca6ea1SDimitry Andric if (!Features.MultiBBRange) { 138081ad6265SDimitry Andric OutStreamer->AddComment("function address"); 1381e8d8bef9SDimitry Andric OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize()); 138281ad6265SDimitry Andric OutStreamer->AddComment("number of basic blocks"); 1383e8d8bef9SDimitry Andric OutStreamer->emitULEB128IntValue(MF.size()); 1384*0fca6ea1SDimitry Andric PrevMBBEndSymbol = FunctionSymbol; 1385*0fca6ea1SDimitry Andric } else { 1386*0fca6ea1SDimitry Andric unsigned BBCount = 0; 1387*0fca6ea1SDimitry Andric for (const MachineBasicBlock &MBB : MF) { 1388*0fca6ea1SDimitry Andric BBCount++; 1389*0fca6ea1SDimitry Andric if (MBB.isEndSection()) { 1390*0fca6ea1SDimitry Andric // Store each section's basic block count when it ends. 1391*0fca6ea1SDimitry Andric MBBSectionNumBlocks[MBB.getSectionID()] = BBCount; 1392*0fca6ea1SDimitry Andric // Reset the count for the next section. 1393*0fca6ea1SDimitry Andric BBCount = 0; 1394*0fca6ea1SDimitry Andric } 1395*0fca6ea1SDimitry Andric } 1396*0fca6ea1SDimitry Andric } 1397*0fca6ea1SDimitry Andric // Emit the BB entry for each basic block in the function. 1398e8d8bef9SDimitry Andric for (const MachineBasicBlock &MBB : MF) { 1399e8d8bef9SDimitry Andric const MCSymbol *MBBSymbol = 1400e8d8bef9SDimitry Andric MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol(); 1401*0fca6ea1SDimitry Andric bool IsBeginSection = 1402*0fca6ea1SDimitry Andric Features.MultiBBRange && (MBB.isBeginSection() || MBB.isEntryBlock()); 1403*0fca6ea1SDimitry Andric if (IsBeginSection) { 1404*0fca6ea1SDimitry Andric OutStreamer->AddComment("base address"); 1405*0fca6ea1SDimitry Andric OutStreamer->emitSymbolValue(MBBSymbol, getPointerSize()); 1406*0fca6ea1SDimitry Andric OutStreamer->AddComment("number of basic blocks"); 1407*0fca6ea1SDimitry Andric OutStreamer->emitULEB128IntValue(MBBSectionNumBlocks[MBB.getSectionID()]); 1408*0fca6ea1SDimitry Andric PrevMBBEndSymbol = MBBSymbol; 1409*0fca6ea1SDimitry Andric } 1410bdd1243dSDimitry Andric // TODO: Remove this check when version 1 is deprecated. 1411bdd1243dSDimitry Andric if (BBAddrMapVersion > 1) { 1412bdd1243dSDimitry Andric OutStreamer->AddComment("BB id"); 1413bdd1243dSDimitry Andric // Emit the BB ID for this basic block. 14145f757f3fSDimitry Andric // We only emit BaseID since CloneID is unset for 14155f757f3fSDimitry Andric // basic-block-sections=labels. 14165f757f3fSDimitry Andric // TODO: Emit the full BBID when labels and sections can be mixed 14175f757f3fSDimitry Andric // together. 14185f757f3fSDimitry Andric OutStreamer->emitULEB128IntValue(MBB.getBBID()->BaseID); 1419bdd1243dSDimitry Andric } 142081ad6265SDimitry Andric // Emit the basic block offset relative to the end of the previous block. 142181ad6265SDimitry Andric // This is zero unless the block is padded due to alignment. 142281ad6265SDimitry Andric emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol); 1423e8d8bef9SDimitry Andric // Emit the basic block size. When BBs have alignments, their size cannot 1424e8d8bef9SDimitry Andric // always be computed from their offsets. 1425e8d8bef9SDimitry Andric emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol); 1426bdd1243dSDimitry Andric // Emit the Metadata. 1427e8d8bef9SDimitry Andric OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB)); 142881ad6265SDimitry Andric PrevMBBEndSymbol = MBB.getEndSymbol(); 1429e8d8bef9SDimitry Andric } 14301db9f3b2SDimitry Andric 1431*0fca6ea1SDimitry Andric if (Features.hasPGOAnalysis()) { 14321db9f3b2SDimitry Andric assert(BBAddrMapVersion >= 2 && 14331db9f3b2SDimitry Andric "PGOAnalysisMap only supports version 2 or later"); 14341db9f3b2SDimitry Andric 1435*0fca6ea1SDimitry Andric if (Features.FuncEntryCount) { 14361db9f3b2SDimitry Andric OutStreamer->AddComment("function entry count"); 14371db9f3b2SDimitry Andric auto MaybeEntryCount = MF.getFunction().getEntryCount(); 14381db9f3b2SDimitry Andric OutStreamer->emitULEB128IntValue( 14391db9f3b2SDimitry Andric MaybeEntryCount ? MaybeEntryCount->getCount() : 0); 14401db9f3b2SDimitry Andric } 14411db9f3b2SDimitry Andric const MachineBlockFrequencyInfo *MBFI = 1442*0fca6ea1SDimitry Andric Features.BBFreq 14431db9f3b2SDimitry Andric ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() 14441db9f3b2SDimitry Andric : nullptr; 14451db9f3b2SDimitry Andric const MachineBranchProbabilityInfo *MBPI = 1446*0fca6ea1SDimitry Andric Features.BrProb 1447*0fca6ea1SDimitry Andric ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI() 14481db9f3b2SDimitry Andric : nullptr; 14491db9f3b2SDimitry Andric 1450*0fca6ea1SDimitry Andric if (Features.BBFreq || Features.BrProb) { 14511db9f3b2SDimitry Andric for (const MachineBasicBlock &MBB : MF) { 1452*0fca6ea1SDimitry Andric if (Features.BBFreq) { 14531db9f3b2SDimitry Andric OutStreamer->AddComment("basic block frequency"); 14541db9f3b2SDimitry Andric OutStreamer->emitULEB128IntValue( 14551db9f3b2SDimitry Andric MBFI->getBlockFreq(&MBB).getFrequency()); 14561db9f3b2SDimitry Andric } 1457*0fca6ea1SDimitry Andric if (Features.BrProb) { 14581db9f3b2SDimitry Andric unsigned SuccCount = MBB.succ_size(); 14591db9f3b2SDimitry Andric OutStreamer->AddComment("basic block successor count"); 14601db9f3b2SDimitry Andric OutStreamer->emitULEB128IntValue(SuccCount); 14611db9f3b2SDimitry Andric for (const MachineBasicBlock *SuccMBB : MBB.successors()) { 14621db9f3b2SDimitry Andric OutStreamer->AddComment("successor BB ID"); 14631db9f3b2SDimitry Andric OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID); 14641db9f3b2SDimitry Andric OutStreamer->AddComment("successor branch probability"); 14651db9f3b2SDimitry Andric OutStreamer->emitULEB128IntValue( 14661db9f3b2SDimitry Andric MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator()); 14671db9f3b2SDimitry Andric } 14681db9f3b2SDimitry Andric } 14691db9f3b2SDimitry Andric } 14701db9f3b2SDimitry Andric } 14711db9f3b2SDimitry Andric } 14721db9f3b2SDimitry Andric 147381ad6265SDimitry Andric OutStreamer->popSection(); 1474e8d8bef9SDimitry Andric } 1475e8d8bef9SDimitry Andric 1476bdd1243dSDimitry Andric void AsmPrinter::emitKCFITrapEntry(const MachineFunction &MF, 1477bdd1243dSDimitry Andric const MCSymbol *Symbol) { 1478bdd1243dSDimitry Andric MCSection *Section = 1479bdd1243dSDimitry Andric getObjFileLowering().getKCFITrapSection(*MF.getSection()); 1480bdd1243dSDimitry Andric if (!Section) 1481bdd1243dSDimitry Andric return; 1482bdd1243dSDimitry Andric 1483bdd1243dSDimitry Andric OutStreamer->pushSection(); 1484bdd1243dSDimitry Andric OutStreamer->switchSection(Section); 1485bdd1243dSDimitry Andric 1486bdd1243dSDimitry Andric MCSymbol *Loc = OutContext.createLinkerPrivateTempSymbol(); 1487bdd1243dSDimitry Andric OutStreamer->emitLabel(Loc); 1488bdd1243dSDimitry Andric OutStreamer->emitAbsoluteSymbolDiff(Symbol, Loc, 4); 1489bdd1243dSDimitry Andric 1490bdd1243dSDimitry Andric OutStreamer->popSection(); 1491bdd1243dSDimitry Andric } 1492bdd1243dSDimitry Andric 1493bdd1243dSDimitry Andric void AsmPrinter::emitKCFITypeId(const MachineFunction &MF) { 1494bdd1243dSDimitry Andric const Function &F = MF.getFunction(); 1495bdd1243dSDimitry Andric if (const MDNode *MD = F.getMetadata(LLVMContext::MD_kcfi_type)) 1496*0fca6ea1SDimitry Andric emitGlobalConstant(F.getDataLayout(), 1497bdd1243dSDimitry Andric mdconst::extract<ConstantInt>(MD->getOperand(0))); 1498bdd1243dSDimitry Andric } 1499bdd1243dSDimitry Andric 1500e8d8bef9SDimitry Andric void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) { 150181ad6265SDimitry Andric if (PP) { 1502e8d8bef9SDimitry Andric auto GUID = MI.getOperand(0).getImm(); 1503e8d8bef9SDimitry Andric auto Index = MI.getOperand(1).getImm(); 1504e8d8bef9SDimitry Andric auto Type = MI.getOperand(2).getImm(); 1505e8d8bef9SDimitry Andric auto Attr = MI.getOperand(3).getImm(); 1506e8d8bef9SDimitry Andric DILocation *DebugLoc = MI.getDebugLoc(); 1507e8d8bef9SDimitry Andric PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc); 1508e8d8bef9SDimitry Andric } 150981ad6265SDimitry Andric } 1510e8d8bef9SDimitry Andric 15110b57cec5SDimitry Andric void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) { 15120b57cec5SDimitry Andric if (!MF.getTarget().Options.EmitStackSizeSection) 15130b57cec5SDimitry Andric return; 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric MCSection *StackSizeSection = 15160b57cec5SDimitry Andric getObjFileLowering().getStackSizesSection(*getCurrentSection()); 15170b57cec5SDimitry Andric if (!StackSizeSection) 15180b57cec5SDimitry Andric return; 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); 15210b57cec5SDimitry Andric // Don't emit functions with dynamic stack allocations. 15220b57cec5SDimitry Andric if (FrameInfo.hasVarSizedObjects()) 15230b57cec5SDimitry Andric return; 15240b57cec5SDimitry Andric 152581ad6265SDimitry Andric OutStreamer->pushSection(); 152681ad6265SDimitry Andric OutStreamer->switchSection(StackSizeSection); 15270b57cec5SDimitry Andric 15280b57cec5SDimitry Andric const MCSymbol *FunctionSymbol = getFunctionBegin(); 152981ad6265SDimitry Andric uint64_t StackSize = 153081ad6265SDimitry Andric FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); 15315ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize()); 15325ffd83dbSDimitry Andric OutStreamer->emitULEB128IntValue(StackSize); 15330b57cec5SDimitry Andric 153481ad6265SDimitry Andric OutStreamer->popSection(); 15350b57cec5SDimitry Andric } 15360b57cec5SDimitry Andric 1537fe6060f1SDimitry Andric void AsmPrinter::emitStackUsage(const MachineFunction &MF) { 1538fe6060f1SDimitry Andric const std::string &OutputFilename = MF.getTarget().Options.StackUsageOutput; 1539fe6060f1SDimitry Andric 1540fe6060f1SDimitry Andric // OutputFilename empty implies -fstack-usage is not passed. 1541fe6060f1SDimitry Andric if (OutputFilename.empty()) 1542fe6060f1SDimitry Andric return; 1543fe6060f1SDimitry Andric 1544fe6060f1SDimitry Andric const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); 154581ad6265SDimitry Andric uint64_t StackSize = 154681ad6265SDimitry Andric FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); 1547fe6060f1SDimitry Andric 1548fe6060f1SDimitry Andric if (StackUsageStream == nullptr) { 1549fe6060f1SDimitry Andric std::error_code EC; 1550fe6060f1SDimitry Andric StackUsageStream = 1551fe6060f1SDimitry Andric std::make_unique<raw_fd_ostream>(OutputFilename, EC, sys::fs::OF_Text); 1552fe6060f1SDimitry Andric if (EC) { 1553fe6060f1SDimitry Andric errs() << "Could not open file: " << EC.message(); 1554fe6060f1SDimitry Andric return; 1555fe6060f1SDimitry Andric } 1556fe6060f1SDimitry Andric } 1557fe6060f1SDimitry Andric 1558fe6060f1SDimitry Andric if (const DISubprogram *DSP = MF.getFunction().getSubprogram()) 15595f757f3fSDimitry Andric *StackUsageStream << DSP->getFilename() << ':' << DSP->getLine(); 15605f757f3fSDimitry Andric else 15615f757f3fSDimitry Andric *StackUsageStream << MF.getFunction().getParent()->getName(); 1562fe6060f1SDimitry Andric 1563fe6060f1SDimitry Andric *StackUsageStream << ':' << MF.getName() << '\t' << StackSize << '\t'; 1564fe6060f1SDimitry Andric if (FrameInfo.hasVarSizedObjects()) 1565fe6060f1SDimitry Andric *StackUsageStream << "dynamic\n"; 1566fe6060f1SDimitry Andric else 1567fe6060f1SDimitry Andric *StackUsageStream << "static\n"; 1568fe6060f1SDimitry Andric } 1569fe6060f1SDimitry Andric 1570bdd1243dSDimitry Andric void AsmPrinter::emitPCSectionsLabel(const MachineFunction &MF, 1571bdd1243dSDimitry Andric const MDNode &MD) { 1572bdd1243dSDimitry Andric MCSymbol *S = MF.getContext().createTempSymbol("pcsection"); 1573bdd1243dSDimitry Andric OutStreamer->emitLabel(S); 1574bdd1243dSDimitry Andric PCSectionsSymbols[&MD].emplace_back(S); 1575bdd1243dSDimitry Andric } 1576bdd1243dSDimitry Andric 1577bdd1243dSDimitry Andric void AsmPrinter::emitPCSections(const MachineFunction &MF) { 1578bdd1243dSDimitry Andric const Function &F = MF.getFunction(); 1579bdd1243dSDimitry Andric if (PCSectionsSymbols.empty() && !F.hasMetadata(LLVMContext::MD_pcsections)) 1580bdd1243dSDimitry Andric return; 1581bdd1243dSDimitry Andric 1582bdd1243dSDimitry Andric const CodeModel::Model CM = MF.getTarget().getCodeModel(); 1583bdd1243dSDimitry Andric const unsigned RelativeRelocSize = 1584bdd1243dSDimitry Andric (CM == CodeModel::Medium || CM == CodeModel::Large) ? getPointerSize() 1585bdd1243dSDimitry Andric : 4; 1586bdd1243dSDimitry Andric 1587bdd1243dSDimitry Andric // Switch to PCSection, short-circuiting the common case where the current 1588bdd1243dSDimitry Andric // section is still valid (assume most MD_pcsections contain just 1 section). 1589bdd1243dSDimitry Andric auto SwitchSection = [&, Prev = StringRef()](const StringRef &Sec) mutable { 1590bdd1243dSDimitry Andric if (Sec == Prev) 1591bdd1243dSDimitry Andric return; 1592bdd1243dSDimitry Andric MCSection *S = getObjFileLowering().getPCSection(Sec, MF.getSection()); 1593bdd1243dSDimitry Andric assert(S && "PC section is not initialized"); 1594bdd1243dSDimitry Andric OutStreamer->switchSection(S); 1595bdd1243dSDimitry Andric Prev = Sec; 1596bdd1243dSDimitry Andric }; 1597bdd1243dSDimitry Andric // Emit symbols into sections and data as specified in the pcsections MDNode. 1598bdd1243dSDimitry Andric auto EmitForMD = [&](const MDNode &MD, ArrayRef<const MCSymbol *> Syms, 1599bdd1243dSDimitry Andric bool Deltas) { 1600bdd1243dSDimitry Andric // Expect the first operand to be a section name. After that, a tuple of 1601bdd1243dSDimitry Andric // constants may appear, which will simply be emitted into the current 1602bdd1243dSDimitry Andric // section (the user of MD_pcsections decides the format of encoded data). 1603bdd1243dSDimitry Andric assert(isa<MDString>(MD.getOperand(0)) && "first operand not a string"); 160406c3fb27SDimitry Andric bool ConstULEB128 = false; 1605bdd1243dSDimitry Andric for (const MDOperand &MDO : MD.operands()) { 1606bdd1243dSDimitry Andric if (auto *S = dyn_cast<MDString>(MDO)) { 160706c3fb27SDimitry Andric // Found string, start of new section! 160806c3fb27SDimitry Andric // Find options for this section "<section>!<opts>" - supported options: 160906c3fb27SDimitry Andric // C = Compress constant integers of size 2-8 bytes as ULEB128. 161006c3fb27SDimitry Andric const StringRef SecWithOpt = S->getString(); 161106c3fb27SDimitry Andric const size_t OptStart = SecWithOpt.find('!'); // likely npos 161206c3fb27SDimitry Andric const StringRef Sec = SecWithOpt.substr(0, OptStart); 161306c3fb27SDimitry Andric const StringRef Opts = SecWithOpt.substr(OptStart); // likely empty 16145f757f3fSDimitry Andric ConstULEB128 = Opts.contains('C'); 161506c3fb27SDimitry Andric #ifndef NDEBUG 161606c3fb27SDimitry Andric for (char O : Opts) 161706c3fb27SDimitry Andric assert((O == '!' || O == 'C') && "Invalid !pcsections options"); 161806c3fb27SDimitry Andric #endif 161906c3fb27SDimitry Andric SwitchSection(Sec); 1620bdd1243dSDimitry Andric const MCSymbol *Prev = Syms.front(); 1621bdd1243dSDimitry Andric for (const MCSymbol *Sym : Syms) { 1622bdd1243dSDimitry Andric if (Sym == Prev || !Deltas) { 1623bdd1243dSDimitry Andric // Use the entry itself as the base of the relative offset. 1624bdd1243dSDimitry Andric MCSymbol *Base = MF.getContext().createTempSymbol("pcsection_base"); 1625bdd1243dSDimitry Andric OutStreamer->emitLabel(Base); 1626bdd1243dSDimitry Andric // Emit relative relocation `addr - base`, which avoids a dynamic 1627bdd1243dSDimitry Andric // relocation in the final binary. User will get the address with 1628bdd1243dSDimitry Andric // `base + addr`. 1629bdd1243dSDimitry Andric emitLabelDifference(Sym, Base, RelativeRelocSize); 1630bdd1243dSDimitry Andric } else { 163106c3fb27SDimitry Andric // Emit delta between symbol and previous symbol. 163206c3fb27SDimitry Andric if (ConstULEB128) 163306c3fb27SDimitry Andric emitLabelDifferenceAsULEB128(Sym, Prev); 163406c3fb27SDimitry Andric else 1635bdd1243dSDimitry Andric emitLabelDifference(Sym, Prev, 4); 1636bdd1243dSDimitry Andric } 1637bdd1243dSDimitry Andric Prev = Sym; 1638bdd1243dSDimitry Andric } 1639bdd1243dSDimitry Andric } else { 164006c3fb27SDimitry Andric // Emit auxiliary data after PC. 1641bdd1243dSDimitry Andric assert(isa<MDNode>(MDO) && "expecting either string or tuple"); 1642bdd1243dSDimitry Andric const auto *AuxMDs = cast<MDNode>(MDO); 1643bdd1243dSDimitry Andric for (const MDOperand &AuxMDO : AuxMDs->operands()) { 1644bdd1243dSDimitry Andric assert(isa<ConstantAsMetadata>(AuxMDO) && "expecting a constant"); 164506c3fb27SDimitry Andric const Constant *C = cast<ConstantAsMetadata>(AuxMDO)->getValue(); 1646*0fca6ea1SDimitry Andric const DataLayout &DL = F.getDataLayout(); 164706c3fb27SDimitry Andric const uint64_t Size = DL.getTypeStoreSize(C->getType()); 164806c3fb27SDimitry Andric 164906c3fb27SDimitry Andric if (auto *CI = dyn_cast<ConstantInt>(C); 165006c3fb27SDimitry Andric CI && ConstULEB128 && Size > 1 && Size <= 8) { 165106c3fb27SDimitry Andric emitULEB128(CI->getZExtValue()); 165206c3fb27SDimitry Andric } else { 165306c3fb27SDimitry Andric emitGlobalConstant(DL, C); 165406c3fb27SDimitry Andric } 1655bdd1243dSDimitry Andric } 1656bdd1243dSDimitry Andric } 1657bdd1243dSDimitry Andric } 1658bdd1243dSDimitry Andric }; 1659bdd1243dSDimitry Andric 1660bdd1243dSDimitry Andric OutStreamer->pushSection(); 1661bdd1243dSDimitry Andric // Emit PCs for function start and function size. 1662bdd1243dSDimitry Andric if (const MDNode *MD = F.getMetadata(LLVMContext::MD_pcsections)) 1663bdd1243dSDimitry Andric EmitForMD(*MD, {getFunctionBegin(), getFunctionEnd()}, true); 1664bdd1243dSDimitry Andric // Emit PCs for instructions collected. 1665bdd1243dSDimitry Andric for (const auto &MS : PCSectionsSymbols) 1666bdd1243dSDimitry Andric EmitForMD(*MS.first, MS.second, false); 1667bdd1243dSDimitry Andric OutStreamer->popSection(); 1668bdd1243dSDimitry Andric PCSectionsSymbols.clear(); 1669bdd1243dSDimitry Andric } 1670bdd1243dSDimitry Andric 1671bdd1243dSDimitry Andric /// Returns true if function begin and end labels should be emitted. 1672*0fca6ea1SDimitry Andric static bool needFuncLabels(const MachineFunction &MF, 1673*0fca6ea1SDimitry Andric const MachineModuleInfo &MMI) { 1674bdd1243dSDimitry Andric if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || 1675bdd1243dSDimitry Andric MMI.hasDebugInfo() || 1676bdd1243dSDimitry Andric MF.getFunction().hasMetadata(LLVMContext::MD_pcsections)) 16770b57cec5SDimitry Andric return true; 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric // We might emit an EH table that uses function begin and end labels even if 16800b57cec5SDimitry Andric // we don't have any landingpads. 16810b57cec5SDimitry Andric if (!MF.getFunction().hasPersonalityFn()) 16820b57cec5SDimitry Andric return false; 16830b57cec5SDimitry Andric return !isNoOpWithoutInvoke( 16840b57cec5SDimitry Andric classifyEHPersonality(MF.getFunction().getPersonalityFn())); 16850b57cec5SDimitry Andric } 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric /// EmitFunctionBody - This method emits the body and trailer for a 16880b57cec5SDimitry Andric /// function. 16895ffd83dbSDimitry Andric void AsmPrinter::emitFunctionBody() { 16905ffd83dbSDimitry Andric emitFunctionHeader(); 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric // Emit target-specific gunk before the function body. 16935ffd83dbSDimitry Andric emitFunctionBodyStart(); 16940b57cec5SDimitry Andric 16950b57cec5SDimitry Andric if (isVerbose()) { 16960b57cec5SDimitry Andric // Get MachineDominatorTree or compute it on the fly if it's unavailable 1697*0fca6ea1SDimitry Andric auto MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>(); 1698*0fca6ea1SDimitry Andric MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; 16990b57cec5SDimitry Andric if (!MDT) { 17008bcb0991SDimitry Andric OwnedMDT = std::make_unique<MachineDominatorTree>(); 17010b57cec5SDimitry Andric OwnedMDT->getBase().recalculate(*MF); 17020b57cec5SDimitry Andric MDT = OwnedMDT.get(); 17030b57cec5SDimitry Andric } 17040b57cec5SDimitry Andric 17050b57cec5SDimitry Andric // Get MachineLoopInfo or compute it on the fly if it's unavailable 1706*0fca6ea1SDimitry Andric auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>(); 1707*0fca6ea1SDimitry Andric MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr; 17080b57cec5SDimitry Andric if (!MLI) { 17098bcb0991SDimitry Andric OwnedMLI = std::make_unique<MachineLoopInfo>(); 1710*0fca6ea1SDimitry Andric OwnedMLI->analyze(MDT->getBase()); 17110b57cec5SDimitry Andric MLI = OwnedMLI.get(); 17120b57cec5SDimitry Andric } 17130b57cec5SDimitry Andric } 17140b57cec5SDimitry Andric 17150b57cec5SDimitry Andric // Print out code for the function. 17160b57cec5SDimitry Andric bool HasAnyRealCode = false; 17170b57cec5SDimitry Andric int NumInstsInFunction = 0; 171806c3fb27SDimitry Andric bool IsEHa = MMI->getModule()->getModuleFlag("eh-asynch"); 17195ffd83dbSDimitry Andric 1720e8d8bef9SDimitry Andric bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE); 17210b57cec5SDimitry Andric for (auto &MBB : *MF) { 17220b57cec5SDimitry Andric // Print a label for the basic block. 17235ffd83dbSDimitry Andric emitBasicBlockStart(MBB); 1724e8d8bef9SDimitry Andric DenseMap<StringRef, unsigned> MnemonicCounts; 17250b57cec5SDimitry Andric for (auto &MI : MBB) { 17260b57cec5SDimitry Andric // Print the assembly for the instruction. 17270b57cec5SDimitry Andric if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() && 17280b57cec5SDimitry Andric !MI.isDebugInstr()) { 17290b57cec5SDimitry Andric HasAnyRealCode = true; 17300b57cec5SDimitry Andric ++NumInstsInFunction; 17310b57cec5SDimitry Andric } 17320b57cec5SDimitry Andric 1733480093f4SDimitry Andric // If there is a pre-instruction symbol, emit a label for it here. 17340b57cec5SDimitry Andric if (MCSymbol *S = MI.getPreInstrSymbol()) 17355ffd83dbSDimitry Andric OutStreamer->emitLabel(S); 17360b57cec5SDimitry Andric 1737bdd1243dSDimitry Andric if (MDNode *MD = MI.getPCSections()) 1738bdd1243dSDimitry Andric emitPCSectionsLabel(*MF, *MD); 1739bdd1243dSDimitry Andric 1740*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 1741*0fca6ea1SDimitry Andric Handler->beginInstruction(&MI); 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric if (isVerbose()) 174481ad6265SDimitry Andric emitComments(MI, OutStreamer->getCommentOS()); 17450b57cec5SDimitry Andric 17460b57cec5SDimitry Andric switch (MI.getOpcode()) { 17470b57cec5SDimitry Andric case TargetOpcode::CFI_INSTRUCTION: 17480b57cec5SDimitry Andric emitCFIInstruction(MI); 17490b57cec5SDimitry Andric break; 17500b57cec5SDimitry Andric case TargetOpcode::LOCAL_ESCAPE: 17510b57cec5SDimitry Andric emitFrameAlloc(MI); 17520b57cec5SDimitry Andric break; 17530b57cec5SDimitry Andric case TargetOpcode::ANNOTATION_LABEL: 17540b57cec5SDimitry Andric case TargetOpcode::GC_LABEL: 17555ffd83dbSDimitry Andric OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol()); 17560b57cec5SDimitry Andric break; 175706c3fb27SDimitry Andric case TargetOpcode::EH_LABEL: 175806c3fb27SDimitry Andric OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol()); 175906c3fb27SDimitry Andric // For AsynchEH, insert a Nop if followed by a trap inst 176006c3fb27SDimitry Andric // Or the exception won't be caught. 176106c3fb27SDimitry Andric // (see MCConstantExpr::create(1,..) in WinException.cpp) 176206c3fb27SDimitry Andric // Ignore SDiv/UDiv because a DIV with Const-0 divisor 176306c3fb27SDimitry Andric // must have being turned into an UndefValue. 176406c3fb27SDimitry Andric // Div with variable opnds won't be the first instruction in 176506c3fb27SDimitry Andric // an EH region as it must be led by at least a Load 176606c3fb27SDimitry Andric { 176706c3fb27SDimitry Andric auto MI2 = std::next(MI.getIterator()); 176806c3fb27SDimitry Andric if (IsEHa && MI2 != MBB.end() && 176906c3fb27SDimitry Andric (MI2->mayLoadOrStore() || MI2->mayRaiseFPException())) 177006c3fb27SDimitry Andric emitNops(1); 177106c3fb27SDimitry Andric } 177206c3fb27SDimitry Andric break; 17730b57cec5SDimitry Andric case TargetOpcode::INLINEASM: 17740b57cec5SDimitry Andric case TargetOpcode::INLINEASM_BR: 17755ffd83dbSDimitry Andric emitInlineAsm(&MI); 17760b57cec5SDimitry Andric break; 17770b57cec5SDimitry Andric case TargetOpcode::DBG_VALUE: 1778fe6060f1SDimitry Andric case TargetOpcode::DBG_VALUE_LIST: 17790b57cec5SDimitry Andric if (isVerbose()) { 17800b57cec5SDimitry Andric if (!emitDebugValueComment(&MI, *this)) 17815ffd83dbSDimitry Andric emitInstruction(&MI); 17820b57cec5SDimitry Andric } 17830b57cec5SDimitry Andric break; 1784e8d8bef9SDimitry Andric case TargetOpcode::DBG_INSTR_REF: 1785e8d8bef9SDimitry Andric // This instruction reference will have been resolved to a machine 1786e8d8bef9SDimitry Andric // location, and a nearby DBG_VALUE created. We can safely ignore 1787e8d8bef9SDimitry Andric // the instruction reference. 1788e8d8bef9SDimitry Andric break; 1789fe6060f1SDimitry Andric case TargetOpcode::DBG_PHI: 1790fe6060f1SDimitry Andric // This instruction is only used to label a program point, it's purely 1791fe6060f1SDimitry Andric // meta information. 1792fe6060f1SDimitry Andric break; 17930b57cec5SDimitry Andric case TargetOpcode::DBG_LABEL: 17940b57cec5SDimitry Andric if (isVerbose()) { 17950b57cec5SDimitry Andric if (!emitDebugLabelComment(&MI, *this)) 17965ffd83dbSDimitry Andric emitInstruction(&MI); 17970b57cec5SDimitry Andric } 17980b57cec5SDimitry Andric break; 17990b57cec5SDimitry Andric case TargetOpcode::IMPLICIT_DEF: 18000b57cec5SDimitry Andric if (isVerbose()) emitImplicitDef(&MI); 18010b57cec5SDimitry Andric break; 18020b57cec5SDimitry Andric case TargetOpcode::KILL: 18030b57cec5SDimitry Andric if (isVerbose()) emitKill(&MI, *this); 18040b57cec5SDimitry Andric break; 1805e8d8bef9SDimitry Andric case TargetOpcode::PSEUDO_PROBE: 1806e8d8bef9SDimitry Andric emitPseudoProbe(MI); 1807e8d8bef9SDimitry Andric break; 1808fe6060f1SDimitry Andric case TargetOpcode::ARITH_FENCE: 1809fe6060f1SDimitry Andric if (isVerbose()) 1810fe6060f1SDimitry Andric OutStreamer->emitRawComment("ARITH_FENCE"); 1811fe6060f1SDimitry Andric break; 1812bdd1243dSDimitry Andric case TargetOpcode::MEMBARRIER: 1813bdd1243dSDimitry Andric OutStreamer->emitRawComment("MEMBARRIER"); 1814bdd1243dSDimitry Andric break; 18155f757f3fSDimitry Andric case TargetOpcode::JUMP_TABLE_DEBUG_INFO: 18165f757f3fSDimitry Andric // This instruction is only used to note jump table debug info, it's 18175f757f3fSDimitry Andric // purely meta information. 18185f757f3fSDimitry Andric break; 18190b57cec5SDimitry Andric default: 18205ffd83dbSDimitry Andric emitInstruction(&MI); 1821e8d8bef9SDimitry Andric if (CanDoExtraAnalysis) { 1822e8d8bef9SDimitry Andric MCInst MCI; 1823e8d8bef9SDimitry Andric MCI.setOpcode(MI.getOpcode()); 1824e8d8bef9SDimitry Andric auto Name = OutStreamer->getMnemonic(MCI); 1825e8d8bef9SDimitry Andric auto I = MnemonicCounts.insert({Name, 0u}); 1826e8d8bef9SDimitry Andric I.first->second++; 1827e8d8bef9SDimitry Andric } 18280b57cec5SDimitry Andric break; 18290b57cec5SDimitry Andric } 18300b57cec5SDimitry Andric 1831480093f4SDimitry Andric // If there is a post-instruction symbol, emit a label for it here. 18320b57cec5SDimitry Andric if (MCSymbol *S = MI.getPostInstrSymbol()) 18335ffd83dbSDimitry Andric OutStreamer->emitLabel(S); 18340b57cec5SDimitry Andric 1835*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 1836*0fca6ea1SDimitry Andric Handler->endInstruction(); 18370b57cec5SDimitry Andric } 18380b57cec5SDimitry Andric 1839e8d8bef9SDimitry Andric // We must emit temporary symbol for the end of this basic block, if either 1840e8d8bef9SDimitry Andric // we have BBLabels enabled or if this basic blocks marks the end of a 1841fe6060f1SDimitry Andric // section. 1842*0fca6ea1SDimitry Andric if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap || 1843fe6060f1SDimitry Andric (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection())) 1844e8d8bef9SDimitry Andric OutStreamer->emitLabel(MBB.getEndSymbol()); 18455ffd83dbSDimitry Andric 18465ffd83dbSDimitry Andric if (MBB.isEndSection()) { 1847e8d8bef9SDimitry Andric // The size directive for the section containing the entry block is 1848e8d8bef9SDimitry Andric // handled separately by the function section. 18495ffd83dbSDimitry Andric if (!MBB.sameSection(&MF->front())) { 1850e8d8bef9SDimitry Andric if (MAI->hasDotTypeDotSizeDirective()) { 1851e8d8bef9SDimitry Andric // Emit the size directive for the basic block section. 1852e8d8bef9SDimitry Andric const MCExpr *SizeExp = MCBinaryExpr::createSub( 1853e8d8bef9SDimitry Andric MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext), 1854e8d8bef9SDimitry Andric MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext), 1855e8d8bef9SDimitry Andric OutContext); 1856e8d8bef9SDimitry Andric OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp); 1857e8d8bef9SDimitry Andric } 1858*0fca6ea1SDimitry Andric assert(!MBBSectionRanges.contains(MBB.getSectionID()) && 1859*0fca6ea1SDimitry Andric "Overwrite section range"); 1860*0fca6ea1SDimitry Andric MBBSectionRanges[MBB.getSectionID()] = 1861e8d8bef9SDimitry Andric MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()}; 18625ffd83dbSDimitry Andric } 18635ffd83dbSDimitry Andric } 18645ffd83dbSDimitry Andric emitBasicBlockEnd(MBB); 1865e8d8bef9SDimitry Andric 1866e8d8bef9SDimitry Andric if (CanDoExtraAnalysis) { 1867e8d8bef9SDimitry Andric // Skip empty blocks. 1868e8d8bef9SDimitry Andric if (MBB.empty()) 1869e8d8bef9SDimitry Andric continue; 1870e8d8bef9SDimitry Andric 1871e8d8bef9SDimitry Andric MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix", 1872e8d8bef9SDimitry Andric MBB.begin()->getDebugLoc(), &MBB); 1873e8d8bef9SDimitry Andric 1874e8d8bef9SDimitry Andric // Generate instruction mix remark. First, sort counts in descending order 1875e8d8bef9SDimitry Andric // by count and name. 1876e8d8bef9SDimitry Andric SmallVector<std::pair<StringRef, unsigned>, 128> MnemonicVec; 1877e8d8bef9SDimitry Andric for (auto &KV : MnemonicCounts) 1878e8d8bef9SDimitry Andric MnemonicVec.emplace_back(KV.first, KV.second); 1879e8d8bef9SDimitry Andric 1880e8d8bef9SDimitry Andric sort(MnemonicVec, [](const std::pair<StringRef, unsigned> &A, 1881e8d8bef9SDimitry Andric const std::pair<StringRef, unsigned> &B) { 1882e8d8bef9SDimitry Andric if (A.second > B.second) 1883e8d8bef9SDimitry Andric return true; 1884e8d8bef9SDimitry Andric if (A.second == B.second) 1885e8d8bef9SDimitry Andric return StringRef(A.first) < StringRef(B.first); 1886e8d8bef9SDimitry Andric return false; 1887e8d8bef9SDimitry Andric }); 1888e8d8bef9SDimitry Andric R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n"; 1889e8d8bef9SDimitry Andric for (auto &KV : MnemonicVec) { 1890349cc55cSDimitry Andric auto Name = (Twine("INST_") + getToken(KV.first.trim()).first).str(); 1891e8d8bef9SDimitry Andric R << KV.first << ": " << ore::NV(Name, KV.second) << "\n"; 1892e8d8bef9SDimitry Andric } 1893e8d8bef9SDimitry Andric ORE->emit(R); 1894e8d8bef9SDimitry Andric } 18950b57cec5SDimitry Andric } 18960b57cec5SDimitry Andric 18970b57cec5SDimitry Andric EmittedInsts += NumInstsInFunction; 18980b57cec5SDimitry Andric MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount", 18990b57cec5SDimitry Andric MF->getFunction().getSubprogram(), 19000b57cec5SDimitry Andric &MF->front()); 19010b57cec5SDimitry Andric R << ore::NV("NumInstructions", NumInstsInFunction) 19020b57cec5SDimitry Andric << " instructions in function"; 19030b57cec5SDimitry Andric ORE->emit(R); 19040b57cec5SDimitry Andric 19050b57cec5SDimitry Andric // If the function is empty and the object file uses .subsections_via_symbols, 19060b57cec5SDimitry Andric // then we need to emit *something* to the function body to prevent the 19070b57cec5SDimitry Andric // labels from collapsing together. Just emit a noop. 19080b57cec5SDimitry Andric // Similarly, don't emit empty functions on Windows either. It can lead to 19090b57cec5SDimitry Andric // duplicate entries (two functions with the same RVA) in the Guard CF Table 19100b57cec5SDimitry Andric // after linking, causing the kernel not to load the binary: 19110b57cec5SDimitry Andric // https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html 19120b57cec5SDimitry Andric // FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer. 19130b57cec5SDimitry Andric const Triple &TT = TM.getTargetTriple(); 19140b57cec5SDimitry Andric if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() || 19150b57cec5SDimitry Andric (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) { 1916fe6060f1SDimitry Andric MCInst Noop = MF->getSubtarget().getInstrInfo()->getNop(); 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andric // Targets can opt-out of emitting the noop here by leaving the opcode 19190b57cec5SDimitry Andric // unspecified. 19200b57cec5SDimitry Andric if (Noop.getOpcode()) { 19210b57cec5SDimitry Andric OutStreamer->AddComment("avoids zero-length function"); 192255e4f9d5SDimitry Andric emitNops(1); 19230b57cec5SDimitry Andric } 19240b57cec5SDimitry Andric } 19250b57cec5SDimitry Andric 19265ffd83dbSDimitry Andric // Switch to the original section in case basic block sections was used. 192781ad6265SDimitry Andric OutStreamer->switchSection(MF->getSection()); 19285ffd83dbSDimitry Andric 19290b57cec5SDimitry Andric const Function &F = MF->getFunction(); 19300b57cec5SDimitry Andric for (const auto &BB : F) { 19310b57cec5SDimitry Andric if (!BB.hasAddressTaken()) 19320b57cec5SDimitry Andric continue; 19330b57cec5SDimitry Andric MCSymbol *Sym = GetBlockAddressSymbol(&BB); 19340b57cec5SDimitry Andric if (Sym->isDefined()) 19350b57cec5SDimitry Andric continue; 19360b57cec5SDimitry Andric OutStreamer->AddComment("Address of block that was removed by CodeGen"); 19375ffd83dbSDimitry Andric OutStreamer->emitLabel(Sym); 19380b57cec5SDimitry Andric } 19390b57cec5SDimitry Andric 19400b57cec5SDimitry Andric // Emit target-specific gunk after the function body. 19415ffd83dbSDimitry Andric emitFunctionBodyEnd(); 19420b57cec5SDimitry Andric 1943bdd1243dSDimitry Andric // Even though wasm supports .type and .size in general, function symbols 1944bdd1243dSDimitry Andric // are automatically sized. 1945bdd1243dSDimitry Andric bool EmitFunctionSize = MAI->hasDotTypeDotSizeDirective() && !TT.isWasm(); 1946bdd1243dSDimitry Andric 1947*0fca6ea1SDimitry Andric if (needFuncLabels(*MF, *MMI) || EmitFunctionSize) { 19480b57cec5SDimitry Andric // Create a symbol for the end of function. 19490b57cec5SDimitry Andric CurrentFnEnd = createTempSymbol("func_end"); 19505ffd83dbSDimitry Andric OutStreamer->emitLabel(CurrentFnEnd); 19510b57cec5SDimitry Andric } 19520b57cec5SDimitry Andric 19530b57cec5SDimitry Andric // If the target wants a .size directive for the size of the function, emit 19540b57cec5SDimitry Andric // it. 1955bdd1243dSDimitry Andric if (EmitFunctionSize) { 19560b57cec5SDimitry Andric // We can get the size as difference between the function label and the 19570b57cec5SDimitry Andric // temp label. 19580b57cec5SDimitry Andric const MCExpr *SizeExp = MCBinaryExpr::createSub( 19590b57cec5SDimitry Andric MCSymbolRefExpr::create(CurrentFnEnd, OutContext), 19600b57cec5SDimitry Andric MCSymbolRefExpr::create(CurrentFnSymForSize, OutContext), OutContext); 19610b57cec5SDimitry Andric OutStreamer->emitELFSize(CurrentFnSym, SizeExp); 1962bdd1243dSDimitry Andric if (CurrentFnBeginLocal) 1963bdd1243dSDimitry Andric OutStreamer->emitELFSize(CurrentFnBeginLocal, SizeExp); 19640b57cec5SDimitry Andric } 19650b57cec5SDimitry Andric 1966bdd1243dSDimitry Andric // Call endBasicBlockSection on the last block now, if it wasn't already 1967bdd1243dSDimitry Andric // called. 1968bdd1243dSDimitry Andric if (!MF->back().isEndSection()) { 1969*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 1970*0fca6ea1SDimitry Andric Handler->endBasicBlockSection(MF->back()); 1971*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 1972*0fca6ea1SDimitry Andric Handler->endBasicBlockSection(MF->back()); 1973bdd1243dSDimitry Andric } 1974*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 1975*0fca6ea1SDimitry Andric Handler->markFunctionEnd(); 19760b57cec5SDimitry Andric 1977*0fca6ea1SDimitry Andric assert(!MBBSectionRanges.contains(MF->front().getSectionID()) && 1978*0fca6ea1SDimitry Andric "Overwrite section range"); 1979*0fca6ea1SDimitry Andric MBBSectionRanges[MF->front().getSectionID()] = 19805ffd83dbSDimitry Andric MBBSectionRange{CurrentFnBegin, CurrentFnEnd}; 19815ffd83dbSDimitry Andric 19820b57cec5SDimitry Andric // Print out jump tables referenced by the function. 19835ffd83dbSDimitry Andric emitJumpTableInfo(); 19840b57cec5SDimitry Andric 19850b57cec5SDimitry Andric // Emit post-function debug and/or EH information. 1986*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 1987*0fca6ea1SDimitry Andric Handler->endFunction(MF); 1988*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 1989*0fca6ea1SDimitry Andric Handler->endFunction(MF); 19900b57cec5SDimitry Andric 1991e8d8bef9SDimitry Andric // Emit section containing BB address offsets and their metadata, when 1992fe6060f1SDimitry Andric // BB labels are requested for this function. Skip empty functions. 19931db9f3b2SDimitry Andric if (HasAnyRealCode) { 1994*0fca6ea1SDimitry Andric if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap) 1995e8d8bef9SDimitry Andric emitBBAddrMapSection(*MF); 19961db9f3b2SDimitry Andric else if (PgoAnalysisMapFeatures.getBits() != 0) 19971db9f3b2SDimitry Andric MF->getContext().reportWarning( 19981db9f3b2SDimitry Andric SMLoc(), "pgo-analysis-map is enabled for function " + MF->getName() + 19991db9f3b2SDimitry Andric " but it does not have labels"); 20001db9f3b2SDimitry Andric } 2001e8d8bef9SDimitry Andric 2002bdd1243dSDimitry Andric // Emit sections containing instruction and function PCs. 2003bdd1243dSDimitry Andric emitPCSections(*MF); 2004bdd1243dSDimitry Andric 20050b57cec5SDimitry Andric // Emit section containing stack size metadata. 20060b57cec5SDimitry Andric emitStackSizeSection(*MF); 20070b57cec5SDimitry Andric 2008fe6060f1SDimitry Andric // Emit .su file containing function stack size information. 2009fe6060f1SDimitry Andric emitStackUsage(*MF); 2010fe6060f1SDimitry Andric 2011480093f4SDimitry Andric emitPatchableFunctionEntries(); 2012480093f4SDimitry Andric 20130b57cec5SDimitry Andric if (isVerbose()) 201481ad6265SDimitry Andric OutStreamer->getCommentOS() << "-- End function\n"; 20150b57cec5SDimitry Andric 201681ad6265SDimitry Andric OutStreamer->addBlankLine(); 20170b57cec5SDimitry Andric } 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric /// Compute the number of Global Variables that uses a Constant. 20200b57cec5SDimitry Andric static unsigned getNumGlobalVariableUses(const Constant *C) { 20210b57cec5SDimitry Andric if (!C) 20220b57cec5SDimitry Andric return 0; 20230b57cec5SDimitry Andric 20240b57cec5SDimitry Andric if (isa<GlobalVariable>(C)) 20250b57cec5SDimitry Andric return 1; 20260b57cec5SDimitry Andric 20270b57cec5SDimitry Andric unsigned NumUses = 0; 2028fcaf7f86SDimitry Andric for (const auto *CU : C->users()) 20290b57cec5SDimitry Andric NumUses += getNumGlobalVariableUses(dyn_cast<Constant>(CU)); 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andric return NumUses; 20320b57cec5SDimitry Andric } 20330b57cec5SDimitry Andric 20340b57cec5SDimitry Andric /// Only consider global GOT equivalents if at least one user is a 20350b57cec5SDimitry Andric /// cstexpr inside an initializer of another global variables. Also, don't 20360b57cec5SDimitry Andric /// handle cstexpr inside instructions. During global variable emission, 20370b57cec5SDimitry Andric /// candidates are skipped and are emitted later in case at least one cstexpr 20380b57cec5SDimitry Andric /// isn't replaced by a PC relative GOT entry access. 20390b57cec5SDimitry Andric static bool isGOTEquivalentCandidate(const GlobalVariable *GV, 20400b57cec5SDimitry Andric unsigned &NumGOTEquivUsers) { 20410b57cec5SDimitry Andric // Global GOT equivalents are unnamed private globals with a constant 20420b57cec5SDimitry Andric // pointer initializer to another global symbol. They must point to a 20430b57cec5SDimitry Andric // GlobalVariable or Function, i.e., as GlobalValue. 20440b57cec5SDimitry Andric if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || 20450b57cec5SDimitry Andric !GV->isConstant() || !GV->isDiscardableIfUnused() || 20460b57cec5SDimitry Andric !isa<GlobalValue>(GV->getOperand(0))) 20470b57cec5SDimitry Andric return false; 20480b57cec5SDimitry Andric 20490b57cec5SDimitry Andric // To be a got equivalent, at least one of its users need to be a constant 20500b57cec5SDimitry Andric // expression used by another global variable. 2051fcaf7f86SDimitry Andric for (const auto *U : GV->users()) 20520b57cec5SDimitry Andric NumGOTEquivUsers += getNumGlobalVariableUses(dyn_cast<Constant>(U)); 20530b57cec5SDimitry Andric 20540b57cec5SDimitry Andric return NumGOTEquivUsers > 0; 20550b57cec5SDimitry Andric } 20560b57cec5SDimitry Andric 20570b57cec5SDimitry Andric /// Unnamed constant global variables solely contaning a pointer to 20580b57cec5SDimitry Andric /// another globals variable is equivalent to a GOT table entry; it contains the 20590b57cec5SDimitry Andric /// the address of another symbol. Optimize it and replace accesses to these 20600b57cec5SDimitry Andric /// "GOT equivalents" by using the GOT entry for the final global instead. 20610b57cec5SDimitry Andric /// Compute GOT equivalent candidates among all global variables to avoid 20620b57cec5SDimitry Andric /// emitting them if possible later on, after it use is replaced by a GOT entry 20630b57cec5SDimitry Andric /// access. 20640b57cec5SDimitry Andric void AsmPrinter::computeGlobalGOTEquivs(Module &M) { 20650b57cec5SDimitry Andric if (!getObjFileLowering().supportIndirectSymViaGOTPCRel()) 20660b57cec5SDimitry Andric return; 20670b57cec5SDimitry Andric 20680b57cec5SDimitry Andric for (const auto &G : M.globals()) { 20690b57cec5SDimitry Andric unsigned NumGOTEquivUsers = 0; 20700b57cec5SDimitry Andric if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers)) 20710b57cec5SDimitry Andric continue; 20720b57cec5SDimitry Andric 20730b57cec5SDimitry Andric const MCSymbol *GOTEquivSym = getSymbol(&G); 20740b57cec5SDimitry Andric GlobalGOTEquivs[GOTEquivSym] = std::make_pair(&G, NumGOTEquivUsers); 20750b57cec5SDimitry Andric } 20760b57cec5SDimitry Andric } 20770b57cec5SDimitry Andric 20780b57cec5SDimitry Andric /// Constant expressions using GOT equivalent globals may not be eligible 20790b57cec5SDimitry Andric /// for PC relative GOT entry conversion, in such cases we need to emit such 20800b57cec5SDimitry Andric /// globals we previously omitted in EmitGlobalVariable. 20810b57cec5SDimitry Andric void AsmPrinter::emitGlobalGOTEquivs() { 20820b57cec5SDimitry Andric if (!getObjFileLowering().supportIndirectSymViaGOTPCRel()) 20830b57cec5SDimitry Andric return; 20840b57cec5SDimitry Andric 20850b57cec5SDimitry Andric SmallVector<const GlobalVariable *, 8> FailedCandidates; 20860b57cec5SDimitry Andric for (auto &I : GlobalGOTEquivs) { 20870b57cec5SDimitry Andric const GlobalVariable *GV = I.second.first; 20880b57cec5SDimitry Andric unsigned Cnt = I.second.second; 20890b57cec5SDimitry Andric if (Cnt) 20900b57cec5SDimitry Andric FailedCandidates.push_back(GV); 20910b57cec5SDimitry Andric } 20920b57cec5SDimitry Andric GlobalGOTEquivs.clear(); 20930b57cec5SDimitry Andric 2094fcaf7f86SDimitry Andric for (const auto *GV : FailedCandidates) 20955ffd83dbSDimitry Andric emitGlobalVariable(GV); 20960b57cec5SDimitry Andric } 20970b57cec5SDimitry Andric 2098*0fca6ea1SDimitry Andric void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) { 2099349cc55cSDimitry Andric MCSymbol *Name = getSymbol(&GA); 2100349cc55cSDimitry Andric bool IsFunction = GA.getValueType()->isFunctionTy(); 21010b57cec5SDimitry Andric // Treat bitcasts of functions as functions also. This is important at least 21020b57cec5SDimitry Andric // on WebAssembly where object and function addresses can't alias each other. 21030b57cec5SDimitry Andric if (!IsFunction) 210481ad6265SDimitry Andric IsFunction = isa<Function>(GA.getAliasee()->stripPointerCasts()); 21050b57cec5SDimitry Andric 2106e8d8bef9SDimitry Andric // AIX's assembly directive `.set` is not usable for aliasing purpose, 2107e8d8bef9SDimitry Andric // so AIX has to use the extra-label-at-definition strategy. At this 2108e8d8bef9SDimitry Andric // point, all the extra label is emitted, we just have to emit linkage for 2109e8d8bef9SDimitry Andric // those labels. 2110e8d8bef9SDimitry Andric if (TM.getTargetTriple().isOSBinFormatXCOFF()) { 2111e8d8bef9SDimitry Andric assert(MAI->hasVisibilityOnlyWithLinkage() && 2112e8d8bef9SDimitry Andric "Visibility should be handled with emitLinkage() on AIX."); 2113753f127fSDimitry Andric 2114753f127fSDimitry Andric // Linkage for alias of global variable has been emitted. 2115753f127fSDimitry Andric if (isa<GlobalVariable>(GA.getAliaseeObject())) 2116753f127fSDimitry Andric return; 2117753f127fSDimitry Andric 2118349cc55cSDimitry Andric emitLinkage(&GA, Name); 2119e8d8bef9SDimitry Andric // If it's a function, also emit linkage for aliases of function entry 2120e8d8bef9SDimitry Andric // point. 2121e8d8bef9SDimitry Andric if (IsFunction) 2122349cc55cSDimitry Andric emitLinkage(&GA, 2123349cc55cSDimitry Andric getObjFileLowering().getFunctionEntryPointSymbol(&GA, TM)); 2124e8d8bef9SDimitry Andric return; 2125e8d8bef9SDimitry Andric } 2126e8d8bef9SDimitry Andric 2127349cc55cSDimitry Andric if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective()) 2128e8d8bef9SDimitry Andric OutStreamer->emitSymbolAttribute(Name, MCSA_Global); 2129349cc55cSDimitry Andric else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage()) 2130e8d8bef9SDimitry Andric OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference); 2131e8d8bef9SDimitry Andric else 2132349cc55cSDimitry Andric assert(GA.hasLocalLinkage() && "Invalid alias linkage"); 2133e8d8bef9SDimitry Andric 21340b57cec5SDimitry Andric // Set the symbol type to function if the alias has a function type. 21350b57cec5SDimitry Andric // This affects codegen when the aliasee is not a function. 21361fd87a68SDimitry Andric if (IsFunction) { 2137349cc55cSDimitry Andric OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction); 21381fd87a68SDimitry Andric if (TM.getTargetTriple().isOSBinFormatCOFF()) { 213981ad6265SDimitry Andric OutStreamer->beginCOFFSymbolDef(Name); 214081ad6265SDimitry Andric OutStreamer->emitCOFFSymbolStorageClass( 21411fd87a68SDimitry Andric GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC 21421fd87a68SDimitry Andric : COFF::IMAGE_SYM_CLASS_EXTERNAL); 214381ad6265SDimitry Andric OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 21441fd87a68SDimitry Andric << COFF::SCT_COMPLEX_TYPE_SHIFT); 214581ad6265SDimitry Andric OutStreamer->endCOFFSymbolDef(); 21461fd87a68SDimitry Andric } 21471fd87a68SDimitry Andric } 21480b57cec5SDimitry Andric 2149349cc55cSDimitry Andric emitVisibility(Name, GA.getVisibility()); 21500b57cec5SDimitry Andric 2151349cc55cSDimitry Andric const MCExpr *Expr = lowerConstant(GA.getAliasee()); 21520b57cec5SDimitry Andric 2153349cc55cSDimitry Andric if (MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr)) 21545ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(Name, MCSA_AltEntry); 21550b57cec5SDimitry Andric 21560b57cec5SDimitry Andric // Emit the directives as assignments aka .set: 21575ffd83dbSDimitry Andric OutStreamer->emitAssignment(Name, Expr); 2158349cc55cSDimitry Andric MCSymbol *LocalAlias = getSymbolPreferLocal(GA); 21595ffd83dbSDimitry Andric if (LocalAlias != Name) 21605ffd83dbSDimitry Andric OutStreamer->emitAssignment(LocalAlias, Expr); 21610b57cec5SDimitry Andric 21620b57cec5SDimitry Andric // If the aliasee does not correspond to a symbol in the output, i.e. the 21630b57cec5SDimitry Andric // alias is not of an object or the aliased object is private, then set the 21640b57cec5SDimitry Andric // size of the alias symbol from the type of the alias. We don't do this in 21650b57cec5SDimitry Andric // other situations as the alias and aliasee having differing types but same 21660b57cec5SDimitry Andric // size may be intentional. 2167349cc55cSDimitry Andric const GlobalObject *BaseObject = GA.getAliaseeObject(); 2168349cc55cSDimitry Andric if (MAI->hasDotTypeDotSizeDirective() && GA.getValueType()->isSized() && 21690b57cec5SDimitry Andric (!BaseObject || BaseObject->hasPrivateLinkage())) { 21700b57cec5SDimitry Andric const DataLayout &DL = M.getDataLayout(); 2171349cc55cSDimitry Andric uint64_t Size = DL.getTypeAllocSize(GA.getValueType()); 21720b57cec5SDimitry Andric OutStreamer->emitELFSize(Name, MCConstantExpr::create(Size, OutContext)); 21730b57cec5SDimitry Andric } 21740b57cec5SDimitry Andric } 2175349cc55cSDimitry Andric 2176349cc55cSDimitry Andric void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) { 2177349cc55cSDimitry Andric assert(!TM.getTargetTriple().isOSBinFormatXCOFF() && 2178349cc55cSDimitry Andric "IFunc is not supported on AIX."); 2179349cc55cSDimitry Andric 21805f757f3fSDimitry Andric auto EmitLinkage = [&](MCSymbol *Sym) { 2181349cc55cSDimitry Andric if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) 21825f757f3fSDimitry Andric OutStreamer->emitSymbolAttribute(Sym, MCSA_Global); 2183349cc55cSDimitry Andric else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) 21845f757f3fSDimitry Andric OutStreamer->emitSymbolAttribute(Sym, MCSA_WeakReference); 2185349cc55cSDimitry Andric else 2186349cc55cSDimitry Andric assert(GI.hasLocalLinkage() && "Invalid ifunc linkage"); 21875f757f3fSDimitry Andric }; 2188349cc55cSDimitry Andric 21895f757f3fSDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF()) { 21905f757f3fSDimitry Andric MCSymbol *Name = getSymbol(&GI); 21915f757f3fSDimitry Andric EmitLinkage(Name); 2192349cc55cSDimitry Andric OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction); 2193349cc55cSDimitry Andric emitVisibility(Name, GI.getVisibility()); 2194349cc55cSDimitry Andric 2195349cc55cSDimitry Andric // Emit the directives as assignments aka .set: 2196349cc55cSDimitry Andric const MCExpr *Expr = lowerConstant(GI.getResolver()); 2197349cc55cSDimitry Andric OutStreamer->emitAssignment(Name, Expr); 2198349cc55cSDimitry Andric MCSymbol *LocalAlias = getSymbolPreferLocal(GI); 2199349cc55cSDimitry Andric if (LocalAlias != Name) 2200349cc55cSDimitry Andric OutStreamer->emitAssignment(LocalAlias, Expr); 22015f757f3fSDimitry Andric 22025f757f3fSDimitry Andric return; 22035f757f3fSDimitry Andric } 22045f757f3fSDimitry Andric 22055f757f3fSDimitry Andric if (!TM.getTargetTriple().isOSBinFormatMachO() || !getIFuncMCSubtargetInfo()) 22065f757f3fSDimitry Andric llvm::report_fatal_error("IFuncs are not supported on this platform"); 22075f757f3fSDimitry Andric 22085f757f3fSDimitry Andric // On Darwin platforms, emit a manually-constructed .symbol_resolver that 22095f757f3fSDimitry Andric // implements the symbol resolution duties of the IFunc. 22105f757f3fSDimitry Andric // 22115f757f3fSDimitry Andric // Normally, this would be handled by linker magic, but unfortunately there 22125f757f3fSDimitry Andric // are a few limitations in ld64 and ld-prime's implementation of 22135f757f3fSDimitry Andric // .symbol_resolver that mean we can't always use them: 22145f757f3fSDimitry Andric // 22155f757f3fSDimitry Andric // * resolvers cannot be the target of an alias 22165f757f3fSDimitry Andric // * resolvers cannot have private linkage 22175f757f3fSDimitry Andric // * resolvers cannot have linkonce linkage 22185f757f3fSDimitry Andric // * resolvers cannot appear in executables 22195f757f3fSDimitry Andric // * resolvers cannot appear in bundles 22205f757f3fSDimitry Andric // 22215f757f3fSDimitry Andric // This works around that by emitting a close approximation of what the 22225f757f3fSDimitry Andric // linker would have done. 22235f757f3fSDimitry Andric 22245f757f3fSDimitry Andric MCSymbol *LazyPointer = 22255f757f3fSDimitry Andric GetExternalSymbolSymbol(GI.getName() + ".lazy_pointer"); 22265f757f3fSDimitry Andric MCSymbol *StubHelper = GetExternalSymbolSymbol(GI.getName() + ".stub_helper"); 22275f757f3fSDimitry Andric 22285f757f3fSDimitry Andric OutStreamer->switchSection(OutContext.getObjectFileInfo()->getDataSection()); 22295f757f3fSDimitry Andric 22305f757f3fSDimitry Andric const DataLayout &DL = M.getDataLayout(); 22315f757f3fSDimitry Andric emitAlignment(Align(DL.getPointerSize())); 22325f757f3fSDimitry Andric OutStreamer->emitLabel(LazyPointer); 22335f757f3fSDimitry Andric emitVisibility(LazyPointer, GI.getVisibility()); 22345f757f3fSDimitry Andric OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8); 22355f757f3fSDimitry Andric 22365f757f3fSDimitry Andric OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection()); 22375f757f3fSDimitry Andric 22385f757f3fSDimitry Andric const TargetSubtargetInfo *STI = 22395f757f3fSDimitry Andric TM.getSubtargetImpl(*GI.getResolverFunction()); 22405f757f3fSDimitry Andric const TargetLowering *TLI = STI->getTargetLowering(); 22415f757f3fSDimitry Andric Align TextAlign(TLI->getMinFunctionAlignment()); 22425f757f3fSDimitry Andric 22435f757f3fSDimitry Andric MCSymbol *Stub = getSymbol(&GI); 22445f757f3fSDimitry Andric EmitLinkage(Stub); 22455f757f3fSDimitry Andric OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo()); 22465f757f3fSDimitry Andric OutStreamer->emitLabel(Stub); 22475f757f3fSDimitry Andric emitVisibility(Stub, GI.getVisibility()); 22485f757f3fSDimitry Andric emitMachOIFuncStubBody(M, GI, LazyPointer); 22495f757f3fSDimitry Andric 22505f757f3fSDimitry Andric OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo()); 22515f757f3fSDimitry Andric OutStreamer->emitLabel(StubHelper); 22525f757f3fSDimitry Andric emitVisibility(StubHelper, GI.getVisibility()); 22535f757f3fSDimitry Andric emitMachOIFuncStubHelperBody(M, GI, LazyPointer); 22540b57cec5SDimitry Andric } 22550b57cec5SDimitry Andric 22565ffd83dbSDimitry Andric void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) { 2257480093f4SDimitry Andric if (!RS.needsSection()) 22580b57cec5SDimitry Andric return; 2259480093f4SDimitry Andric 2260480093f4SDimitry Andric remarks::RemarkSerializer &RemarkSerializer = RS.getSerializer(); 22618bcb0991SDimitry Andric 2262bdd1243dSDimitry Andric std::optional<SmallString<128>> Filename; 2263bdd1243dSDimitry Andric if (std::optional<StringRef> FilenameRef = RS.getFilename()) { 22648bcb0991SDimitry Andric Filename = *FilenameRef; 22658bcb0991SDimitry Andric sys::fs::make_absolute(*Filename); 22668bcb0991SDimitry Andric assert(!Filename->empty() && "The filename can't be empty."); 22678bcb0991SDimitry Andric } 22688bcb0991SDimitry Andric 22698bcb0991SDimitry Andric std::string Buf; 22708bcb0991SDimitry Andric raw_string_ostream OS(Buf); 22718bcb0991SDimitry Andric std::unique_ptr<remarks::MetaSerializer> MetaSerializer = 2272fe6060f1SDimitry Andric Filename ? RemarkSerializer.metaSerializer(OS, Filename->str()) 22738bcb0991SDimitry Andric : RemarkSerializer.metaSerializer(OS); 22748bcb0991SDimitry Andric MetaSerializer->emit(); 22750b57cec5SDimitry Andric 2276480093f4SDimitry Andric // Switch to the remarks section. 22770b57cec5SDimitry Andric MCSection *RemarksSection = 22780b57cec5SDimitry Andric OutContext.getObjectFileInfo()->getRemarksSection(); 227981ad6265SDimitry Andric OutStreamer->switchSection(RemarksSection); 22800b57cec5SDimitry Andric 2281*0fca6ea1SDimitry Andric OutStreamer->emitBinaryData(Buf); 22820b57cec5SDimitry Andric } 22830b57cec5SDimitry Andric 22840b57cec5SDimitry Andric bool AsmPrinter::doFinalization(Module &M) { 22850b57cec5SDimitry Andric // Set the MachineFunction to nullptr so that we can catch attempted 22860b57cec5SDimitry Andric // accesses to MF specific features at the module level and so that 22870b57cec5SDimitry Andric // we can conditionalize accesses based on whether or not it is nullptr. 22880b57cec5SDimitry Andric MF = nullptr; 22890b57cec5SDimitry Andric 22900b57cec5SDimitry Andric // Gather all GOT equivalent globals in the module. We really need two 22910b57cec5SDimitry Andric // passes over the globals: one to compute and another to avoid its emission 22920b57cec5SDimitry Andric // in EmitGlobalVariable, otherwise we would not be able to handle cases 22930b57cec5SDimitry Andric // where the got equivalent shows up before its use. 22940b57cec5SDimitry Andric computeGlobalGOTEquivs(M); 22950b57cec5SDimitry Andric 22960b57cec5SDimitry Andric // Emit global variables. 22970b57cec5SDimitry Andric for (const auto &G : M.globals()) 22985ffd83dbSDimitry Andric emitGlobalVariable(&G); 22990b57cec5SDimitry Andric 23000b57cec5SDimitry Andric // Emit remaining GOT equivalent globals. 23010b57cec5SDimitry Andric emitGlobalGOTEquivs(); 23020b57cec5SDimitry Andric 23035ffd83dbSDimitry Andric const TargetLoweringObjectFile &TLOF = getObjFileLowering(); 23045ffd83dbSDimitry Andric 23055ffd83dbSDimitry Andric // Emit linkage(XCOFF) and visibility info for declarations 23060b57cec5SDimitry Andric for (const Function &F : M) { 23070b57cec5SDimitry Andric if (!F.isDeclarationForLinker()) 23080b57cec5SDimitry Andric continue; 23095ffd83dbSDimitry Andric 23105ffd83dbSDimitry Andric MCSymbol *Name = getSymbol(&F); 23115ffd83dbSDimitry Andric // Function getSymbol gives us the function descriptor symbol for XCOFF. 23125ffd83dbSDimitry Andric 23135ffd83dbSDimitry Andric if (!TM.getTargetTriple().isOSBinFormatXCOFF()) { 23140b57cec5SDimitry Andric GlobalValue::VisibilityTypes V = F.getVisibility(); 23150b57cec5SDimitry Andric if (V == GlobalValue::DefaultVisibility) 23160b57cec5SDimitry Andric continue; 23170b57cec5SDimitry Andric 23185ffd83dbSDimitry Andric emitVisibility(Name, V, false); 23195ffd83dbSDimitry Andric continue; 23205ffd83dbSDimitry Andric } 23215ffd83dbSDimitry Andric 23225ffd83dbSDimitry Andric if (F.isIntrinsic()) 23235ffd83dbSDimitry Andric continue; 23245ffd83dbSDimitry Andric 23255ffd83dbSDimitry Andric // Handle the XCOFF case. 23265ffd83dbSDimitry Andric // Variable `Name` is the function descriptor symbol (see above). Get the 23275ffd83dbSDimitry Andric // function entry point symbol. 23285ffd83dbSDimitry Andric MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM); 23295ffd83dbSDimitry Andric // Emit linkage for the function entry point. 23305ffd83dbSDimitry Andric emitLinkage(&F, FnEntryPointSym); 23315ffd83dbSDimitry Andric 2332*0fca6ea1SDimitry Andric // If a function's address is taken, which means it may be called via a 2333*0fca6ea1SDimitry Andric // function pointer, we need the function descriptor for it. 2334*0fca6ea1SDimitry Andric if (F.hasAddressTaken()) 23355ffd83dbSDimitry Andric emitLinkage(&F, Name); 23360b57cec5SDimitry Andric } 23370b57cec5SDimitry Andric 23380b57cec5SDimitry Andric // Emit the remarks section contents. 23390b57cec5SDimitry Andric // FIXME: Figure out when is the safest time to emit this section. It should 23400b57cec5SDimitry Andric // not come after debug info. 23415ffd83dbSDimitry Andric if (remarks::RemarkStreamer *RS = M.getContext().getMainRemarkStreamer()) 2342480093f4SDimitry Andric emitRemarksSection(*RS); 23430b57cec5SDimitry Andric 23440b57cec5SDimitry Andric TLOF.emitModuleMetadata(*OutStreamer, M); 23450b57cec5SDimitry Andric 23460b57cec5SDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF()) { 23470b57cec5SDimitry Andric MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 23480b57cec5SDimitry Andric 23490b57cec5SDimitry Andric // Output stubs for external and common global variables. 23500b57cec5SDimitry Andric MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 23510b57cec5SDimitry Andric if (!Stubs.empty()) { 235281ad6265SDimitry Andric OutStreamer->switchSection(TLOF.getDataSection()); 23530b57cec5SDimitry Andric const DataLayout &DL = M.getDataLayout(); 23540b57cec5SDimitry Andric 23555ffd83dbSDimitry Andric emitAlignment(Align(DL.getPointerSize())); 23560b57cec5SDimitry Andric for (const auto &Stub : Stubs) { 23575ffd83dbSDimitry Andric OutStreamer->emitLabel(Stub.first); 23585ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(Stub.second.getPointer(), 23590b57cec5SDimitry Andric DL.getPointerSize()); 23600b57cec5SDimitry Andric } 23610b57cec5SDimitry Andric } 23620b57cec5SDimitry Andric } 23630b57cec5SDimitry Andric 23640b57cec5SDimitry Andric if (TM.getTargetTriple().isOSBinFormatCOFF()) { 23650b57cec5SDimitry Andric MachineModuleInfoCOFF &MMICOFF = 23660b57cec5SDimitry Andric MMI->getObjFileInfo<MachineModuleInfoCOFF>(); 23670b57cec5SDimitry Andric 23680b57cec5SDimitry Andric // Output stubs for external and common global variables. 23690b57cec5SDimitry Andric MachineModuleInfoCOFF::SymbolListTy Stubs = MMICOFF.GetGVStubList(); 23700b57cec5SDimitry Andric if (!Stubs.empty()) { 23710b57cec5SDimitry Andric const DataLayout &DL = M.getDataLayout(); 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric for (const auto &Stub : Stubs) { 23740b57cec5SDimitry Andric SmallString<256> SectionName = StringRef(".rdata$"); 23750b57cec5SDimitry Andric SectionName += Stub.first->getName(); 237681ad6265SDimitry Andric OutStreamer->switchSection(OutContext.getCOFFSection( 23770b57cec5SDimitry Andric SectionName, 23780b57cec5SDimitry Andric COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | 23790b57cec5SDimitry Andric COFF::IMAGE_SCN_LNK_COMDAT, 2380*0fca6ea1SDimitry Andric Stub.first->getName(), COFF::IMAGE_COMDAT_SELECT_ANY)); 23815ffd83dbSDimitry Andric emitAlignment(Align(DL.getPointerSize())); 23825ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(Stub.first, MCSA_Global); 23835ffd83dbSDimitry Andric OutStreamer->emitLabel(Stub.first); 23845ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(Stub.second.getPointer(), 23850b57cec5SDimitry Andric DL.getPointerSize()); 23860b57cec5SDimitry Andric } 23870b57cec5SDimitry Andric } 23880b57cec5SDimitry Andric } 23890b57cec5SDimitry Andric 2390349cc55cSDimitry Andric // This needs to happen before emitting debug information since that can end 2391349cc55cSDimitry Andric // arbitrary sections. 2392349cc55cSDimitry Andric if (auto *TS = OutStreamer->getTargetStreamer()) 2393349cc55cSDimitry Andric TS->emitConstantPools(); 2394349cc55cSDimitry Andric 2395bdd1243dSDimitry Andric // Emit Stack maps before any debug info. Mach-O requires that no data or 2396bdd1243dSDimitry Andric // text sections come after debug info has been emitted. This matters for 2397bdd1243dSDimitry Andric // stack maps as they are arbitrary data, and may even have a custom format 2398bdd1243dSDimitry Andric // through user plugins. 2399bdd1243dSDimitry Andric emitStackMaps(); 2400bdd1243dSDimitry Andric 24015f757f3fSDimitry Andric // Print aliases in topological order, that is, for each alias a = b, 24025f757f3fSDimitry Andric // b must be printed before a. 24035f757f3fSDimitry Andric // This is because on some targets (e.g. PowerPC) linker expects aliases in 24045f757f3fSDimitry Andric // such an order to generate correct TOC information. 24055f757f3fSDimitry Andric SmallVector<const GlobalAlias *, 16> AliasStack; 24065f757f3fSDimitry Andric SmallPtrSet<const GlobalAlias *, 16> AliasVisited; 24075f757f3fSDimitry Andric for (const auto &Alias : M.aliases()) { 24085f757f3fSDimitry Andric if (Alias.hasAvailableExternallyLinkage()) 24095f757f3fSDimitry Andric continue; 24105f757f3fSDimitry Andric for (const GlobalAlias *Cur = &Alias; Cur; 24115f757f3fSDimitry Andric Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) { 24125f757f3fSDimitry Andric if (!AliasVisited.insert(Cur).second) 24135f757f3fSDimitry Andric break; 24145f757f3fSDimitry Andric AliasStack.push_back(Cur); 24155f757f3fSDimitry Andric } 24165f757f3fSDimitry Andric for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack)) 24175f757f3fSDimitry Andric emitGlobalAlias(M, *AncestorAlias); 24185f757f3fSDimitry Andric AliasStack.clear(); 24195f757f3fSDimitry Andric } 24205f757f3fSDimitry Andric 24215f757f3fSDimitry Andric // IFuncs must come before deubginfo in case the backend decides to emit them 24225f757f3fSDimitry Andric // as actual functions, since on Mach-O targets, we cannot create regular 24235f757f3fSDimitry Andric // sections after DWARF. 24245f757f3fSDimitry Andric for (const auto &IFunc : M.ifuncs()) 24255f757f3fSDimitry Andric emitGlobalIFunc(M, IFunc); 24265f757f3fSDimitry Andric 24270b57cec5SDimitry Andric // Finalize debug and EH information. 2428*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 2429*0fca6ea1SDimitry Andric Handler->endModule(); 2430*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 2431*0fca6ea1SDimitry Andric Handler->endModule(); 2432e8d8bef9SDimitry Andric 2433e8d8bef9SDimitry Andric // This deletes all the ephemeral handlers that AsmPrinter added, while 2434e8d8bef9SDimitry Andric // keeping all the user-added handlers alive until the AsmPrinter is 2435e8d8bef9SDimitry Andric // destroyed. 2436e8d8bef9SDimitry Andric Handlers.erase(Handlers.begin() + NumUserHandlers, Handlers.end()); 2437*0fca6ea1SDimitry Andric DebugHandlers.erase(DebugHandlers.begin() + NumUserDebugHandlers, 2438*0fca6ea1SDimitry Andric DebugHandlers.end()); 24390b57cec5SDimitry Andric DD = nullptr; 24400b57cec5SDimitry Andric 24410b57cec5SDimitry Andric // If the target wants to know about weak references, print them all. 24420b57cec5SDimitry Andric if (MAI->getWeakRefDirective()) { 24430b57cec5SDimitry Andric // FIXME: This is not lazy, it would be nice to only print weak references 24440b57cec5SDimitry Andric // to stuff that is actually used. Note that doing so would require targets 24450b57cec5SDimitry Andric // to notice uses in operands (due to constant exprs etc). This should 24460b57cec5SDimitry Andric // happen with the MC stuff eventually. 24470b57cec5SDimitry Andric 24480b57cec5SDimitry Andric // Print out module-level global objects here. 24490b57cec5SDimitry Andric for (const auto &GO : M.global_objects()) { 24500b57cec5SDimitry Andric if (!GO.hasExternalWeakLinkage()) 24510b57cec5SDimitry Andric continue; 24525ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference); 24530b57cec5SDimitry Andric } 24540eae32dcSDimitry Andric if (shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()) { 24550eae32dcSDimitry Andric auto SymbolName = "swift_async_extendedFramePointerFlags"; 24560eae32dcSDimitry Andric auto Global = M.getGlobalVariable(SymbolName); 24570eae32dcSDimitry Andric if (!Global) { 24585f757f3fSDimitry Andric auto Int8PtrTy = PointerType::getUnqual(M.getContext()); 24590eae32dcSDimitry Andric Global = new GlobalVariable(M, Int8PtrTy, false, 24600eae32dcSDimitry Andric GlobalValue::ExternalWeakLinkage, nullptr, 24610eae32dcSDimitry Andric SymbolName); 24620eae32dcSDimitry Andric OutStreamer->emitSymbolAttribute(getSymbol(Global), MCSA_WeakReference); 24630eae32dcSDimitry Andric } 24640eae32dcSDimitry Andric } 24650b57cec5SDimitry Andric } 24660b57cec5SDimitry Andric 24670b57cec5SDimitry Andric GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 24680b57cec5SDimitry Andric assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 24690b57cec5SDimitry Andric for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) 2470bdd1243dSDimitry Andric if (GCMetadataPrinter *MP = getOrCreateGCPrinter(**--I)) 24710b57cec5SDimitry Andric MP->finishAssembly(M, *MI, *this); 24720b57cec5SDimitry Andric 24730b57cec5SDimitry Andric // Emit llvm.ident metadata in an '.ident' directive. 24745ffd83dbSDimitry Andric emitModuleIdents(M); 24750b57cec5SDimitry Andric 24760b57cec5SDimitry Andric // Emit bytes for llvm.commandline metadata. 247706c3fb27SDimitry Andric // The command line metadata is emitted earlier on XCOFF. 247806c3fb27SDimitry Andric if (!TM.getTargetTriple().isOSBinFormatXCOFF()) 24795ffd83dbSDimitry Andric emitModuleCommandLines(M); 24800b57cec5SDimitry Andric 24810b57cec5SDimitry Andric // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if 24820b57cec5SDimitry Andric // split-stack is used. 248381ad6265SDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) { 248481ad6265SDimitry Andric OutStreamer->switchSection(OutContext.getELFSection(".note.GNU-split-stack", 248581ad6265SDimitry Andric ELF::SHT_PROGBITS, 0)); 248681ad6265SDimitry Andric if (HasNoSplitStack) 248781ad6265SDimitry Andric OutStreamer->switchSection(OutContext.getELFSection( 248881ad6265SDimitry Andric ".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0)); 24890b57cec5SDimitry Andric } 24900b57cec5SDimitry Andric 24910b57cec5SDimitry Andric // If we don't have any trampolines, then we don't require stack memory 24920b57cec5SDimitry Andric // to be executable. Some targets have a directive to declare this. 24930b57cec5SDimitry Andric Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); 24940b57cec5SDimitry Andric if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) 24950b57cec5SDimitry Andric if (MCSection *S = MAI->getNonexecutableStackSection(OutContext)) 249681ad6265SDimitry Andric OutStreamer->switchSection(S); 24970b57cec5SDimitry Andric 24980b57cec5SDimitry Andric if (TM.Options.EmitAddrsig) { 24990b57cec5SDimitry Andric // Emit address-significance attributes for all globals. 25005ffd83dbSDimitry Andric OutStreamer->emitAddrsig(); 2501fe6060f1SDimitry Andric for (const GlobalValue &GV : M.global_values()) { 2502bdd1243dSDimitry Andric if (!GV.use_empty() && !GV.isThreadLocal() && 25035f757f3fSDimitry Andric !GV.hasDLLImportStorageClass() && 25045f757f3fSDimitry Andric !GV.getName().starts_with("llvm.") && 2505bdd1243dSDimitry Andric !GV.hasAtLeastLocalUnnamedAddr()) 25065ffd83dbSDimitry Andric OutStreamer->emitAddrsigSym(getSymbol(&GV)); 25070b57cec5SDimitry Andric } 2508fe6060f1SDimitry Andric } 25090b57cec5SDimitry Andric 25100b57cec5SDimitry Andric // Emit symbol partition specifications (ELF only). 25110b57cec5SDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF()) { 25120b57cec5SDimitry Andric unsigned UniqueID = 0; 25130b57cec5SDimitry Andric for (const GlobalValue &GV : M.global_values()) { 25140b57cec5SDimitry Andric if (!GV.hasPartition() || GV.isDeclarationForLinker() || 25150b57cec5SDimitry Andric GV.getVisibility() != GlobalValue::DefaultVisibility) 25160b57cec5SDimitry Andric continue; 25170b57cec5SDimitry Andric 251881ad6265SDimitry Andric OutStreamer->switchSection( 25195ffd83dbSDimitry Andric OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0, 2520fe6060f1SDimitry Andric "", false, ++UniqueID, nullptr)); 25215ffd83dbSDimitry Andric OutStreamer->emitBytes(GV.getPartition()); 25225ffd83dbSDimitry Andric OutStreamer->emitZeros(1); 25235ffd83dbSDimitry Andric OutStreamer->emitValue( 25240b57cec5SDimitry Andric MCSymbolRefExpr::create(getSymbol(&GV), OutContext), 25250b57cec5SDimitry Andric MAI->getCodePointerSize()); 25260b57cec5SDimitry Andric } 25270b57cec5SDimitry Andric } 25280b57cec5SDimitry Andric 25290b57cec5SDimitry Andric // Allow the target to emit any magic that it wants at the end of the file, 25300b57cec5SDimitry Andric // after everything else has gone out. 25315ffd83dbSDimitry Andric emitEndOfAsmFile(M); 25320b57cec5SDimitry Andric 25330b57cec5SDimitry Andric MMI = nullptr; 253481ad6265SDimitry Andric AddrLabelSymbols = nullptr; 25350b57cec5SDimitry Andric 253681ad6265SDimitry Andric OutStreamer->finish(); 25370b57cec5SDimitry Andric OutStreamer->reset(); 25380b57cec5SDimitry Andric OwnedMLI.reset(); 25390b57cec5SDimitry Andric OwnedMDT.reset(); 25400b57cec5SDimitry Andric 25410b57cec5SDimitry Andric return false; 25420b57cec5SDimitry Andric } 25430b57cec5SDimitry Andric 2544e8d8bef9SDimitry Andric MCSymbol *AsmPrinter::getMBBExceptionSym(const MachineBasicBlock &MBB) { 2545*0fca6ea1SDimitry Andric auto Res = MBBSectionExceptionSyms.try_emplace(MBB.getSectionID()); 2546e8d8bef9SDimitry Andric if (Res.second) 2547e8d8bef9SDimitry Andric Res.first->second = createTempSymbol("exception"); 2548e8d8bef9SDimitry Andric return Res.first->second; 25490b57cec5SDimitry Andric } 25500b57cec5SDimitry Andric 25510b57cec5SDimitry Andric void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { 25520b57cec5SDimitry Andric this->MF = &MF; 2553480093f4SDimitry Andric const Function &F = MF.getFunction(); 25548bcb0991SDimitry Andric 255581ad6265SDimitry Andric // Record that there are split-stack functions, so we will emit a special 255681ad6265SDimitry Andric // section to tell the linker. 255781ad6265SDimitry Andric if (MF.shouldSplitStack()) { 255881ad6265SDimitry Andric HasSplitStack = true; 255981ad6265SDimitry Andric 256081ad6265SDimitry Andric if (!MF.getFrameInfo().needsSplitStackProlog()) 256181ad6265SDimitry Andric HasNoSplitStack = true; 256281ad6265SDimitry Andric } else 256381ad6265SDimitry Andric HasNoSplitStack = true; 256481ad6265SDimitry Andric 25650b57cec5SDimitry Andric // Get the function symbol. 25665ffd83dbSDimitry Andric if (!MAI->needsFunctionDescriptors()) { 25675ffd83dbSDimitry Andric CurrentFnSym = getSymbol(&MF.getFunction()); 25685ffd83dbSDimitry Andric } else { 25695ffd83dbSDimitry Andric assert(TM.getTargetTriple().isOSAIX() && 25705ffd83dbSDimitry Andric "Only AIX uses the function descriptor hooks."); 25715ffd83dbSDimitry Andric // AIX is unique here in that the name of the symbol emitted for the 25725ffd83dbSDimitry Andric // function body does not have the same name as the source function's 25735ffd83dbSDimitry Andric // C-linkage name. 25748bcb0991SDimitry Andric assert(CurrentFnDescSym && "The function descriptor symbol needs to be" 25758bcb0991SDimitry Andric " initalized first."); 25768bcb0991SDimitry Andric 25778bcb0991SDimitry Andric // Get the function entry point symbol. 25785ffd83dbSDimitry Andric CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&F, TM); 25798bcb0991SDimitry Andric } 25808bcb0991SDimitry Andric 25810b57cec5SDimitry Andric CurrentFnSymForSize = CurrentFnSym; 25820b57cec5SDimitry Andric CurrentFnBegin = nullptr; 2583bdd1243dSDimitry Andric CurrentFnBeginLocal = nullptr; 25845ffd83dbSDimitry Andric CurrentSectionBeginSym = nullptr; 25855ffd83dbSDimitry Andric MBBSectionRanges.clear(); 2586e8d8bef9SDimitry Andric MBBSectionExceptionSyms.clear(); 25870b57cec5SDimitry Andric bool NeedsLocalForSize = MAI->needsLocalForSize(); 2588480093f4SDimitry Andric if (F.hasFnAttribute("patchable-function-entry") || 25895ffd83dbSDimitry Andric F.hasFnAttribute("function-instrument") || 25905ffd83dbSDimitry Andric F.hasFnAttribute("xray-instruction-threshold") || 2591*0fca6ea1SDimitry Andric needFuncLabels(MF, *MMI) || NeedsLocalForSize || 2592*0fca6ea1SDimitry Andric MF.getTarget().Options.EmitStackSizeSection || 2593*0fca6ea1SDimitry Andric MF.getTarget().Options.BBAddrMap || MF.hasBBLabels()) { 25940b57cec5SDimitry Andric CurrentFnBegin = createTempSymbol("func_begin"); 25950b57cec5SDimitry Andric if (NeedsLocalForSize) 25960b57cec5SDimitry Andric CurrentFnSymForSize = CurrentFnBegin; 25970b57cec5SDimitry Andric } 25980b57cec5SDimitry Andric 25990b57cec5SDimitry Andric ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE(); 26000b57cec5SDimitry Andric } 26010b57cec5SDimitry Andric 26020b57cec5SDimitry Andric namespace { 26030b57cec5SDimitry Andric 26040b57cec5SDimitry Andric // Keep track the alignment, constpool entries per Section. 26050b57cec5SDimitry Andric struct SectionCPs { 26060b57cec5SDimitry Andric MCSection *S; 26075ffd83dbSDimitry Andric Align Alignment; 26080b57cec5SDimitry Andric SmallVector<unsigned, 4> CPEs; 26090b57cec5SDimitry Andric 26105ffd83dbSDimitry Andric SectionCPs(MCSection *s, Align a) : S(s), Alignment(a) {} 26110b57cec5SDimitry Andric }; 26120b57cec5SDimitry Andric 26130b57cec5SDimitry Andric } // end anonymous namespace 26140b57cec5SDimitry Andric 26150b57cec5SDimitry Andric /// EmitConstantPool - Print to the current output stream assembly 26160b57cec5SDimitry Andric /// representations of the constants in the constant pool MCP. This is 26170b57cec5SDimitry Andric /// used to print out constants which have been "spilled to memory" by 26180b57cec5SDimitry Andric /// the code generator. 26195ffd83dbSDimitry Andric void AsmPrinter::emitConstantPool() { 26200b57cec5SDimitry Andric const MachineConstantPool *MCP = MF->getConstantPool(); 26210b57cec5SDimitry Andric const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); 26220b57cec5SDimitry Andric if (CP.empty()) return; 26230b57cec5SDimitry Andric 26240b57cec5SDimitry Andric // Calculate sections for constant pool entries. We collect entries to go into 26250b57cec5SDimitry Andric // the same section together to reduce amount of section switch statements. 26260b57cec5SDimitry Andric SmallVector<SectionCPs, 4> CPSections; 26270b57cec5SDimitry Andric for (unsigned i = 0, e = CP.size(); i != e; ++i) { 26280b57cec5SDimitry Andric const MachineConstantPoolEntry &CPE = CP[i]; 26295ffd83dbSDimitry Andric Align Alignment = CPE.getAlign(); 26300b57cec5SDimitry Andric 26310b57cec5SDimitry Andric SectionKind Kind = CPE.getSectionKind(&getDataLayout()); 26320b57cec5SDimitry Andric 26330b57cec5SDimitry Andric const Constant *C = nullptr; 26340b57cec5SDimitry Andric if (!CPE.isMachineConstantPoolEntry()) 26350b57cec5SDimitry Andric C = CPE.Val.ConstVal; 26360b57cec5SDimitry Andric 26375ffd83dbSDimitry Andric MCSection *S = getObjFileLowering().getSectionForConstant( 26385ffd83dbSDimitry Andric getDataLayout(), Kind, C, Alignment); 26390b57cec5SDimitry Andric 26400b57cec5SDimitry Andric // The number of sections are small, just do a linear search from the 26410b57cec5SDimitry Andric // last section to the first. 26420b57cec5SDimitry Andric bool Found = false; 26430b57cec5SDimitry Andric unsigned SecIdx = CPSections.size(); 26440b57cec5SDimitry Andric while (SecIdx != 0) { 26450b57cec5SDimitry Andric if (CPSections[--SecIdx].S == S) { 26460b57cec5SDimitry Andric Found = true; 26470b57cec5SDimitry Andric break; 26480b57cec5SDimitry Andric } 26490b57cec5SDimitry Andric } 26500b57cec5SDimitry Andric if (!Found) { 26510b57cec5SDimitry Andric SecIdx = CPSections.size(); 26525ffd83dbSDimitry Andric CPSections.push_back(SectionCPs(S, Alignment)); 26530b57cec5SDimitry Andric } 26540b57cec5SDimitry Andric 26555ffd83dbSDimitry Andric if (Alignment > CPSections[SecIdx].Alignment) 26565ffd83dbSDimitry Andric CPSections[SecIdx].Alignment = Alignment; 26570b57cec5SDimitry Andric CPSections[SecIdx].CPEs.push_back(i); 26580b57cec5SDimitry Andric } 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric // Now print stuff into the calculated sections. 26610b57cec5SDimitry Andric const MCSection *CurSection = nullptr; 26620b57cec5SDimitry Andric unsigned Offset = 0; 26630b57cec5SDimitry Andric for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { 26640b57cec5SDimitry Andric for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { 26650b57cec5SDimitry Andric unsigned CPI = CPSections[i].CPEs[j]; 26660b57cec5SDimitry Andric MCSymbol *Sym = GetCPISymbol(CPI); 26670b57cec5SDimitry Andric if (!Sym->isUndefined()) 26680b57cec5SDimitry Andric continue; 26690b57cec5SDimitry Andric 26700b57cec5SDimitry Andric if (CurSection != CPSections[i].S) { 267181ad6265SDimitry Andric OutStreamer->switchSection(CPSections[i].S); 26725ffd83dbSDimitry Andric emitAlignment(Align(CPSections[i].Alignment)); 26730b57cec5SDimitry Andric CurSection = CPSections[i].S; 26740b57cec5SDimitry Andric Offset = 0; 26750b57cec5SDimitry Andric } 26760b57cec5SDimitry Andric 26770b57cec5SDimitry Andric MachineConstantPoolEntry CPE = CP[CPI]; 26780b57cec5SDimitry Andric 26790b57cec5SDimitry Andric // Emit inter-object padding for alignment. 26805ffd83dbSDimitry Andric unsigned NewOffset = alignTo(Offset, CPE.getAlign()); 26815ffd83dbSDimitry Andric OutStreamer->emitZeros(NewOffset - Offset); 26820b57cec5SDimitry Andric 2683e8d8bef9SDimitry Andric Offset = NewOffset + CPE.getSizeInBytes(getDataLayout()); 26840b57cec5SDimitry Andric 26855ffd83dbSDimitry Andric OutStreamer->emitLabel(Sym); 26860b57cec5SDimitry Andric if (CPE.isMachineConstantPoolEntry()) 26875ffd83dbSDimitry Andric emitMachineConstantPoolValue(CPE.Val.MachineCPVal); 26880b57cec5SDimitry Andric else 26895ffd83dbSDimitry Andric emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal); 26900b57cec5SDimitry Andric } 26910b57cec5SDimitry Andric } 26920b57cec5SDimitry Andric } 26930b57cec5SDimitry Andric 26945ffd83dbSDimitry Andric // Print assembly representations of the jump tables used by the current 26955ffd83dbSDimitry Andric // function. 26965ffd83dbSDimitry Andric void AsmPrinter::emitJumpTableInfo() { 26970b57cec5SDimitry Andric const DataLayout &DL = MF->getDataLayout(); 26980b57cec5SDimitry Andric const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 26990b57cec5SDimitry Andric if (!MJTI) return; 27000b57cec5SDimitry Andric if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; 27010b57cec5SDimitry Andric const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 27020b57cec5SDimitry Andric if (JT.empty()) return; 27030b57cec5SDimitry Andric 27040b57cec5SDimitry Andric // Pick the directive to use to print the jump table entries, and switch to 27050b57cec5SDimitry Andric // the appropriate section. 27060b57cec5SDimitry Andric const Function &F = MF->getFunction(); 27070b57cec5SDimitry Andric const TargetLoweringObjectFile &TLOF = getObjFileLowering(); 27080b57cec5SDimitry Andric bool JTInDiffSection = !TLOF.shouldPutJumpTableInFunctionSection( 27095f757f3fSDimitry Andric MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || 27105f757f3fSDimitry Andric MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference64, 27110b57cec5SDimitry Andric F); 27120b57cec5SDimitry Andric if (JTInDiffSection) { 27130b57cec5SDimitry Andric // Drop it in the readonly section. 27140b57cec5SDimitry Andric MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM); 271581ad6265SDimitry Andric OutStreamer->switchSection(ReadOnlySection); 27160b57cec5SDimitry Andric } 27170b57cec5SDimitry Andric 27185ffd83dbSDimitry Andric emitAlignment(Align(MJTI->getEntryAlignment(DL))); 27190b57cec5SDimitry Andric 27200b57cec5SDimitry Andric // Jump tables in code sections are marked with a data_region directive 27210b57cec5SDimitry Andric // where that's supported. 27220b57cec5SDimitry Andric if (!JTInDiffSection) 27235ffd83dbSDimitry Andric OutStreamer->emitDataRegion(MCDR_DataRegionJT32); 27240b57cec5SDimitry Andric 27250b57cec5SDimitry Andric for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { 27260b57cec5SDimitry Andric const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 27270b57cec5SDimitry Andric 27280b57cec5SDimitry Andric // If this jump table was deleted, ignore it. 27290b57cec5SDimitry Andric if (JTBBs.empty()) continue; 27300b57cec5SDimitry Andric 27310b57cec5SDimitry Andric // For the EK_LabelDifference32 entry, if using .set avoids a relocation, 27320b57cec5SDimitry Andric /// emit a .set directive for each unique entry. 27330b57cec5SDimitry Andric if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && 27340b57cec5SDimitry Andric MAI->doesSetDirectiveSuppressReloc()) { 27350b57cec5SDimitry Andric SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets; 27360b57cec5SDimitry Andric const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); 27370b57cec5SDimitry Andric const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext); 27384824e7fdSDimitry Andric for (const MachineBasicBlock *MBB : JTBBs) { 27390b57cec5SDimitry Andric if (!EmittedSets.insert(MBB).second) 27400b57cec5SDimitry Andric continue; 27410b57cec5SDimitry Andric 27420b57cec5SDimitry Andric // .set LJTSet, LBB32-base 27430b57cec5SDimitry Andric const MCExpr *LHS = 27440b57cec5SDimitry Andric MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); 27455ffd83dbSDimitry Andric OutStreamer->emitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), 27460b57cec5SDimitry Andric MCBinaryExpr::createSub(LHS, Base, 27470b57cec5SDimitry Andric OutContext)); 27480b57cec5SDimitry Andric } 27490b57cec5SDimitry Andric } 27500b57cec5SDimitry Andric 27510b57cec5SDimitry Andric // On some targets (e.g. Darwin) we want to emit two consecutive labels 27520b57cec5SDimitry Andric // before each jump table. The first label is never referenced, but tells 27530b57cec5SDimitry Andric // the assembler and linker the extents of the jump table object. The 27540b57cec5SDimitry Andric // second label is actually referenced by the code. 27550b57cec5SDimitry Andric if (JTInDiffSection && DL.hasLinkerPrivateGlobalPrefix()) 27560b57cec5SDimitry Andric // FIXME: This doesn't have to have any specific name, just any randomly 2757480093f4SDimitry Andric // named and numbered local label started with 'l' would work. Simplify 2758480093f4SDimitry Andric // GetJTISymbol. 27595ffd83dbSDimitry Andric OutStreamer->emitLabel(GetJTISymbol(JTI, true)); 27600b57cec5SDimitry Andric 2761480093f4SDimitry Andric MCSymbol* JTISymbol = GetJTISymbol(JTI); 27625ffd83dbSDimitry Andric OutStreamer->emitLabel(JTISymbol); 27630b57cec5SDimitry Andric 2764*0fca6ea1SDimitry Andric // Defer MCAssembler based constant folding due to a performance issue. The 2765*0fca6ea1SDimitry Andric // label differences will be evaluated at write time. 27664824e7fdSDimitry Andric for (const MachineBasicBlock *MBB : JTBBs) 27674824e7fdSDimitry Andric emitJumpTableEntry(MJTI, MBB, JTI); 27680b57cec5SDimitry Andric } 27690b57cec5SDimitry Andric if (!JTInDiffSection) 27705ffd83dbSDimitry Andric OutStreamer->emitDataRegion(MCDR_DataRegionEnd); 27710b57cec5SDimitry Andric } 27720b57cec5SDimitry Andric 27730b57cec5SDimitry Andric /// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the 27740b57cec5SDimitry Andric /// current stream. 27755ffd83dbSDimitry Andric void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI, 27760b57cec5SDimitry Andric const MachineBasicBlock *MBB, 27770b57cec5SDimitry Andric unsigned UID) const { 27780b57cec5SDimitry Andric assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block"); 27790b57cec5SDimitry Andric const MCExpr *Value = nullptr; 27800b57cec5SDimitry Andric switch (MJTI->getEntryKind()) { 27810b57cec5SDimitry Andric case MachineJumpTableInfo::EK_Inline: 27820b57cec5SDimitry Andric llvm_unreachable("Cannot emit EK_Inline jump table entry"); 27830b57cec5SDimitry Andric case MachineJumpTableInfo::EK_Custom32: 27840b57cec5SDimitry Andric Value = MF->getSubtarget().getTargetLowering()->LowerCustomJumpTableEntry( 27850b57cec5SDimitry Andric MJTI, MBB, UID, OutContext); 27860b57cec5SDimitry Andric break; 27870b57cec5SDimitry Andric case MachineJumpTableInfo::EK_BlockAddress: 27880b57cec5SDimitry Andric // EK_BlockAddress - Each entry is a plain address of block, e.g.: 27890b57cec5SDimitry Andric // .word LBB123 27900b57cec5SDimitry Andric Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); 27910b57cec5SDimitry Andric break; 27920b57cec5SDimitry Andric case MachineJumpTableInfo::EK_GPRel32BlockAddress: { 27930b57cec5SDimitry Andric // EK_GPRel32BlockAddress - Each entry is an address of block, encoded 27940b57cec5SDimitry Andric // with a relocation as gp-relative, e.g.: 27950b57cec5SDimitry Andric // .gprel32 LBB123 27960b57cec5SDimitry Andric MCSymbol *MBBSym = MBB->getSymbol(); 27975ffd83dbSDimitry Andric OutStreamer->emitGPRel32Value(MCSymbolRefExpr::create(MBBSym, OutContext)); 27980b57cec5SDimitry Andric return; 27990b57cec5SDimitry Andric } 28000b57cec5SDimitry Andric 28010b57cec5SDimitry Andric case MachineJumpTableInfo::EK_GPRel64BlockAddress: { 28020b57cec5SDimitry Andric // EK_GPRel64BlockAddress - Each entry is an address of block, encoded 28030b57cec5SDimitry Andric // with a relocation as gp-relative, e.g.: 28040b57cec5SDimitry Andric // .gpdword LBB123 28050b57cec5SDimitry Andric MCSymbol *MBBSym = MBB->getSymbol(); 28065ffd83dbSDimitry Andric OutStreamer->emitGPRel64Value(MCSymbolRefExpr::create(MBBSym, OutContext)); 28070b57cec5SDimitry Andric return; 28080b57cec5SDimitry Andric } 28090b57cec5SDimitry Andric 28105f757f3fSDimitry Andric case MachineJumpTableInfo::EK_LabelDifference32: 28115f757f3fSDimitry Andric case MachineJumpTableInfo::EK_LabelDifference64: { 28120b57cec5SDimitry Andric // Each entry is the address of the block minus the address of the jump 28130b57cec5SDimitry Andric // table. This is used for PIC jump tables where gprel32 is not supported. 28140b57cec5SDimitry Andric // e.g.: 28150b57cec5SDimitry Andric // .word LBB123 - LJTI1_2 28160b57cec5SDimitry Andric // If the .set directive avoids relocations, this is emitted as: 28170b57cec5SDimitry Andric // .set L4_5_set_123, LBB123 - LJTI1_2 28180b57cec5SDimitry Andric // .word L4_5_set_123 28195f757f3fSDimitry Andric if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && 28205f757f3fSDimitry Andric MAI->doesSetDirectiveSuppressReloc()) { 28210b57cec5SDimitry Andric Value = MCSymbolRefExpr::create(GetJTSetSymbol(UID, MBB->getNumber()), 28220b57cec5SDimitry Andric OutContext); 28230b57cec5SDimitry Andric break; 28240b57cec5SDimitry Andric } 28250b57cec5SDimitry Andric Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext); 28260b57cec5SDimitry Andric const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); 28270b57cec5SDimitry Andric const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF, UID, OutContext); 28280b57cec5SDimitry Andric Value = MCBinaryExpr::createSub(Value, Base, OutContext); 28290b57cec5SDimitry Andric break; 28300b57cec5SDimitry Andric } 28310b57cec5SDimitry Andric } 28320b57cec5SDimitry Andric 28330b57cec5SDimitry Andric assert(Value && "Unknown entry kind!"); 28340b57cec5SDimitry Andric 28350b57cec5SDimitry Andric unsigned EntrySize = MJTI->getEntrySize(getDataLayout()); 28365ffd83dbSDimitry Andric OutStreamer->emitValue(Value, EntrySize); 28370b57cec5SDimitry Andric } 28380b57cec5SDimitry Andric 28390b57cec5SDimitry Andric /// EmitSpecialLLVMGlobal - Check to see if the specified global is a 28400b57cec5SDimitry Andric /// special global used by LLVM. If so, emit it and return true, otherwise 28410b57cec5SDimitry Andric /// do nothing and return false. 28425ffd83dbSDimitry Andric bool AsmPrinter::emitSpecialLLVMGlobal(const GlobalVariable *GV) { 28430b57cec5SDimitry Andric if (GV->getName() == "llvm.used") { 28440b57cec5SDimitry Andric if (MAI->hasNoDeadStrip()) // No need to emit this at all. 28455ffd83dbSDimitry Andric emitLLVMUsedList(cast<ConstantArray>(GV->getInitializer())); 28460b57cec5SDimitry Andric return true; 28470b57cec5SDimitry Andric } 28480b57cec5SDimitry Andric 28490b57cec5SDimitry Andric // Ignore debug and non-emitted data. This handles llvm.compiler.used. 28500b57cec5SDimitry Andric if (GV->getSection() == "llvm.metadata" || 28510b57cec5SDimitry Andric GV->hasAvailableExternallyLinkage()) 28520b57cec5SDimitry Andric return true; 28530b57cec5SDimitry Andric 28547a6dacacSDimitry Andric if (GV->getName() == "llvm.arm64ec.symbolmap") { 28557a6dacacSDimitry Andric // For ARM64EC, print the table that maps between symbols and the 28567a6dacacSDimitry Andric // corresponding thunks to translate between x64 and AArch64 code. 28577a6dacacSDimitry Andric // This table is generated by AArch64Arm64ECCallLowering. 2858*0fca6ea1SDimitry Andric OutStreamer->switchSection( 2859*0fca6ea1SDimitry Andric OutContext.getCOFFSection(".hybmp$x", COFF::IMAGE_SCN_LNK_INFO)); 28607a6dacacSDimitry Andric auto *Arr = cast<ConstantArray>(GV->getInitializer()); 28617a6dacacSDimitry Andric for (auto &U : Arr->operands()) { 28627a6dacacSDimitry Andric auto *C = cast<Constant>(U); 2863*0fca6ea1SDimitry Andric auto *Src = cast<GlobalValue>(C->getOperand(0)->stripPointerCasts()); 2864*0fca6ea1SDimitry Andric auto *Dst = cast<GlobalValue>(C->getOperand(1)->stripPointerCasts()); 28657a6dacacSDimitry Andric int Kind = cast<ConstantInt>(C->getOperand(2))->getZExtValue(); 28667a6dacacSDimitry Andric 28677a6dacacSDimitry Andric if (Src->hasDLLImportStorageClass()) { 28687a6dacacSDimitry Andric // For now, we assume dllimport functions aren't directly called. 28697a6dacacSDimitry Andric // (We might change this later to match MSVC.) 28707a6dacacSDimitry Andric OutStreamer->emitCOFFSymbolIndex( 28717a6dacacSDimitry Andric OutContext.getOrCreateSymbol("__imp_" + Src->getName())); 28727a6dacacSDimitry Andric OutStreamer->emitCOFFSymbolIndex(getSymbol(Dst)); 28737a6dacacSDimitry Andric OutStreamer->emitInt32(Kind); 28747a6dacacSDimitry Andric } else { 28757a6dacacSDimitry Andric // FIXME: For non-dllimport functions, MSVC emits the same entry 28767a6dacacSDimitry Andric // twice, for reasons I don't understand. I have to assume the linker 28777a6dacacSDimitry Andric // ignores the redundant entry; there aren't any reasonable semantics 28787a6dacacSDimitry Andric // to attach to it. 28797a6dacacSDimitry Andric OutStreamer->emitCOFFSymbolIndex(getSymbol(Src)); 28807a6dacacSDimitry Andric OutStreamer->emitCOFFSymbolIndex(getSymbol(Dst)); 28817a6dacacSDimitry Andric OutStreamer->emitInt32(Kind); 28827a6dacacSDimitry Andric } 28837a6dacacSDimitry Andric } 28847a6dacacSDimitry Andric return true; 28857a6dacacSDimitry Andric } 28867a6dacacSDimitry Andric 28870b57cec5SDimitry Andric if (!GV->hasAppendingLinkage()) return false; 28880b57cec5SDimitry Andric 28890b57cec5SDimitry Andric assert(GV->hasInitializer() && "Not a special LLVM global!"); 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric if (GV->getName() == "llvm.global_ctors") { 2892*0fca6ea1SDimitry Andric emitXXStructorList(GV->getDataLayout(), GV->getInitializer(), 28930b57cec5SDimitry Andric /* isCtor */ true); 28940b57cec5SDimitry Andric 28950b57cec5SDimitry Andric return true; 28960b57cec5SDimitry Andric } 28970b57cec5SDimitry Andric 28980b57cec5SDimitry Andric if (GV->getName() == "llvm.global_dtors") { 2899*0fca6ea1SDimitry Andric emitXXStructorList(GV->getDataLayout(), GV->getInitializer(), 29000b57cec5SDimitry Andric /* isCtor */ false); 29010b57cec5SDimitry Andric 29020b57cec5SDimitry Andric return true; 29030b57cec5SDimitry Andric } 29040b57cec5SDimitry Andric 2905*0fca6ea1SDimitry Andric report_fatal_error("unknown special variable with appending linkage"); 29060b57cec5SDimitry Andric } 29070b57cec5SDimitry Andric 29080b57cec5SDimitry Andric /// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each 29090b57cec5SDimitry Andric /// global in the specified llvm.used list. 29105ffd83dbSDimitry Andric void AsmPrinter::emitLLVMUsedList(const ConstantArray *InitList) { 29110b57cec5SDimitry Andric // Should be an array of 'i8*'. 29120b57cec5SDimitry Andric for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { 29130b57cec5SDimitry Andric const GlobalValue *GV = 29140b57cec5SDimitry Andric dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); 29150b57cec5SDimitry Andric if (GV) 29165ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip); 29170b57cec5SDimitry Andric } 29180b57cec5SDimitry Andric } 29190b57cec5SDimitry Andric 2920e8d8bef9SDimitry Andric void AsmPrinter::preprocessXXStructorList(const DataLayout &DL, 2921e8d8bef9SDimitry Andric const Constant *List, 2922e8d8bef9SDimitry Andric SmallVector<Structor, 8> &Structors) { 2923e8d8bef9SDimitry Andric // Should be an array of '{ i32, void ()*, i8* }' structs. The first value is 2924e8d8bef9SDimitry Andric // the init priority. 2925e8d8bef9SDimitry Andric if (!isa<ConstantArray>(List)) 2926e8d8bef9SDimitry Andric return; 29270b57cec5SDimitry Andric 29280b57cec5SDimitry Andric // Gather the structors in a form that's convenient for sorting by priority. 29295ffd83dbSDimitry Andric for (Value *O : cast<ConstantArray>(List)->operands()) { 29305ffd83dbSDimitry Andric auto *CS = cast<ConstantStruct>(O); 29310b57cec5SDimitry Andric if (CS->getOperand(1)->isNullValue()) 29320b57cec5SDimitry Andric break; // Found a null terminator, skip the rest. 29330b57cec5SDimitry Andric ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); 2934e8d8bef9SDimitry Andric if (!Priority) 2935e8d8bef9SDimitry Andric continue; // Malformed. 29360b57cec5SDimitry Andric Structors.push_back(Structor()); 29370b57cec5SDimitry Andric Structor &S = Structors.back(); 29380b57cec5SDimitry Andric S.Priority = Priority->getLimitedValue(65535); 29390b57cec5SDimitry Andric S.Func = CS->getOperand(1); 2940e8d8bef9SDimitry Andric if (!CS->getOperand(2)->isNullValue()) { 2941e8d8bef9SDimitry Andric if (TM.getTargetTriple().isOSAIX()) 2942e8d8bef9SDimitry Andric llvm::report_fatal_error( 2943e8d8bef9SDimitry Andric "associated data of XXStructor list is not yet supported on AIX"); 29440b57cec5SDimitry Andric S.ComdatKey = 29450b57cec5SDimitry Andric dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts()); 29460b57cec5SDimitry Andric } 2947e8d8bef9SDimitry Andric } 29480b57cec5SDimitry Andric 29490b57cec5SDimitry Andric // Emit the function pointers in the target-specific order 29500b57cec5SDimitry Andric llvm::stable_sort(Structors, [](const Structor &L, const Structor &R) { 29510b57cec5SDimitry Andric return L.Priority < R.Priority; 29520b57cec5SDimitry Andric }); 2953e8d8bef9SDimitry Andric } 2954e8d8bef9SDimitry Andric 2955e8d8bef9SDimitry Andric /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init 2956e8d8bef9SDimitry Andric /// priority. 2957e8d8bef9SDimitry Andric void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List, 2958e8d8bef9SDimitry Andric bool IsCtor) { 2959e8d8bef9SDimitry Andric SmallVector<Structor, 8> Structors; 2960e8d8bef9SDimitry Andric preprocessXXStructorList(DL, List, Structors); 2961e8d8bef9SDimitry Andric if (Structors.empty()) 2962e8d8bef9SDimitry Andric return; 2963e8d8bef9SDimitry Andric 2964fe6060f1SDimitry Andric // Emit the structors in reverse order if we are using the .ctor/.dtor 2965fe6060f1SDimitry Andric // initialization scheme. 2966fe6060f1SDimitry Andric if (!TM.Options.UseInitArray) 2967fe6060f1SDimitry Andric std::reverse(Structors.begin(), Structors.end()); 2968fe6060f1SDimitry Andric 29698bcb0991SDimitry Andric const Align Align = DL.getPointerPrefAlignment(); 29700b57cec5SDimitry Andric for (Structor &S : Structors) { 29710b57cec5SDimitry Andric const TargetLoweringObjectFile &Obj = getObjFileLowering(); 29720b57cec5SDimitry Andric const MCSymbol *KeySym = nullptr; 29730b57cec5SDimitry Andric if (GlobalValue *GV = S.ComdatKey) { 29740b57cec5SDimitry Andric if (GV->isDeclarationForLinker()) 29750b57cec5SDimitry Andric // If the associated variable is not defined in this module 29760b57cec5SDimitry Andric // (it might be available_externally, or have been an 29770b57cec5SDimitry Andric // available_externally definition that was dropped by the 29780b57cec5SDimitry Andric // EliminateAvailableExternally pass), some other TU 29790b57cec5SDimitry Andric // will provide its dynamic initializer. 29800b57cec5SDimitry Andric continue; 29810b57cec5SDimitry Andric 29820b57cec5SDimitry Andric KeySym = getSymbol(GV); 29830b57cec5SDimitry Andric } 2984e8d8bef9SDimitry Andric 29850b57cec5SDimitry Andric MCSection *OutputSection = 2986e8d8bef9SDimitry Andric (IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym) 29870b57cec5SDimitry Andric : Obj.getStaticDtorSection(S.Priority, KeySym)); 298881ad6265SDimitry Andric OutStreamer->switchSection(OutputSection); 29890b57cec5SDimitry Andric if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection()) 29905ffd83dbSDimitry Andric emitAlignment(Align); 29915ffd83dbSDimitry Andric emitXXStructor(DL, S.Func); 29920b57cec5SDimitry Andric } 29930b57cec5SDimitry Andric } 29940b57cec5SDimitry Andric 29955ffd83dbSDimitry Andric void AsmPrinter::emitModuleIdents(Module &M) { 29960b57cec5SDimitry Andric if (!MAI->hasIdentDirective()) 29970b57cec5SDimitry Andric return; 29980b57cec5SDimitry Andric 29990b57cec5SDimitry Andric if (const NamedMDNode *NMD = M.getNamedMetadata("llvm.ident")) { 3000*0fca6ea1SDimitry Andric for (const MDNode *N : NMD->operands()) { 30010b57cec5SDimitry Andric assert(N->getNumOperands() == 1 && 30020b57cec5SDimitry Andric "llvm.ident metadata entry can have only one operand"); 30030b57cec5SDimitry Andric const MDString *S = cast<MDString>(N->getOperand(0)); 30045ffd83dbSDimitry Andric OutStreamer->emitIdent(S->getString()); 30050b57cec5SDimitry Andric } 30060b57cec5SDimitry Andric } 30070b57cec5SDimitry Andric } 30080b57cec5SDimitry Andric 30095ffd83dbSDimitry Andric void AsmPrinter::emitModuleCommandLines(Module &M) { 30100b57cec5SDimitry Andric MCSection *CommandLine = getObjFileLowering().getSectionForCommandLines(); 30110b57cec5SDimitry Andric if (!CommandLine) 30120b57cec5SDimitry Andric return; 30130b57cec5SDimitry Andric 30140b57cec5SDimitry Andric const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline"); 30150b57cec5SDimitry Andric if (!NMD || !NMD->getNumOperands()) 30160b57cec5SDimitry Andric return; 30170b57cec5SDimitry Andric 301881ad6265SDimitry Andric OutStreamer->pushSection(); 301981ad6265SDimitry Andric OutStreamer->switchSection(CommandLine); 30205ffd83dbSDimitry Andric OutStreamer->emitZeros(1); 3021*0fca6ea1SDimitry Andric for (const MDNode *N : NMD->operands()) { 30220b57cec5SDimitry Andric assert(N->getNumOperands() == 1 && 30230b57cec5SDimitry Andric "llvm.commandline metadata entry can have only one operand"); 30240b57cec5SDimitry Andric const MDString *S = cast<MDString>(N->getOperand(0)); 30255ffd83dbSDimitry Andric OutStreamer->emitBytes(S->getString()); 30265ffd83dbSDimitry Andric OutStreamer->emitZeros(1); 30270b57cec5SDimitry Andric } 302881ad6265SDimitry Andric OutStreamer->popSection(); 30290b57cec5SDimitry Andric } 30300b57cec5SDimitry Andric 30310b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 30320b57cec5SDimitry Andric // Emission and print routines 30330b57cec5SDimitry Andric // 30340b57cec5SDimitry Andric 30350b57cec5SDimitry Andric /// Emit a byte directive and value. 30360b57cec5SDimitry Andric /// 30375ffd83dbSDimitry Andric void AsmPrinter::emitInt8(int Value) const { OutStreamer->emitInt8(Value); } 30380b57cec5SDimitry Andric 30390b57cec5SDimitry Andric /// Emit a short directive and value. 30405ffd83dbSDimitry Andric void AsmPrinter::emitInt16(int Value) const { OutStreamer->emitInt16(Value); } 30410b57cec5SDimitry Andric 30420b57cec5SDimitry Andric /// Emit a long directive and value. 30435ffd83dbSDimitry Andric void AsmPrinter::emitInt32(int Value) const { OutStreamer->emitInt32(Value); } 30440b57cec5SDimitry Andric 304506c3fb27SDimitry Andric /// EmitSLEB128 - emit the specified signed leb128 value. 304606c3fb27SDimitry Andric void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const { 304706c3fb27SDimitry Andric if (isVerbose() && Desc) 304806c3fb27SDimitry Andric OutStreamer->AddComment(Desc); 304906c3fb27SDimitry Andric 305006c3fb27SDimitry Andric OutStreamer->emitSLEB128IntValue(Value); 305106c3fb27SDimitry Andric } 305206c3fb27SDimitry Andric 305306c3fb27SDimitry Andric void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc, 305406c3fb27SDimitry Andric unsigned PadTo) const { 305506c3fb27SDimitry Andric if (isVerbose() && Desc) 305606c3fb27SDimitry Andric OutStreamer->AddComment(Desc); 305706c3fb27SDimitry Andric 305806c3fb27SDimitry Andric OutStreamer->emitULEB128IntValue(Value, PadTo); 305906c3fb27SDimitry Andric } 306006c3fb27SDimitry Andric 30610b57cec5SDimitry Andric /// Emit a long long directive and value. 30620b57cec5SDimitry Andric void AsmPrinter::emitInt64(uint64_t Value) const { 30635ffd83dbSDimitry Andric OutStreamer->emitInt64(Value); 30640b57cec5SDimitry Andric } 30650b57cec5SDimitry Andric 30660b57cec5SDimitry Andric /// Emit something like ".long Hi-Lo" where the size in bytes of the directive 30670b57cec5SDimitry Andric /// is specified by Size and Hi/Lo specify the labels. This implicitly uses 30680b57cec5SDimitry Andric /// .set if it avoids relocations. 30695ffd83dbSDimitry Andric void AsmPrinter::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 30700b57cec5SDimitry Andric unsigned Size) const { 30710b57cec5SDimitry Andric OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size); 30720b57cec5SDimitry Andric } 30730b57cec5SDimitry Andric 307406c3fb27SDimitry Andric /// Emit something like ".uleb128 Hi-Lo". 307506c3fb27SDimitry Andric void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi, 307606c3fb27SDimitry Andric const MCSymbol *Lo) const { 307706c3fb27SDimitry Andric OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); 307806c3fb27SDimitry Andric } 307906c3fb27SDimitry Andric 30800b57cec5SDimitry Andric /// EmitLabelPlusOffset - Emit something like ".long Label+Offset" 30810b57cec5SDimitry Andric /// where the size in bytes of the directive is specified by Size and Label 30820b57cec5SDimitry Andric /// specifies the label. This implicitly uses .set if it is available. 30835ffd83dbSDimitry Andric void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, 30840b57cec5SDimitry Andric unsigned Size, 30850b57cec5SDimitry Andric bool IsSectionRelative) const { 30860b57cec5SDimitry Andric if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) { 308781ad6265SDimitry Andric OutStreamer->emitCOFFSecRel32(Label, Offset); 30880b57cec5SDimitry Andric if (Size > 4) 30895ffd83dbSDimitry Andric OutStreamer->emitZeros(Size - 4); 30900b57cec5SDimitry Andric return; 30910b57cec5SDimitry Andric } 30920b57cec5SDimitry Andric 30930b57cec5SDimitry Andric // Emit Label+Offset (or just Label if Offset is zero) 30940b57cec5SDimitry Andric const MCExpr *Expr = MCSymbolRefExpr::create(Label, OutContext); 30950b57cec5SDimitry Andric if (Offset) 30960b57cec5SDimitry Andric Expr = MCBinaryExpr::createAdd( 30970b57cec5SDimitry Andric Expr, MCConstantExpr::create(Offset, OutContext), OutContext); 30980b57cec5SDimitry Andric 30995ffd83dbSDimitry Andric OutStreamer->emitValue(Expr, Size); 31000b57cec5SDimitry Andric } 31010b57cec5SDimitry Andric 31020b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 31030b57cec5SDimitry Andric 31040b57cec5SDimitry Andric // EmitAlignment - Emit an alignment directive to the specified power of 31058bcb0991SDimitry Andric // two boundary. If a global value is specified, and if that global has 31060b57cec5SDimitry Andric // an explicit alignment requested, it will override the alignment request 31070b57cec5SDimitry Andric // if required for correctness. 310804eeddc0SDimitry Andric void AsmPrinter::emitAlignment(Align Alignment, const GlobalObject *GV, 310904eeddc0SDimitry Andric unsigned MaxBytesToEmit) const { 31100b57cec5SDimitry Andric if (GV) 3111*0fca6ea1SDimitry Andric Alignment = getGVAlignment(GV, GV->getDataLayout(), Alignment); 31120b57cec5SDimitry Andric 31135ffd83dbSDimitry Andric if (Alignment == Align(1)) 31148bcb0991SDimitry Andric return; // 1-byte aligned: no need to emit alignment. 31150b57cec5SDimitry Andric 3116*0fca6ea1SDimitry Andric if (getCurrentSection()->isText()) { 3117349cc55cSDimitry Andric const MCSubtargetInfo *STI = nullptr; 3118349cc55cSDimitry Andric if (this->MF) 3119349cc55cSDimitry Andric STI = &getSubtargetInfo(); 31200b57cec5SDimitry Andric else 3121349cc55cSDimitry Andric STI = TM.getMCSubtargetInfo(); 3122bdd1243dSDimitry Andric OutStreamer->emitCodeAlignment(Alignment, STI, MaxBytesToEmit); 3123349cc55cSDimitry Andric } else 3124bdd1243dSDimitry Andric OutStreamer->emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit); 31250b57cec5SDimitry Andric } 31260b57cec5SDimitry Andric 31270b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 31280b57cec5SDimitry Andric // Constant emission. 31290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 31300b57cec5SDimitry Andric 31310b57cec5SDimitry Andric const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { 31320b57cec5SDimitry Andric MCContext &Ctx = OutContext; 31330b57cec5SDimitry Andric 31340b57cec5SDimitry Andric if (CV->isNullValue() || isa<UndefValue>(CV)) 31350b57cec5SDimitry Andric return MCConstantExpr::create(0, Ctx); 31360b57cec5SDimitry Andric 31370b57cec5SDimitry Andric if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) 31380b57cec5SDimitry Andric return MCConstantExpr::create(CI->getZExtValue(), Ctx); 31390b57cec5SDimitry Andric 3140*0fca6ea1SDimitry Andric if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(CV)) 3141*0fca6ea1SDimitry Andric return lowerConstantPtrAuth(*CPA); 3142*0fca6ea1SDimitry Andric 31430b57cec5SDimitry Andric if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) 31440b57cec5SDimitry Andric return MCSymbolRefExpr::create(getSymbol(GV), Ctx); 31450b57cec5SDimitry Andric 31460b57cec5SDimitry Andric if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) 3147*0fca6ea1SDimitry Andric return lowerBlockAddressConstant(*BA); 31480b57cec5SDimitry Andric 3149e8d8bef9SDimitry Andric if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) 3150e8d8bef9SDimitry Andric return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM); 3151e8d8bef9SDimitry Andric 31520eae32dcSDimitry Andric if (const NoCFIValue *NC = dyn_cast<NoCFIValue>(CV)) 31530eae32dcSDimitry Andric return MCSymbolRefExpr::create(getSymbol(NC->getGlobalValue()), Ctx); 31540eae32dcSDimitry Andric 31550b57cec5SDimitry Andric const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); 31560b57cec5SDimitry Andric if (!CE) { 31570b57cec5SDimitry Andric llvm_unreachable("Unknown constant value to lower!"); 31580b57cec5SDimitry Andric } 31590b57cec5SDimitry Andric 316081ad6265SDimitry Andric // The constant expression opcodes are limited to those that are necessary 316181ad6265SDimitry Andric // to represent relocations on supported targets. Expressions involving only 316281ad6265SDimitry Andric // constant addresses are constant folded instead. 31630b57cec5SDimitry Andric switch (CE->getOpcode()) { 3164fcaf7f86SDimitry Andric default: 3165fcaf7f86SDimitry Andric break; // Error 3166e8d8bef9SDimitry Andric case Instruction::AddrSpaceCast: { 3167e8d8bef9SDimitry Andric const Constant *Op = CE->getOperand(0); 3168e8d8bef9SDimitry Andric unsigned DstAS = CE->getType()->getPointerAddressSpace(); 3169e8d8bef9SDimitry Andric unsigned SrcAS = Op->getType()->getPointerAddressSpace(); 3170e8d8bef9SDimitry Andric if (TM.isNoopAddrSpaceCast(SrcAS, DstAS)) 3171e8d8bef9SDimitry Andric return lowerConstant(Op); 3172e8d8bef9SDimitry Andric 3173fcaf7f86SDimitry Andric break; // Error 31740b57cec5SDimitry Andric } 31750b57cec5SDimitry Andric case Instruction::GetElementPtr: { 31760b57cec5SDimitry Andric // Generate a symbolic expression for the byte address 31770b57cec5SDimitry Andric APInt OffsetAI(getDataLayout().getPointerTypeSizeInBits(CE->getType()), 0); 31780b57cec5SDimitry Andric cast<GEPOperator>(CE)->accumulateConstantOffset(getDataLayout(), OffsetAI); 31790b57cec5SDimitry Andric 31800b57cec5SDimitry Andric const MCExpr *Base = lowerConstant(CE->getOperand(0)); 31810b57cec5SDimitry Andric if (!OffsetAI) 31820b57cec5SDimitry Andric return Base; 31830b57cec5SDimitry Andric 31840b57cec5SDimitry Andric int64_t Offset = OffsetAI.getSExtValue(); 31850b57cec5SDimitry Andric return MCBinaryExpr::createAdd(Base, MCConstantExpr::create(Offset, Ctx), 31860b57cec5SDimitry Andric Ctx); 31870b57cec5SDimitry Andric } 31880b57cec5SDimitry Andric 31890b57cec5SDimitry Andric case Instruction::Trunc: 31900b57cec5SDimitry Andric // We emit the value and depend on the assembler to truncate the generated 31910b57cec5SDimitry Andric // expression properly. This is important for differences between 31920b57cec5SDimitry Andric // blockaddress labels. Since the two labels are in the same function, it 31930b57cec5SDimitry Andric // is reasonable to treat their delta as a 32-bit value. 3194bdd1243dSDimitry Andric [[fallthrough]]; 31950b57cec5SDimitry Andric case Instruction::BitCast: 31960b57cec5SDimitry Andric return lowerConstant(CE->getOperand(0)); 31970b57cec5SDimitry Andric 31980b57cec5SDimitry Andric case Instruction::IntToPtr: { 31990b57cec5SDimitry Andric const DataLayout &DL = getDataLayout(); 32000b57cec5SDimitry Andric 32010b57cec5SDimitry Andric // Handle casts to pointers by changing them into casts to the appropriate 32020b57cec5SDimitry Andric // integer type. This promotes constant folding and simplifies this code. 32030b57cec5SDimitry Andric Constant *Op = CE->getOperand(0); 32045f757f3fSDimitry Andric Op = ConstantFoldIntegerCast(Op, DL.getIntPtrType(CV->getType()), 32055f757f3fSDimitry Andric /*IsSigned*/ false, DL); 32065f757f3fSDimitry Andric if (Op) 32070b57cec5SDimitry Andric return lowerConstant(Op); 32085f757f3fSDimitry Andric 32095f757f3fSDimitry Andric break; // Error 32100b57cec5SDimitry Andric } 32110b57cec5SDimitry Andric 32120b57cec5SDimitry Andric case Instruction::PtrToInt: { 32130b57cec5SDimitry Andric const DataLayout &DL = getDataLayout(); 32140b57cec5SDimitry Andric 32150b57cec5SDimitry Andric // Support only foldable casts to/from pointers that can be eliminated by 32160b57cec5SDimitry Andric // changing the pointer to the appropriately sized integer type. 32170b57cec5SDimitry Andric Constant *Op = CE->getOperand(0); 32180b57cec5SDimitry Andric Type *Ty = CE->getType(); 32190b57cec5SDimitry Andric 32200b57cec5SDimitry Andric const MCExpr *OpExpr = lowerConstant(Op); 32210b57cec5SDimitry Andric 32220b57cec5SDimitry Andric // We can emit the pointer value into this slot if the slot is an 32230b57cec5SDimitry Andric // integer slot equal to the size of the pointer. 32240b57cec5SDimitry Andric // 32250b57cec5SDimitry Andric // If the pointer is larger than the resultant integer, then 32260b57cec5SDimitry Andric // as with Trunc just depend on the assembler to truncate it. 3227bdd1243dSDimitry Andric if (DL.getTypeAllocSize(Ty).getFixedValue() <= 3228bdd1243dSDimitry Andric DL.getTypeAllocSize(Op->getType()).getFixedValue()) 32290b57cec5SDimitry Andric return OpExpr; 32300b57cec5SDimitry Andric 3231972a253aSDimitry Andric break; // Error 32320b57cec5SDimitry Andric } 32330b57cec5SDimitry Andric 32340b57cec5SDimitry Andric case Instruction::Sub: { 32350b57cec5SDimitry Andric GlobalValue *LHSGV; 32360b57cec5SDimitry Andric APInt LHSOffset; 3237e8d8bef9SDimitry Andric DSOLocalEquivalent *DSOEquiv; 32380b57cec5SDimitry Andric if (IsConstantOffsetFromGlobal(CE->getOperand(0), LHSGV, LHSOffset, 3239e8d8bef9SDimitry Andric getDataLayout(), &DSOEquiv)) { 32400b57cec5SDimitry Andric GlobalValue *RHSGV; 32410b57cec5SDimitry Andric APInt RHSOffset; 32420b57cec5SDimitry Andric if (IsConstantOffsetFromGlobal(CE->getOperand(1), RHSGV, RHSOffset, 32430b57cec5SDimitry Andric getDataLayout())) { 32440b57cec5SDimitry Andric const MCExpr *RelocExpr = 32450b57cec5SDimitry Andric getObjFileLowering().lowerRelativeReference(LHSGV, RHSGV, TM); 3246e8d8bef9SDimitry Andric if (!RelocExpr) { 3247e8d8bef9SDimitry Andric const MCExpr *LHSExpr = 3248e8d8bef9SDimitry Andric MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx); 3249e8d8bef9SDimitry Andric if (DSOEquiv && 3250e8d8bef9SDimitry Andric getObjFileLowering().supportDSOLocalEquivalentLowering()) 3251e8d8bef9SDimitry Andric LHSExpr = 3252e8d8bef9SDimitry Andric getObjFileLowering().lowerDSOLocalEquivalent(DSOEquiv, TM); 32530b57cec5SDimitry Andric RelocExpr = MCBinaryExpr::createSub( 3254e8d8bef9SDimitry Andric LHSExpr, MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx); 3255e8d8bef9SDimitry Andric } 32560b57cec5SDimitry Andric int64_t Addend = (LHSOffset - RHSOffset).getSExtValue(); 32570b57cec5SDimitry Andric if (Addend != 0) 32580b57cec5SDimitry Andric RelocExpr = MCBinaryExpr::createAdd( 32590b57cec5SDimitry Andric RelocExpr, MCConstantExpr::create(Addend, Ctx), Ctx); 32600b57cec5SDimitry Andric return RelocExpr; 32610b57cec5SDimitry Andric } 32620b57cec5SDimitry Andric } 32630b57cec5SDimitry Andric 32640b57cec5SDimitry Andric const MCExpr *LHS = lowerConstant(CE->getOperand(0)); 32650b57cec5SDimitry Andric const MCExpr *RHS = lowerConstant(CE->getOperand(1)); 326681ad6265SDimitry Andric return MCBinaryExpr::createSub(LHS, RHS, Ctx); 326781ad6265SDimitry Andric break; 32680b57cec5SDimitry Andric } 326981ad6265SDimitry Andric 327081ad6265SDimitry Andric case Instruction::Add: { 327181ad6265SDimitry Andric const MCExpr *LHS = lowerConstant(CE->getOperand(0)); 327281ad6265SDimitry Andric const MCExpr *RHS = lowerConstant(CE->getOperand(1)); 327381ad6265SDimitry Andric return MCBinaryExpr::createAdd(LHS, RHS, Ctx); 32740b57cec5SDimitry Andric } 32750b57cec5SDimitry Andric } 3276fcaf7f86SDimitry Andric 3277fcaf7f86SDimitry Andric // If the code isn't optimized, there may be outstanding folding 3278fcaf7f86SDimitry Andric // opportunities. Attempt to fold the expression using DataLayout as a 3279fcaf7f86SDimitry Andric // last resort before giving up. 3280fcaf7f86SDimitry Andric Constant *C = ConstantFoldConstant(CE, getDataLayout()); 3281fcaf7f86SDimitry Andric if (C != CE) 3282fcaf7f86SDimitry Andric return lowerConstant(C); 3283fcaf7f86SDimitry Andric 3284fcaf7f86SDimitry Andric // Otherwise report the problem to the user. 3285fcaf7f86SDimitry Andric std::string S; 3286fcaf7f86SDimitry Andric raw_string_ostream OS(S); 3287fcaf7f86SDimitry Andric OS << "Unsupported expression in static initializer: "; 3288fcaf7f86SDimitry Andric CE->printAsOperand(OS, /*PrintType=*/false, 3289fcaf7f86SDimitry Andric !MF ? nullptr : MF->getFunction().getParent()); 3290*0fca6ea1SDimitry Andric report_fatal_error(Twine(S)); 32910b57cec5SDimitry Andric } 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andric static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *C, 32940b57cec5SDimitry Andric AsmPrinter &AP, 32950b57cec5SDimitry Andric const Constant *BaseCV = nullptr, 3296753f127fSDimitry Andric uint64_t Offset = 0, 3297753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList = nullptr); 32980b57cec5SDimitry Andric 32990b57cec5SDimitry Andric static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP); 33000b57cec5SDimitry Andric static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP); 33010b57cec5SDimitry Andric 33020b57cec5SDimitry Andric /// isRepeatedByteSequence - Determine whether the given value is 33030b57cec5SDimitry Andric /// composed of a repeated sequence of identical bytes and return the 33040b57cec5SDimitry Andric /// byte value. If it is not a repeated sequence, return -1. 33050b57cec5SDimitry Andric static int isRepeatedByteSequence(const ConstantDataSequential *V) { 33060b57cec5SDimitry Andric StringRef Data = V->getRawDataValues(); 33070b57cec5SDimitry Andric assert(!Data.empty() && "Empty aggregates should be CAZ node"); 33080b57cec5SDimitry Andric char C = Data[0]; 33090b57cec5SDimitry Andric for (unsigned i = 1, e = Data.size(); i != e; ++i) 33100b57cec5SDimitry Andric if (Data[i] != C) return -1; 33110b57cec5SDimitry Andric return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1. 33120b57cec5SDimitry Andric } 33130b57cec5SDimitry Andric 33140b57cec5SDimitry Andric /// isRepeatedByteSequence - Determine whether the given value is 33150b57cec5SDimitry Andric /// composed of a repeated sequence of identical bytes and return the 33160b57cec5SDimitry Andric /// byte value. If it is not a repeated sequence, return -1. 33170b57cec5SDimitry Andric static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) { 33180b57cec5SDimitry Andric if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { 33190b57cec5SDimitry Andric uint64_t Size = DL.getTypeAllocSizeInBits(V->getType()); 33200b57cec5SDimitry Andric assert(Size % 8 == 0); 33210b57cec5SDimitry Andric 33220b57cec5SDimitry Andric // Extend the element to take zero padding into account. 332381ad6265SDimitry Andric APInt Value = CI->getValue().zext(Size); 33240b57cec5SDimitry Andric if (!Value.isSplat(8)) 33250b57cec5SDimitry Andric return -1; 33260b57cec5SDimitry Andric 33270b57cec5SDimitry Andric return Value.zextOrTrunc(8).getZExtValue(); 33280b57cec5SDimitry Andric } 33290b57cec5SDimitry Andric if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) { 33300b57cec5SDimitry Andric // Make sure all array elements are sequences of the same repeated 33310b57cec5SDimitry Andric // byte. 33320b57cec5SDimitry Andric assert(CA->getNumOperands() != 0 && "Should be a CAZ"); 33330b57cec5SDimitry Andric Constant *Op0 = CA->getOperand(0); 33340b57cec5SDimitry Andric int Byte = isRepeatedByteSequence(Op0, DL); 33350b57cec5SDimitry Andric if (Byte == -1) 33360b57cec5SDimitry Andric return -1; 33370b57cec5SDimitry Andric 33380b57cec5SDimitry Andric // All array elements must be equal. 33390b57cec5SDimitry Andric for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) 33400b57cec5SDimitry Andric if (CA->getOperand(i) != Op0) 33410b57cec5SDimitry Andric return -1; 33420b57cec5SDimitry Andric return Byte; 33430b57cec5SDimitry Andric } 33440b57cec5SDimitry Andric 33450b57cec5SDimitry Andric if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V)) 33460b57cec5SDimitry Andric return isRepeatedByteSequence(CDS); 33470b57cec5SDimitry Andric 33480b57cec5SDimitry Andric return -1; 33490b57cec5SDimitry Andric } 33500b57cec5SDimitry Andric 3351753f127fSDimitry Andric static void emitGlobalAliasInline(AsmPrinter &AP, uint64_t Offset, 3352753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList) { 3353753f127fSDimitry Andric if (AliasList) { 3354753f127fSDimitry Andric auto AliasIt = AliasList->find(Offset); 3355753f127fSDimitry Andric if (AliasIt != AliasList->end()) { 3356753f127fSDimitry Andric for (const GlobalAlias *GA : AliasIt->second) 3357753f127fSDimitry Andric AP.OutStreamer->emitLabel(AP.getSymbol(GA)); 3358753f127fSDimitry Andric AliasList->erase(Offset); 3359753f127fSDimitry Andric } 3360753f127fSDimitry Andric } 3361753f127fSDimitry Andric } 3362753f127fSDimitry Andric 3363753f127fSDimitry Andric static void emitGlobalConstantDataSequential( 3364753f127fSDimitry Andric const DataLayout &DL, const ConstantDataSequential *CDS, AsmPrinter &AP, 3365753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList) { 33660b57cec5SDimitry Andric // See if we can aggregate this into a .fill, if so, emit it as such. 33670b57cec5SDimitry Andric int Value = isRepeatedByteSequence(CDS, DL); 33680b57cec5SDimitry Andric if (Value != -1) { 33690b57cec5SDimitry Andric uint64_t Bytes = DL.getTypeAllocSize(CDS->getType()); 33700b57cec5SDimitry Andric // Don't emit a 1-byte object as a .fill. 33710b57cec5SDimitry Andric if (Bytes > 1) 33720b57cec5SDimitry Andric return AP.OutStreamer->emitFill(Bytes, Value); 33730b57cec5SDimitry Andric } 33740b57cec5SDimitry Andric 33750b57cec5SDimitry Andric // If this can be emitted with .ascii/.asciz, emit it as such. 33760b57cec5SDimitry Andric if (CDS->isString()) 33775ffd83dbSDimitry Andric return AP.OutStreamer->emitBytes(CDS->getAsString()); 33780b57cec5SDimitry Andric 33790b57cec5SDimitry Andric // Otherwise, emit the values in successive locations. 33800b57cec5SDimitry Andric unsigned ElementByteSize = CDS->getElementByteSize(); 33810b57cec5SDimitry Andric if (isa<IntegerType>(CDS->getElementType())) { 3382753f127fSDimitry Andric for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { 3383753f127fSDimitry Andric emitGlobalAliasInline(AP, ElementByteSize * I, AliasList); 33840b57cec5SDimitry Andric if (AP.isVerbose()) 338581ad6265SDimitry Andric AP.OutStreamer->getCommentOS() 3386753f127fSDimitry Andric << format("0x%" PRIx64 "\n", CDS->getElementAsInteger(I)); 3387753f127fSDimitry Andric AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(I), 33880b57cec5SDimitry Andric ElementByteSize); 33890b57cec5SDimitry Andric } 33900b57cec5SDimitry Andric } else { 33910b57cec5SDimitry Andric Type *ET = CDS->getElementType(); 3392753f127fSDimitry Andric for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { 3393753f127fSDimitry Andric emitGlobalAliasInline(AP, ElementByteSize * I, AliasList); 33940b57cec5SDimitry Andric emitGlobalConstantFP(CDS->getElementAsAPFloat(I), ET, AP); 33950b57cec5SDimitry Andric } 3396753f127fSDimitry Andric } 33970b57cec5SDimitry Andric 33980b57cec5SDimitry Andric unsigned Size = DL.getTypeAllocSize(CDS->getType()); 33995ffd83dbSDimitry Andric unsigned EmittedSize = 34005ffd83dbSDimitry Andric DL.getTypeAllocSize(CDS->getElementType()) * CDS->getNumElements(); 34010b57cec5SDimitry Andric assert(EmittedSize <= Size && "Size cannot be less than EmittedSize!"); 34020b57cec5SDimitry Andric if (unsigned Padding = Size - EmittedSize) 34035ffd83dbSDimitry Andric AP.OutStreamer->emitZeros(Padding); 34040b57cec5SDimitry Andric } 34050b57cec5SDimitry Andric 34060b57cec5SDimitry Andric static void emitGlobalConstantArray(const DataLayout &DL, 34070b57cec5SDimitry Andric const ConstantArray *CA, AsmPrinter &AP, 3408753f127fSDimitry Andric const Constant *BaseCV, uint64_t Offset, 3409753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList) { 34100b57cec5SDimitry Andric // See if we can aggregate some values. Make sure it can be 34110b57cec5SDimitry Andric // represented as a series of bytes of the constant value. 34120b57cec5SDimitry Andric int Value = isRepeatedByteSequence(CA, DL); 34130b57cec5SDimitry Andric 34140b57cec5SDimitry Andric if (Value != -1) { 34150b57cec5SDimitry Andric uint64_t Bytes = DL.getTypeAllocSize(CA->getType()); 34160b57cec5SDimitry Andric AP.OutStreamer->emitFill(Bytes, Value); 3417753f127fSDimitry Andric } else { 3418753f127fSDimitry Andric for (unsigned I = 0, E = CA->getNumOperands(); I != E; ++I) { 3419753f127fSDimitry Andric emitGlobalConstantImpl(DL, CA->getOperand(I), AP, BaseCV, Offset, 3420753f127fSDimitry Andric AliasList); 3421753f127fSDimitry Andric Offset += DL.getTypeAllocSize(CA->getOperand(I)->getType()); 34220b57cec5SDimitry Andric } 34230b57cec5SDimitry Andric } 34240b57cec5SDimitry Andric } 34250b57cec5SDimitry Andric 3426753f127fSDimitry Andric static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP); 3427753f127fSDimitry Andric 34280b57cec5SDimitry Andric static void emitGlobalConstantVector(const DataLayout &DL, 3429753f127fSDimitry Andric const ConstantVector *CV, AsmPrinter &AP, 3430753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList) { 3431753f127fSDimitry Andric Type *ElementType = CV->getType()->getElementType(); 3432753f127fSDimitry Andric uint64_t ElementSizeInBits = DL.getTypeSizeInBits(ElementType); 3433753f127fSDimitry Andric uint64_t ElementAllocSizeInBits = DL.getTypeAllocSizeInBits(ElementType); 3434753f127fSDimitry Andric uint64_t EmittedSize; 3435753f127fSDimitry Andric if (ElementSizeInBits != ElementAllocSizeInBits) { 3436753f127fSDimitry Andric // If the allocation size of an element is different from the size in bits, 3437753f127fSDimitry Andric // printing each element separately will insert incorrect padding. 3438753f127fSDimitry Andric // 3439753f127fSDimitry Andric // The general algorithm here is complicated; instead of writing it out 3440753f127fSDimitry Andric // here, just use the existing code in ConstantFolding. 3441753f127fSDimitry Andric Type *IntT = 3442753f127fSDimitry Andric IntegerType::get(CV->getContext(), DL.getTypeSizeInBits(CV->getType())); 3443753f127fSDimitry Andric ConstantInt *CI = dyn_cast_or_null<ConstantInt>(ConstantFoldConstant( 3444753f127fSDimitry Andric ConstantExpr::getBitCast(const_cast<ConstantVector *>(CV), IntT), DL)); 3445753f127fSDimitry Andric if (!CI) { 3446753f127fSDimitry Andric report_fatal_error( 3447753f127fSDimitry Andric "Cannot lower vector global with unusual element type"); 3448753f127fSDimitry Andric } 3449753f127fSDimitry Andric emitGlobalAliasInline(AP, 0, AliasList); 3450753f127fSDimitry Andric emitGlobalConstantLargeInt(CI, AP); 3451753f127fSDimitry Andric EmittedSize = DL.getTypeStoreSize(CV->getType()); 3452753f127fSDimitry Andric } else { 3453753f127fSDimitry Andric for (unsigned I = 0, E = CV->getType()->getNumElements(); I != E; ++I) { 3454753f127fSDimitry Andric emitGlobalAliasInline(AP, DL.getTypeAllocSize(CV->getType()) * I, AliasList); 3455753f127fSDimitry Andric emitGlobalConstantImpl(DL, CV->getOperand(I), AP); 3456753f127fSDimitry Andric } 3457753f127fSDimitry Andric EmittedSize = 3458753f127fSDimitry Andric DL.getTypeAllocSize(ElementType) * CV->getType()->getNumElements(); 3459753f127fSDimitry Andric } 34600b57cec5SDimitry Andric 34610b57cec5SDimitry Andric unsigned Size = DL.getTypeAllocSize(CV->getType()); 34620b57cec5SDimitry Andric if (unsigned Padding = Size - EmittedSize) 34635ffd83dbSDimitry Andric AP.OutStreamer->emitZeros(Padding); 34640b57cec5SDimitry Andric } 34650b57cec5SDimitry Andric 34660b57cec5SDimitry Andric static void emitGlobalConstantStruct(const DataLayout &DL, 34670b57cec5SDimitry Andric const ConstantStruct *CS, AsmPrinter &AP, 3468753f127fSDimitry Andric const Constant *BaseCV, uint64_t Offset, 3469753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList) { 34700b57cec5SDimitry Andric // Print the fields in successive locations. Pad to align if needed! 3471*0fca6ea1SDimitry Andric uint64_t Size = DL.getTypeAllocSize(CS->getType()); 34720b57cec5SDimitry Andric const StructLayout *Layout = DL.getStructLayout(CS->getType()); 34730b57cec5SDimitry Andric uint64_t SizeSoFar = 0; 3474753f127fSDimitry Andric for (unsigned I = 0, E = CS->getNumOperands(); I != E; ++I) { 3475753f127fSDimitry Andric const Constant *Field = CS->getOperand(I); 34760b57cec5SDimitry Andric 34770b57cec5SDimitry Andric // Print the actual field value. 3478753f127fSDimitry Andric emitGlobalConstantImpl(DL, Field, AP, BaseCV, Offset + SizeSoFar, 3479753f127fSDimitry Andric AliasList); 34800b57cec5SDimitry Andric 34810b57cec5SDimitry Andric // Check if padding is needed and insert one or more 0s. 34820b57cec5SDimitry Andric uint64_t FieldSize = DL.getTypeAllocSize(Field->getType()); 3483753f127fSDimitry Andric uint64_t PadSize = ((I == E - 1 ? Size : Layout->getElementOffset(I + 1)) - 3484753f127fSDimitry Andric Layout->getElementOffset(I)) - 3485753f127fSDimitry Andric FieldSize; 34860b57cec5SDimitry Andric SizeSoFar += FieldSize + PadSize; 34870b57cec5SDimitry Andric 34880b57cec5SDimitry Andric // Insert padding - this may include padding to increase the size of the 34890b57cec5SDimitry Andric // current field up to the ABI size (if the struct is not packed) as well 34900b57cec5SDimitry Andric // as padding to ensure that the next field starts at the right offset. 34915ffd83dbSDimitry Andric AP.OutStreamer->emitZeros(PadSize); 34920b57cec5SDimitry Andric } 34930b57cec5SDimitry Andric assert(SizeSoFar == Layout->getSizeInBytes() && 34940b57cec5SDimitry Andric "Layout of constant struct may be incorrect!"); 34950b57cec5SDimitry Andric } 34960b57cec5SDimitry Andric 34970b57cec5SDimitry Andric static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) { 34988bcb0991SDimitry Andric assert(ET && "Unknown float type"); 34990b57cec5SDimitry Andric APInt API = APF.bitcastToAPInt(); 35000b57cec5SDimitry Andric 35010b57cec5SDimitry Andric // First print a comment with what we think the original floating-point value 35020b57cec5SDimitry Andric // should have been. 35030b57cec5SDimitry Andric if (AP.isVerbose()) { 35040b57cec5SDimitry Andric SmallString<8> StrVal; 35050b57cec5SDimitry Andric APF.toString(StrVal); 350681ad6265SDimitry Andric ET->print(AP.OutStreamer->getCommentOS()); 350781ad6265SDimitry Andric AP.OutStreamer->getCommentOS() << ' ' << StrVal << '\n'; 35080b57cec5SDimitry Andric } 35090b57cec5SDimitry Andric 35100b57cec5SDimitry Andric // Now iterate through the APInt chunks, emitting them in endian-correct 35110b57cec5SDimitry Andric // order, possibly with a smaller chunk at beginning/end (e.g. for x87 80-bit 35120b57cec5SDimitry Andric // floats). 35130b57cec5SDimitry Andric unsigned NumBytes = API.getBitWidth() / 8; 35140b57cec5SDimitry Andric unsigned TrailingBytes = NumBytes % sizeof(uint64_t); 35150b57cec5SDimitry Andric const uint64_t *p = API.getRawData(); 35160b57cec5SDimitry Andric 35170b57cec5SDimitry Andric // PPC's long double has odd notions of endianness compared to how LLVM 35180b57cec5SDimitry Andric // handles it: p[0] goes first for *big* endian on PPC. 35190b57cec5SDimitry Andric if (AP.getDataLayout().isBigEndian() && !ET->isPPC_FP128Ty()) { 35200b57cec5SDimitry Andric int Chunk = API.getNumWords() - 1; 35210b57cec5SDimitry Andric 35220b57cec5SDimitry Andric if (TrailingBytes) 35235ffd83dbSDimitry Andric AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk--], TrailingBytes); 35240b57cec5SDimitry Andric 35250b57cec5SDimitry Andric for (; Chunk >= 0; --Chunk) 35265ffd83dbSDimitry Andric AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t)); 35270b57cec5SDimitry Andric } else { 35280b57cec5SDimitry Andric unsigned Chunk; 35290b57cec5SDimitry Andric for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk) 35305ffd83dbSDimitry Andric AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t)); 35310b57cec5SDimitry Andric 35320b57cec5SDimitry Andric if (TrailingBytes) 35335ffd83dbSDimitry Andric AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], TrailingBytes); 35340b57cec5SDimitry Andric } 35350b57cec5SDimitry Andric 35360b57cec5SDimitry Andric // Emit the tail padding for the long double. 35370b57cec5SDimitry Andric const DataLayout &DL = AP.getDataLayout(); 35385ffd83dbSDimitry Andric AP.OutStreamer->emitZeros(DL.getTypeAllocSize(ET) - DL.getTypeStoreSize(ET)); 35390b57cec5SDimitry Andric } 35400b57cec5SDimitry Andric 35410b57cec5SDimitry Andric static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) { 35420b57cec5SDimitry Andric emitGlobalConstantFP(CFP->getValueAPF(), CFP->getType(), AP); 35430b57cec5SDimitry Andric } 35440b57cec5SDimitry Andric 35450b57cec5SDimitry Andric static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) { 35460b57cec5SDimitry Andric const DataLayout &DL = AP.getDataLayout(); 35470b57cec5SDimitry Andric unsigned BitWidth = CI->getBitWidth(); 35480b57cec5SDimitry Andric 35490b57cec5SDimitry Andric // Copy the value as we may massage the layout for constants whose bit width 35500b57cec5SDimitry Andric // is not a multiple of 64-bits. 35510b57cec5SDimitry Andric APInt Realigned(CI->getValue()); 35520b57cec5SDimitry Andric uint64_t ExtraBits = 0; 35530b57cec5SDimitry Andric unsigned ExtraBitsSize = BitWidth & 63; 35540b57cec5SDimitry Andric 35550b57cec5SDimitry Andric if (ExtraBitsSize) { 35560b57cec5SDimitry Andric // The bit width of the data is not a multiple of 64-bits. 35570b57cec5SDimitry Andric // The extra bits are expected to be at the end of the chunk of the memory. 35580b57cec5SDimitry Andric // Little endian: 35590b57cec5SDimitry Andric // * Nothing to be done, just record the extra bits to emit. 35600b57cec5SDimitry Andric // Big endian: 35610b57cec5SDimitry Andric // * Record the extra bits to emit. 35620b57cec5SDimitry Andric // * Realign the raw data to emit the chunks of 64-bits. 35630b57cec5SDimitry Andric if (DL.isBigEndian()) { 35640b57cec5SDimitry Andric // Basically the structure of the raw data is a chunk of 64-bits cells: 35650b57cec5SDimitry Andric // 0 1 BitWidth / 64 35660b57cec5SDimitry Andric // [chunk1][chunk2] ... [chunkN]. 35670b57cec5SDimitry Andric // The most significant chunk is chunkN and it should be emitted first. 35680b57cec5SDimitry Andric // However, due to the alignment issue chunkN contains useless bits. 35695ffd83dbSDimitry Andric // Realign the chunks so that they contain only useful information: 35700b57cec5SDimitry Andric // ExtraBits 0 1 (BitWidth / 64) - 1 35710b57cec5SDimitry Andric // chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN] 35725ffd83dbSDimitry Andric ExtraBitsSize = alignTo(ExtraBitsSize, 8); 35730b57cec5SDimitry Andric ExtraBits = Realigned.getRawData()[0] & 35740b57cec5SDimitry Andric (((uint64_t)-1) >> (64 - ExtraBitsSize)); 357506c3fb27SDimitry Andric if (BitWidth >= 64) 35760b57cec5SDimitry Andric Realigned.lshrInPlace(ExtraBitsSize); 35770b57cec5SDimitry Andric } else 35780b57cec5SDimitry Andric ExtraBits = Realigned.getRawData()[BitWidth / 64]; 35790b57cec5SDimitry Andric } 35800b57cec5SDimitry Andric 35810b57cec5SDimitry Andric // We don't expect assemblers to support integer data directives 35820b57cec5SDimitry Andric // for more than 64 bits, so we emit the data in at most 64-bit 35830b57cec5SDimitry Andric // quantities at a time. 35840b57cec5SDimitry Andric const uint64_t *RawData = Realigned.getRawData(); 35850b57cec5SDimitry Andric for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { 35860b57cec5SDimitry Andric uint64_t Val = DL.isBigEndian() ? RawData[e - i - 1] : RawData[i]; 35875ffd83dbSDimitry Andric AP.OutStreamer->emitIntValue(Val, 8); 35880b57cec5SDimitry Andric } 35890b57cec5SDimitry Andric 35900b57cec5SDimitry Andric if (ExtraBitsSize) { 35910b57cec5SDimitry Andric // Emit the extra bits after the 64-bits chunks. 35920b57cec5SDimitry Andric 35930b57cec5SDimitry Andric // Emit a directive that fills the expected size. 35945ffd83dbSDimitry Andric uint64_t Size = AP.getDataLayout().getTypeStoreSize(CI->getType()); 35950b57cec5SDimitry Andric Size -= (BitWidth / 64) * 8; 35960b57cec5SDimitry Andric assert(Size && Size * 8 >= ExtraBitsSize && 35970b57cec5SDimitry Andric (ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize))) 35980b57cec5SDimitry Andric == ExtraBits && "Directive too small for extra bits."); 35995ffd83dbSDimitry Andric AP.OutStreamer->emitIntValue(ExtraBits, Size); 36000b57cec5SDimitry Andric } 36010b57cec5SDimitry Andric } 36020b57cec5SDimitry Andric 36030b57cec5SDimitry Andric /// Transform a not absolute MCExpr containing a reference to a GOT 36040b57cec5SDimitry Andric /// equivalent global, by a target specific GOT pc relative access to the 36050b57cec5SDimitry Andric /// final symbol. 36060b57cec5SDimitry Andric static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, 36070b57cec5SDimitry Andric const Constant *BaseCst, 36080b57cec5SDimitry Andric uint64_t Offset) { 36090b57cec5SDimitry Andric // The global @foo below illustrates a global that uses a got equivalent. 36100b57cec5SDimitry Andric // 36110b57cec5SDimitry Andric // @bar = global i32 42 36120b57cec5SDimitry Andric // @gotequiv = private unnamed_addr constant i32* @bar 36130b57cec5SDimitry Andric // @foo = i32 trunc (i64 sub (i64 ptrtoint (i32** @gotequiv to i64), 36140b57cec5SDimitry Andric // i64 ptrtoint (i32* @foo to i64)) 36150b57cec5SDimitry Andric // to i32) 36160b57cec5SDimitry Andric // 36170b57cec5SDimitry Andric // The cstexpr in @foo is converted into the MCExpr `ME`, where we actually 36180b57cec5SDimitry Andric // check whether @foo is suitable to use a GOTPCREL. `ME` is usually in the 36190b57cec5SDimitry Andric // form: 36200b57cec5SDimitry Andric // 36210b57cec5SDimitry Andric // foo = cstexpr, where 36220b57cec5SDimitry Andric // cstexpr := <gotequiv> - "." + <cst> 36230b57cec5SDimitry Andric // cstexpr := <gotequiv> - (<foo> - <offset from @foo base>) + <cst> 36240b57cec5SDimitry Andric // 36250b57cec5SDimitry Andric // After canonicalization by evaluateAsRelocatable `ME` turns into: 36260b57cec5SDimitry Andric // 36270b57cec5SDimitry Andric // cstexpr := <gotequiv> - <foo> + gotpcrelcst, where 36280b57cec5SDimitry Andric // gotpcrelcst := <offset from @foo base> + <cst> 36290b57cec5SDimitry Andric MCValue MV; 36300b57cec5SDimitry Andric if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute()) 36310b57cec5SDimitry Andric return; 36320b57cec5SDimitry Andric const MCSymbolRefExpr *SymA = MV.getSymA(); 36330b57cec5SDimitry Andric if (!SymA) 36340b57cec5SDimitry Andric return; 36350b57cec5SDimitry Andric 36360b57cec5SDimitry Andric // Check that GOT equivalent symbol is cached. 36370b57cec5SDimitry Andric const MCSymbol *GOTEquivSym = &SymA->getSymbol(); 36380b57cec5SDimitry Andric if (!AP.GlobalGOTEquivs.count(GOTEquivSym)) 36390b57cec5SDimitry Andric return; 36400b57cec5SDimitry Andric 36410b57cec5SDimitry Andric const GlobalValue *BaseGV = dyn_cast_or_null<GlobalValue>(BaseCst); 36420b57cec5SDimitry Andric if (!BaseGV) 36430b57cec5SDimitry Andric return; 36440b57cec5SDimitry Andric 36450b57cec5SDimitry Andric // Check for a valid base symbol 36460b57cec5SDimitry Andric const MCSymbol *BaseSym = AP.getSymbol(BaseGV); 36470b57cec5SDimitry Andric const MCSymbolRefExpr *SymB = MV.getSymB(); 36480b57cec5SDimitry Andric 36490b57cec5SDimitry Andric if (!SymB || BaseSym != &SymB->getSymbol()) 36500b57cec5SDimitry Andric return; 36510b57cec5SDimitry Andric 36520b57cec5SDimitry Andric // Make sure to match: 36530b57cec5SDimitry Andric // 36540b57cec5SDimitry Andric // gotpcrelcst := <offset from @foo base> + <cst> 36550b57cec5SDimitry Andric // 36560b57cec5SDimitry Andric int64_t GOTPCRelCst = Offset + MV.getConstant(); 36570b57cec5SDimitry Andric if (!AP.getObjFileLowering().supportGOTPCRelWithOffset() && GOTPCRelCst != 0) 36580b57cec5SDimitry Andric return; 36590b57cec5SDimitry Andric 36600b57cec5SDimitry Andric // Emit the GOT PC relative to replace the got equivalent global, i.e.: 36610b57cec5SDimitry Andric // 36620b57cec5SDimitry Andric // bar: 36630b57cec5SDimitry Andric // .long 42 36640b57cec5SDimitry Andric // gotequiv: 36650b57cec5SDimitry Andric // .quad bar 36660b57cec5SDimitry Andric // foo: 36670b57cec5SDimitry Andric // .long gotequiv - "." + <cst> 36680b57cec5SDimitry Andric // 36690b57cec5SDimitry Andric // is replaced by the target specific equivalent to: 36700b57cec5SDimitry Andric // 36710b57cec5SDimitry Andric // bar: 36720b57cec5SDimitry Andric // .long 42 36730b57cec5SDimitry Andric // foo: 36740b57cec5SDimitry Andric // .long bar@GOTPCREL+<gotpcrelcst> 36750b57cec5SDimitry Andric AsmPrinter::GOTEquivUsePair Result = AP.GlobalGOTEquivs[GOTEquivSym]; 36760b57cec5SDimitry Andric const GlobalVariable *GV = Result.first; 36770b57cec5SDimitry Andric int NumUses = (int)Result.second; 36780b57cec5SDimitry Andric const GlobalValue *FinalGV = dyn_cast<GlobalValue>(GV->getOperand(0)); 36790b57cec5SDimitry Andric const MCSymbol *FinalSym = AP.getSymbol(FinalGV); 36800b57cec5SDimitry Andric *ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel( 36818bcb0991SDimitry Andric FinalGV, FinalSym, MV, Offset, AP.MMI, *AP.OutStreamer); 36820b57cec5SDimitry Andric 36830b57cec5SDimitry Andric // Update GOT equivalent usage information 36840b57cec5SDimitry Andric --NumUses; 36850b57cec5SDimitry Andric if (NumUses >= 0) 36860b57cec5SDimitry Andric AP.GlobalGOTEquivs[GOTEquivSym] = std::make_pair(GV, NumUses); 36870b57cec5SDimitry Andric } 36880b57cec5SDimitry Andric 36890b57cec5SDimitry Andric static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, 36900b57cec5SDimitry Andric AsmPrinter &AP, const Constant *BaseCV, 3691753f127fSDimitry Andric uint64_t Offset, 3692753f127fSDimitry Andric AsmPrinter::AliasMapTy *AliasList) { 3693753f127fSDimitry Andric emitGlobalAliasInline(AP, Offset, AliasList); 36940b57cec5SDimitry Andric uint64_t Size = DL.getTypeAllocSize(CV->getType()); 36950b57cec5SDimitry Andric 36960b57cec5SDimitry Andric // Globals with sub-elements such as combinations of arrays and structs 36970b57cec5SDimitry Andric // are handled recursively by emitGlobalConstantImpl. Keep track of the 36980b57cec5SDimitry Andric // constant symbol base and the current position with BaseCV and Offset. 36990b57cec5SDimitry Andric if (!BaseCV && CV->hasOneUse()) 37000b57cec5SDimitry Andric BaseCV = dyn_cast<Constant>(CV->user_back()); 37010b57cec5SDimitry Andric 37020b57cec5SDimitry Andric if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) 37035ffd83dbSDimitry Andric return AP.OutStreamer->emitZeros(Size); 37040b57cec5SDimitry Andric 37050b57cec5SDimitry Andric if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 37065ffd83dbSDimitry Andric const uint64_t StoreSize = DL.getTypeStoreSize(CV->getType()); 37075ffd83dbSDimitry Andric 37088833aad7SDimitry Andric if (StoreSize <= 8) { 37090b57cec5SDimitry Andric if (AP.isVerbose()) 371081ad6265SDimitry Andric AP.OutStreamer->getCommentOS() 371181ad6265SDimitry Andric << format("0x%" PRIx64 "\n", CI->getZExtValue()); 37125ffd83dbSDimitry Andric AP.OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize); 37135ffd83dbSDimitry Andric } else { 37140b57cec5SDimitry Andric emitGlobalConstantLargeInt(CI, AP); 37150b57cec5SDimitry Andric } 37165ffd83dbSDimitry Andric 37175ffd83dbSDimitry Andric // Emit tail padding if needed 37185ffd83dbSDimitry Andric if (Size != StoreSize) 37195ffd83dbSDimitry Andric AP.OutStreamer->emitZeros(Size - StoreSize); 37205ffd83dbSDimitry Andric 37215ffd83dbSDimitry Andric return; 37220b57cec5SDimitry Andric } 37230b57cec5SDimitry Andric 37240b57cec5SDimitry Andric if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) 37250b57cec5SDimitry Andric return emitGlobalConstantFP(CFP, AP); 37260b57cec5SDimitry Andric 37270b57cec5SDimitry Andric if (isa<ConstantPointerNull>(CV)) { 37285ffd83dbSDimitry Andric AP.OutStreamer->emitIntValue(0, Size); 37290b57cec5SDimitry Andric return; 37300b57cec5SDimitry Andric } 37310b57cec5SDimitry Andric 37320b57cec5SDimitry Andric if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV)) 3733753f127fSDimitry Andric return emitGlobalConstantDataSequential(DL, CDS, AP, AliasList); 37340b57cec5SDimitry Andric 37350b57cec5SDimitry Andric if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) 3736753f127fSDimitry Andric return emitGlobalConstantArray(DL, CVA, AP, BaseCV, Offset, AliasList); 37370b57cec5SDimitry Andric 37380b57cec5SDimitry Andric if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) 3739753f127fSDimitry Andric return emitGlobalConstantStruct(DL, CVS, AP, BaseCV, Offset, AliasList); 37400b57cec5SDimitry Andric 37410b57cec5SDimitry Andric if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { 37420b57cec5SDimitry Andric // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of 37430b57cec5SDimitry Andric // vectors). 37440b57cec5SDimitry Andric if (CE->getOpcode() == Instruction::BitCast) 37450b57cec5SDimitry Andric return emitGlobalConstantImpl(DL, CE->getOperand(0), AP); 37460b57cec5SDimitry Andric 37470b57cec5SDimitry Andric if (Size > 8) { 37480b57cec5SDimitry Andric // If the constant expression's size is greater than 64-bits, then we have 37490b57cec5SDimitry Andric // to emit the value in chunks. Try to constant fold the value and emit it 37500b57cec5SDimitry Andric // that way. 37510b57cec5SDimitry Andric Constant *New = ConstantFoldConstant(CE, DL); 37525ffd83dbSDimitry Andric if (New != CE) 37530b57cec5SDimitry Andric return emitGlobalConstantImpl(DL, New, AP); 37540b57cec5SDimitry Andric } 37550b57cec5SDimitry Andric } 37560b57cec5SDimitry Andric 37570b57cec5SDimitry Andric if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) 3758753f127fSDimitry Andric return emitGlobalConstantVector(DL, V, AP, AliasList); 37590b57cec5SDimitry Andric 37600b57cec5SDimitry Andric // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it 37610b57cec5SDimitry Andric // thread the streamer with EmitValue. 37620b57cec5SDimitry Andric const MCExpr *ME = AP.lowerConstant(CV); 37630b57cec5SDimitry Andric 37640b57cec5SDimitry Andric // Since lowerConstant already folded and got rid of all IR pointer and 37650b57cec5SDimitry Andric // integer casts, detect GOT equivalent accesses by looking into the MCExpr 37660b57cec5SDimitry Andric // directly. 37670b57cec5SDimitry Andric if (AP.getObjFileLowering().supportIndirectSymViaGOTPCRel()) 37680b57cec5SDimitry Andric handleIndirectSymViaGOTPCRel(AP, &ME, BaseCV, Offset); 37690b57cec5SDimitry Andric 37705ffd83dbSDimitry Andric AP.OutStreamer->emitValue(ME, Size); 37710b57cec5SDimitry Andric } 37720b57cec5SDimitry Andric 37730b57cec5SDimitry Andric /// EmitGlobalConstant - Print a general LLVM constant to the .s file. 3774753f127fSDimitry Andric void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV, 3775753f127fSDimitry Andric AliasMapTy *AliasList) { 37760b57cec5SDimitry Andric uint64_t Size = DL.getTypeAllocSize(CV->getType()); 37770b57cec5SDimitry Andric if (Size) 3778753f127fSDimitry Andric emitGlobalConstantImpl(DL, CV, *this, nullptr, 0, AliasList); 37790b57cec5SDimitry Andric else if (MAI->hasSubsectionsViaSymbols()) { 37800b57cec5SDimitry Andric // If the global has zero size, emit a single byte so that two labels don't 37810b57cec5SDimitry Andric // look like they are at the same location. 37825ffd83dbSDimitry Andric OutStreamer->emitIntValue(0, 1); 37830b57cec5SDimitry Andric } 3784753f127fSDimitry Andric if (!AliasList) 3785753f127fSDimitry Andric return; 3786fcaf7f86SDimitry Andric // TODO: These remaining aliases are not emitted in the correct location. Need 3787fcaf7f86SDimitry Andric // to handle the case where the alias offset doesn't refer to any sub-element. 3788fcaf7f86SDimitry Andric for (auto &AliasPair : *AliasList) { 3789fcaf7f86SDimitry Andric for (const GlobalAlias *GA : AliasPair.second) 3790fcaf7f86SDimitry Andric OutStreamer->emitLabel(getSymbol(GA)); 3791fcaf7f86SDimitry Andric } 37920b57cec5SDimitry Andric } 37930b57cec5SDimitry Andric 37945ffd83dbSDimitry Andric void AsmPrinter::emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 37950b57cec5SDimitry Andric // Target doesn't support this yet! 37960b57cec5SDimitry Andric llvm_unreachable("Target does not support EmitMachineConstantPoolValue"); 37970b57cec5SDimitry Andric } 37980b57cec5SDimitry Andric 37990b57cec5SDimitry Andric void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { 38000b57cec5SDimitry Andric if (Offset > 0) 38010b57cec5SDimitry Andric OS << '+' << Offset; 38020b57cec5SDimitry Andric else if (Offset < 0) 38030b57cec5SDimitry Andric OS << Offset; 38040b57cec5SDimitry Andric } 38050b57cec5SDimitry Andric 380655e4f9d5SDimitry Andric void AsmPrinter::emitNops(unsigned N) { 3807fe6060f1SDimitry Andric MCInst Nop = MF->getSubtarget().getInstrInfo()->getNop(); 380855e4f9d5SDimitry Andric for (; N; --N) 380955e4f9d5SDimitry Andric EmitToStreamer(*OutStreamer, Nop); 381055e4f9d5SDimitry Andric } 381155e4f9d5SDimitry Andric 38120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 38130b57cec5SDimitry Andric // Symbol Lowering Routines. 38140b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 38150b57cec5SDimitry Andric 38160b57cec5SDimitry Andric MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const { 38170b57cec5SDimitry Andric return OutContext.createTempSymbol(Name, true); 38180b57cec5SDimitry Andric } 38190b57cec5SDimitry Andric 38200b57cec5SDimitry Andric MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { 382181ad6265SDimitry Andric return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol( 382281ad6265SDimitry Andric BA->getBasicBlock()); 38230b57cec5SDimitry Andric } 38240b57cec5SDimitry Andric 38250b57cec5SDimitry Andric MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { 382681ad6265SDimitry Andric return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB); 38270b57cec5SDimitry Andric } 38280b57cec5SDimitry Andric 3829*0fca6ea1SDimitry Andric const MCExpr *AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) { 3830*0fca6ea1SDimitry Andric return MCSymbolRefExpr::create(GetBlockAddressSymbol(&BA), OutContext); 3831*0fca6ea1SDimitry Andric } 3832*0fca6ea1SDimitry Andric 38330b57cec5SDimitry Andric /// GetCPISymbol - Return the symbol for the specified constant pool entry. 38340b57cec5SDimitry Andric MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { 38350b57cec5SDimitry Andric if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment()) { 38360b57cec5SDimitry Andric const MachineConstantPoolEntry &CPE = 38370b57cec5SDimitry Andric MF->getConstantPool()->getConstants()[CPID]; 38380b57cec5SDimitry Andric if (!CPE.isMachineConstantPoolEntry()) { 38390b57cec5SDimitry Andric const DataLayout &DL = MF->getDataLayout(); 38400b57cec5SDimitry Andric SectionKind Kind = CPE.getSectionKind(&DL); 38410b57cec5SDimitry Andric const Constant *C = CPE.Val.ConstVal; 38425ffd83dbSDimitry Andric Align Alignment = CPE.Alignment; 38430b57cec5SDimitry Andric if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>( 38445ffd83dbSDimitry Andric getObjFileLowering().getSectionForConstant(DL, Kind, C, 38455ffd83dbSDimitry Andric Alignment))) { 38460b57cec5SDimitry Andric if (MCSymbol *Sym = S->getCOMDATSymbol()) { 38470b57cec5SDimitry Andric if (Sym->isUndefined()) 38485ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(Sym, MCSA_Global); 38490b57cec5SDimitry Andric return Sym; 38500b57cec5SDimitry Andric } 38510b57cec5SDimitry Andric } 38520b57cec5SDimitry Andric } 38530b57cec5SDimitry Andric } 38540b57cec5SDimitry Andric 38550b57cec5SDimitry Andric const DataLayout &DL = getDataLayout(); 38560b57cec5SDimitry Andric return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 38570b57cec5SDimitry Andric "CPI" + Twine(getFunctionNumber()) + "_" + 38580b57cec5SDimitry Andric Twine(CPID)); 38590b57cec5SDimitry Andric } 38600b57cec5SDimitry Andric 38610b57cec5SDimitry Andric /// GetJTISymbol - Return the symbol for the specified jump table entry. 38620b57cec5SDimitry Andric MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { 38630b57cec5SDimitry Andric return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate); 38640b57cec5SDimitry Andric } 38650b57cec5SDimitry Andric 38660b57cec5SDimitry Andric /// GetJTSetSymbol - Return the symbol for the specified jump table .set 38670b57cec5SDimitry Andric /// FIXME: privatize to AsmPrinter. 38680b57cec5SDimitry Andric MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { 38690b57cec5SDimitry Andric const DataLayout &DL = getDataLayout(); 38700b57cec5SDimitry Andric return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) + 38710b57cec5SDimitry Andric Twine(getFunctionNumber()) + "_" + 38720b57cec5SDimitry Andric Twine(UID) + "_set_" + Twine(MBBID)); 38730b57cec5SDimitry Andric } 38740b57cec5SDimitry Andric 38750b57cec5SDimitry Andric MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV, 38760b57cec5SDimitry Andric StringRef Suffix) const { 38770b57cec5SDimitry Andric return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, TM); 38780b57cec5SDimitry Andric } 38790b57cec5SDimitry Andric 38800b57cec5SDimitry Andric /// Return the MCSymbol for the specified ExternalSymbol. 38815f757f3fSDimitry Andric MCSymbol *AsmPrinter::GetExternalSymbolSymbol(Twine Sym) const { 38820b57cec5SDimitry Andric SmallString<60> NameStr; 38830b57cec5SDimitry Andric Mangler::getNameWithPrefix(NameStr, Sym, getDataLayout()); 38840b57cec5SDimitry Andric return OutContext.getOrCreateSymbol(NameStr); 38850b57cec5SDimitry Andric } 38860b57cec5SDimitry Andric 38870b57cec5SDimitry Andric /// PrintParentLoopComment - Print comments about parent loops of this one. 38880b57cec5SDimitry Andric static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, 38890b57cec5SDimitry Andric unsigned FunctionNumber) { 38900b57cec5SDimitry Andric if (!Loop) return; 38910b57cec5SDimitry Andric PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber); 38920b57cec5SDimitry Andric OS.indent(Loop->getLoopDepth()*2) 38930b57cec5SDimitry Andric << "Parent Loop BB" << FunctionNumber << "_" 38940b57cec5SDimitry Andric << Loop->getHeader()->getNumber() 38950b57cec5SDimitry Andric << " Depth=" << Loop->getLoopDepth() << '\n'; 38960b57cec5SDimitry Andric } 38970b57cec5SDimitry Andric 38980b57cec5SDimitry Andric /// PrintChildLoopComment - Print comments about child loops within 38990b57cec5SDimitry Andric /// the loop for this basic block, with nesting. 39000b57cec5SDimitry Andric static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, 39010b57cec5SDimitry Andric unsigned FunctionNumber) { 39020b57cec5SDimitry Andric // Add child loop information 39030b57cec5SDimitry Andric for (const MachineLoop *CL : *Loop) { 39040b57cec5SDimitry Andric OS.indent(CL->getLoopDepth()*2) 39050b57cec5SDimitry Andric << "Child Loop BB" << FunctionNumber << "_" 39060b57cec5SDimitry Andric << CL->getHeader()->getNumber() << " Depth " << CL->getLoopDepth() 39070b57cec5SDimitry Andric << '\n'; 39080b57cec5SDimitry Andric PrintChildLoopComment(OS, CL, FunctionNumber); 39090b57cec5SDimitry Andric } 39100b57cec5SDimitry Andric } 39110b57cec5SDimitry Andric 39120b57cec5SDimitry Andric /// emitBasicBlockLoopComments - Pretty-print comments for basic blocks. 39130b57cec5SDimitry Andric static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB, 39140b57cec5SDimitry Andric const MachineLoopInfo *LI, 39150b57cec5SDimitry Andric const AsmPrinter &AP) { 39160b57cec5SDimitry Andric // Add loop depth information 39170b57cec5SDimitry Andric const MachineLoop *Loop = LI->getLoopFor(&MBB); 39180b57cec5SDimitry Andric if (!Loop) return; 39190b57cec5SDimitry Andric 39200b57cec5SDimitry Andric MachineBasicBlock *Header = Loop->getHeader(); 39210b57cec5SDimitry Andric assert(Header && "No header for loop"); 39220b57cec5SDimitry Andric 39230b57cec5SDimitry Andric // If this block is not a loop header, just print out what is the loop header 39240b57cec5SDimitry Andric // and return. 39250b57cec5SDimitry Andric if (Header != &MBB) { 39260b57cec5SDimitry Andric AP.OutStreamer->AddComment(" in Loop: Header=BB" + 39270b57cec5SDimitry Andric Twine(AP.getFunctionNumber())+"_" + 39280b57cec5SDimitry Andric Twine(Loop->getHeader()->getNumber())+ 39290b57cec5SDimitry Andric " Depth="+Twine(Loop->getLoopDepth())); 39300b57cec5SDimitry Andric return; 39310b57cec5SDimitry Andric } 39320b57cec5SDimitry Andric 39330b57cec5SDimitry Andric // Otherwise, it is a loop header. Print out information about child and 39340b57cec5SDimitry Andric // parent loops. 393581ad6265SDimitry Andric raw_ostream &OS = AP.OutStreamer->getCommentOS(); 39360b57cec5SDimitry Andric 39370b57cec5SDimitry Andric PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); 39380b57cec5SDimitry Andric 39390b57cec5SDimitry Andric OS << "=>"; 39400b57cec5SDimitry Andric OS.indent(Loop->getLoopDepth()*2-2); 39410b57cec5SDimitry Andric 39420b57cec5SDimitry Andric OS << "This "; 3943e8d8bef9SDimitry Andric if (Loop->isInnermost()) 39440b57cec5SDimitry Andric OS << "Inner "; 39450b57cec5SDimitry Andric OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; 39460b57cec5SDimitry Andric 39470b57cec5SDimitry Andric PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); 39480b57cec5SDimitry Andric } 39490b57cec5SDimitry Andric 39505ffd83dbSDimitry Andric /// emitBasicBlockStart - This method prints the label for the specified 39510b57cec5SDimitry Andric /// MachineBasicBlock, an alignment (if present) and a comment describing 39520b57cec5SDimitry Andric /// it if appropriate. 39535ffd83dbSDimitry Andric void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) { 39540b57cec5SDimitry Andric // End the previous funclet and start a new one. 39550b57cec5SDimitry Andric if (MBB.isEHFuncletEntry()) { 3956*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) { 3957*0fca6ea1SDimitry Andric Handler->endFunclet(); 3958*0fca6ea1SDimitry Andric Handler->beginFunclet(MBB); 39590b57cec5SDimitry Andric } 39600b57cec5SDimitry Andric } 39610b57cec5SDimitry Andric 3962e8d8bef9SDimitry Andric // Switch to a new section if this basic block must begin a section. The 3963e8d8bef9SDimitry Andric // entry block is always placed in the function section and is handled 3964e8d8bef9SDimitry Andric // separately. 3965e8d8bef9SDimitry Andric if (MBB.isBeginSection() && !MBB.isEntryBlock()) { 396681ad6265SDimitry Andric OutStreamer->switchSection( 3967e8d8bef9SDimitry Andric getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(), 3968e8d8bef9SDimitry Andric MBB, TM)); 3969e8d8bef9SDimitry Andric CurrentSectionBeginSym = MBB.getSymbol(); 3970e8d8bef9SDimitry Andric } 3971e8d8bef9SDimitry Andric 3972bdd1243dSDimitry Andric // Emit an alignment directive for this block, if needed. 3973bdd1243dSDimitry Andric const Align Alignment = MBB.getAlignment(); 3974bdd1243dSDimitry Andric if (Alignment != Align(1)) 3975bdd1243dSDimitry Andric emitAlignment(Alignment, nullptr, MBB.getMaxBytesForAlignment()); 3976bdd1243dSDimitry Andric 39770b57cec5SDimitry Andric // If the block has its address taken, emit any labels that were used to 39780b57cec5SDimitry Andric // reference the block. It is possible that there is more than one label 39790b57cec5SDimitry Andric // here, because multiple LLVM BB's may have been RAUW'd to this block after 39800b57cec5SDimitry Andric // the references were generated. 3981bdd1243dSDimitry Andric if (MBB.isIRBlockAddressTaken()) { 39820b57cec5SDimitry Andric if (isVerbose()) 39830b57cec5SDimitry Andric OutStreamer->AddComment("Block address taken"); 39840b57cec5SDimitry Andric 3985bdd1243dSDimitry Andric BasicBlock *BB = MBB.getAddressTakenIRBlock(); 3986bdd1243dSDimitry Andric assert(BB && BB->hasAddressTaken() && "Missing BB"); 398781ad6265SDimitry Andric for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB)) 39885ffd83dbSDimitry Andric OutStreamer->emitLabel(Sym); 3989bdd1243dSDimitry Andric } else if (isVerbose() && MBB.isMachineBlockAddressTaken()) { 3990bdd1243dSDimitry Andric OutStreamer->AddComment("Block address taken"); 39910b57cec5SDimitry Andric } 39920b57cec5SDimitry Andric 39930b57cec5SDimitry Andric // Print some verbose block comments. 39940b57cec5SDimitry Andric if (isVerbose()) { 3995bdd1243dSDimitry Andric if (const BasicBlock *BB = MBB.getBasicBlock()) { 39960b57cec5SDimitry Andric if (BB->hasName()) { 399781ad6265SDimitry Andric BB->printAsOperand(OutStreamer->getCommentOS(), 39980b57cec5SDimitry Andric /*PrintType=*/false, BB->getModule()); 399981ad6265SDimitry Andric OutStreamer->getCommentOS() << '\n'; 40000b57cec5SDimitry Andric } 40010b57cec5SDimitry Andric } 40020b57cec5SDimitry Andric 40030b57cec5SDimitry Andric assert(MLI != nullptr && "MachineLoopInfo should has been computed"); 40040b57cec5SDimitry Andric emitBasicBlockLoopComments(MBB, MLI, *this); 40050b57cec5SDimitry Andric } 40060b57cec5SDimitry Andric 4007e8d8bef9SDimitry Andric // Print the main label for the block. 4008e8d8bef9SDimitry Andric if (shouldEmitLabelForBasicBlock(MBB)) { 4009e8d8bef9SDimitry Andric if (isVerbose() && MBB.hasLabelMustBeEmitted()) 4010e8d8bef9SDimitry Andric OutStreamer->AddComment("Label of block must be emitted"); 4011e8d8bef9SDimitry Andric OutStreamer->emitLabel(MBB.getSymbol()); 4012e8d8bef9SDimitry Andric } else { 40130b57cec5SDimitry Andric if (isVerbose()) { 40140b57cec5SDimitry Andric // NOTE: Want this comment at start of line, don't emit with AddComment. 40150b57cec5SDimitry Andric OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":", 40160b57cec5SDimitry Andric false); 40170b57cec5SDimitry Andric } 40185ffd83dbSDimitry Andric } 4019e8d8bef9SDimitry Andric 4020fe6060f1SDimitry Andric if (MBB.isEHCatchretTarget() && 4021fe6060f1SDimitry Andric MAI->getExceptionHandlingType() == ExceptionHandling::WinEH) { 4022fe6060f1SDimitry Andric OutStreamer->emitLabel(MBB.getEHCatchretSymbol()); 4023fe6060f1SDimitry Andric } 4024fe6060f1SDimitry Andric 40255ffd83dbSDimitry Andric // With BB sections, each basic block must handle CFI information on its own 4026bdd1243dSDimitry Andric // if it begins a section (Entry block call is handled separately, next to 4027bdd1243dSDimitry Andric // beginFunction). 4028*0fca6ea1SDimitry Andric if (MBB.isBeginSection() && !MBB.isEntryBlock()) { 4029*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 4030*0fca6ea1SDimitry Andric Handler->beginBasicBlockSection(MBB); 4031*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 4032*0fca6ea1SDimitry Andric Handler->beginBasicBlockSection(MBB); 4033*0fca6ea1SDimitry Andric } 40340b57cec5SDimitry Andric } 40350b57cec5SDimitry Andric 40365ffd83dbSDimitry Andric void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) { 40375ffd83dbSDimitry Andric // Check if CFI information needs to be updated for this MBB with basic block 40385ffd83dbSDimitry Andric // sections. 4039*0fca6ea1SDimitry Andric if (MBB.isEndSection()) { 4040*0fca6ea1SDimitry Andric for (auto &Handler : DebugHandlers) 4041*0fca6ea1SDimitry Andric Handler->endBasicBlockSection(MBB); 4042*0fca6ea1SDimitry Andric for (auto &Handler : Handlers) 4043*0fca6ea1SDimitry Andric Handler->endBasicBlockSection(MBB); 4044*0fca6ea1SDimitry Andric } 40455ffd83dbSDimitry Andric } 40460b57cec5SDimitry Andric 40475ffd83dbSDimitry Andric void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility, 40480b57cec5SDimitry Andric bool IsDefinition) const { 40490b57cec5SDimitry Andric MCSymbolAttr Attr = MCSA_Invalid; 40500b57cec5SDimitry Andric 40510b57cec5SDimitry Andric switch (Visibility) { 40520b57cec5SDimitry Andric default: break; 40530b57cec5SDimitry Andric case GlobalValue::HiddenVisibility: 40540b57cec5SDimitry Andric if (IsDefinition) 40550b57cec5SDimitry Andric Attr = MAI->getHiddenVisibilityAttr(); 40560b57cec5SDimitry Andric else 40570b57cec5SDimitry Andric Attr = MAI->getHiddenDeclarationVisibilityAttr(); 40580b57cec5SDimitry Andric break; 40590b57cec5SDimitry Andric case GlobalValue::ProtectedVisibility: 40600b57cec5SDimitry Andric Attr = MAI->getProtectedVisibilityAttr(); 40610b57cec5SDimitry Andric break; 40620b57cec5SDimitry Andric } 40630b57cec5SDimitry Andric 40640b57cec5SDimitry Andric if (Attr != MCSA_Invalid) 40655ffd83dbSDimitry Andric OutStreamer->emitSymbolAttribute(Sym, Attr); 40660b57cec5SDimitry Andric } 40670b57cec5SDimitry Andric 4068e8d8bef9SDimitry Andric bool AsmPrinter::shouldEmitLabelForBasicBlock( 4069e8d8bef9SDimitry Andric const MachineBasicBlock &MBB) const { 4070e8d8bef9SDimitry Andric // With `-fbasic-block-sections=`, a label is needed for every non-entry block 4071e8d8bef9SDimitry Andric // in the labels mode (option `=labels`) and every section beginning in the 4072e8d8bef9SDimitry Andric // sections mode (`=all` and `=list=`). 4073*0fca6ea1SDimitry Andric if ((MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap || 4074*0fca6ea1SDimitry Andric MBB.isBeginSection()) && 4075*0fca6ea1SDimitry Andric !MBB.isEntryBlock()) 4076e8d8bef9SDimitry Andric return true; 4077e8d8bef9SDimitry Andric // A label is needed for any block with at least one predecessor (when that 4078e8d8bef9SDimitry Andric // predecessor is not the fallthrough predecessor, or if it is an EH funclet 4079e8d8bef9SDimitry Andric // entry, or if a label is forced). 4080e8d8bef9SDimitry Andric return !MBB.pred_empty() && 4081e8d8bef9SDimitry Andric (!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() || 4082e8d8bef9SDimitry Andric MBB.hasLabelMustBeEmitted()); 4083e8d8bef9SDimitry Andric } 4084e8d8bef9SDimitry Andric 40850b57cec5SDimitry Andric /// isBlockOnlyReachableByFallthough - Return true if the basic block has 40860b57cec5SDimitry Andric /// exactly one predecessor and the control transfer mechanism between 40870b57cec5SDimitry Andric /// the predecessor and this block is a fall-through. 40880b57cec5SDimitry Andric bool AsmPrinter:: 40890b57cec5SDimitry Andric isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { 40900b57cec5SDimitry Andric // If this is a landing pad, it isn't a fall through. If it has no preds, 40910b57cec5SDimitry Andric // then nothing falls through to it. 40920b57cec5SDimitry Andric if (MBB->isEHPad() || MBB->pred_empty()) 40930b57cec5SDimitry Andric return false; 40940b57cec5SDimitry Andric 40950b57cec5SDimitry Andric // If there isn't exactly one predecessor, it can't be a fall through. 40960b57cec5SDimitry Andric if (MBB->pred_size() > 1) 40970b57cec5SDimitry Andric return false; 40980b57cec5SDimitry Andric 40990b57cec5SDimitry Andric // The predecessor has to be immediately before this block. 41000b57cec5SDimitry Andric MachineBasicBlock *Pred = *MBB->pred_begin(); 41010b57cec5SDimitry Andric if (!Pred->isLayoutSuccessor(MBB)) 41020b57cec5SDimitry Andric return false; 41030b57cec5SDimitry Andric 41040b57cec5SDimitry Andric // If the block is completely empty, then it definitely does fall through. 41050b57cec5SDimitry Andric if (Pred->empty()) 41060b57cec5SDimitry Andric return true; 41070b57cec5SDimitry Andric 41080b57cec5SDimitry Andric // Check the terminators in the previous blocks 41090b57cec5SDimitry Andric for (const auto &MI : Pred->terminators()) { 41100b57cec5SDimitry Andric // If it is not a simple branch, we are in a table somewhere. 41110b57cec5SDimitry Andric if (!MI.isBranch() || MI.isIndirectBranch()) 41120b57cec5SDimitry Andric return false; 41130b57cec5SDimitry Andric 41140b57cec5SDimitry Andric // If we are the operands of one of the branches, this is not a fall 41150b57cec5SDimitry Andric // through. Note that targets with delay slots will usually bundle 41160b57cec5SDimitry Andric // terminators with the delay slot instruction. 41170b57cec5SDimitry Andric for (ConstMIBundleOperands OP(MI); OP.isValid(); ++OP) { 41180b57cec5SDimitry Andric if (OP->isJTI()) 41190b57cec5SDimitry Andric return false; 41200b57cec5SDimitry Andric if (OP->isMBB() && OP->getMBB() == MBB) 41210b57cec5SDimitry Andric return false; 41220b57cec5SDimitry Andric } 41230b57cec5SDimitry Andric } 41240b57cec5SDimitry Andric 41250b57cec5SDimitry Andric return true; 41260b57cec5SDimitry Andric } 41270b57cec5SDimitry Andric 4128bdd1243dSDimitry Andric GCMetadataPrinter *AsmPrinter::getOrCreateGCPrinter(GCStrategy &S) { 41290b57cec5SDimitry Andric if (!S.usesMetadata()) 41300b57cec5SDimitry Andric return nullptr; 41310b57cec5SDimitry Andric 4132bdd1243dSDimitry Andric auto [GCPI, Inserted] = GCMetadataPrinters.insert({&S, nullptr}); 4133bdd1243dSDimitry Andric if (!Inserted) 41340b57cec5SDimitry Andric return GCPI->second.get(); 41350b57cec5SDimitry Andric 41360b57cec5SDimitry Andric auto Name = S.getName(); 41370b57cec5SDimitry Andric 41385ffd83dbSDimitry Andric for (const GCMetadataPrinterRegistry::entry &GCMetaPrinter : 41395ffd83dbSDimitry Andric GCMetadataPrinterRegistry::entries()) 41405ffd83dbSDimitry Andric if (Name == GCMetaPrinter.getName()) { 41415ffd83dbSDimitry Andric std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate(); 41420b57cec5SDimitry Andric GMP->S = &S; 4143bdd1243dSDimitry Andric GCPI->second = std::move(GMP); 4144bdd1243dSDimitry Andric return GCPI->second.get(); 41450b57cec5SDimitry Andric } 41460b57cec5SDimitry Andric 41470b57cec5SDimitry Andric report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); 41480b57cec5SDimitry Andric } 41490b57cec5SDimitry Andric 4150bdd1243dSDimitry Andric void AsmPrinter::emitStackMaps() { 41510b57cec5SDimitry Andric GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); 41520b57cec5SDimitry Andric assert(MI && "AsmPrinter didn't require GCModuleInfo?"); 41530b57cec5SDimitry Andric bool NeedsDefault = false; 41540b57cec5SDimitry Andric if (MI->begin() == MI->end()) 41550b57cec5SDimitry Andric // No GC strategy, use the default format. 41560b57cec5SDimitry Andric NeedsDefault = true; 41570b57cec5SDimitry Andric else 4158fcaf7f86SDimitry Andric for (const auto &I : *MI) { 4159bdd1243dSDimitry Andric if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I)) 41600b57cec5SDimitry Andric if (MP->emitStackMaps(SM, *this)) 41610b57cec5SDimitry Andric continue; 41620b57cec5SDimitry Andric // The strategy doesn't have printer or doesn't emit custom stack maps. 41630b57cec5SDimitry Andric // Use the default format. 41640b57cec5SDimitry Andric NeedsDefault = true; 41650b57cec5SDimitry Andric } 41660b57cec5SDimitry Andric 41670b57cec5SDimitry Andric if (NeedsDefault) 41680b57cec5SDimitry Andric SM.serializeToStackMapSection(); 41690b57cec5SDimitry Andric } 41700b57cec5SDimitry Andric 4171*0fca6ea1SDimitry Andric void AsmPrinter::addAsmPrinterHandler( 4172*0fca6ea1SDimitry Andric std::unique_ptr<AsmPrinterHandler> Handler) { 4173*0fca6ea1SDimitry Andric Handlers.insert(Handlers.begin(), std::move(Handler)); 4174*0fca6ea1SDimitry Andric NumUserHandlers++; 4175*0fca6ea1SDimitry Andric } 4176*0fca6ea1SDimitry Andric 4177*0fca6ea1SDimitry Andric void AsmPrinter::addDebugHandler(std::unique_ptr<DebugHandlerBase> Handler) { 4178*0fca6ea1SDimitry Andric DebugHandlers.insert(DebugHandlers.begin(), std::move(Handler)); 4179*0fca6ea1SDimitry Andric NumUserDebugHandlers++; 4180*0fca6ea1SDimitry Andric } 4181*0fca6ea1SDimitry Andric 41820b57cec5SDimitry Andric /// Pin vtable to this file. 41830b57cec5SDimitry Andric AsmPrinterHandler::~AsmPrinterHandler() = default; 41840b57cec5SDimitry Andric 41850b57cec5SDimitry Andric void AsmPrinterHandler::markFunctionEnd() {} 41860b57cec5SDimitry Andric 41870b57cec5SDimitry Andric // In the binary's "xray_instr_map" section, an array of these function entries 41880b57cec5SDimitry Andric // describes each instrumentation point. When XRay patches your code, the index 41890b57cec5SDimitry Andric // into this table will be given to your handler as a patch point identifier. 41905ffd83dbSDimitry Andric void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out) const { 41910b57cec5SDimitry Andric auto Kind8 = static_cast<uint8_t>(Kind); 41925ffd83dbSDimitry Andric Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1)); 41935ffd83dbSDimitry Andric Out->emitBinaryData( 41940b57cec5SDimitry Andric StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1)); 41955ffd83dbSDimitry Andric Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1)); 41960b57cec5SDimitry Andric auto Padding = (4 * Bytes) - ((2 * Bytes) + 3); 41970b57cec5SDimitry Andric assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size"); 41985ffd83dbSDimitry Andric Out->emitZeros(Padding); 41990b57cec5SDimitry Andric } 42000b57cec5SDimitry Andric 42010b57cec5SDimitry Andric void AsmPrinter::emitXRayTable() { 42020b57cec5SDimitry Andric if (Sleds.empty()) 42030b57cec5SDimitry Andric return; 42040b57cec5SDimitry Andric 42050b57cec5SDimitry Andric auto PrevSection = OutStreamer->getCurrentSectionOnly(); 42060b57cec5SDimitry Andric const Function &F = MF->getFunction(); 42070b57cec5SDimitry Andric MCSection *InstMap = nullptr; 42080b57cec5SDimitry Andric MCSection *FnSledIndex = nullptr; 42095ffd83dbSDimitry Andric const Triple &TT = TM.getTargetTriple(); 4210e8d8bef9SDimitry Andric // Use PC-relative addresses on all targets. 42115ffd83dbSDimitry Andric if (TT.isOSBinFormatELF()) { 42125ffd83dbSDimitry Andric auto LinkedToSym = cast<MCSymbolELF>(CurrentFnSym); 42135ffd83dbSDimitry Andric auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER; 42145ffd83dbSDimitry Andric StringRef GroupName; 42150b57cec5SDimitry Andric if (F.hasComdat()) { 42160b57cec5SDimitry Andric Flags |= ELF::SHF_GROUP; 42170b57cec5SDimitry Andric GroupName = F.getComdat()->getName(); 42180b57cec5SDimitry Andric } 42195ffd83dbSDimitry Andric InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, 4220fe6060f1SDimitry Andric Flags, 0, GroupName, F.hasComdat(), 42215ffd83dbSDimitry Andric MCSection::NonUniqueID, LinkedToSym); 42220b57cec5SDimitry Andric 422306c3fb27SDimitry Andric if (TM.Options.XRayFunctionIndex) 42245ffd83dbSDimitry Andric FnSledIndex = OutContext.getELFSection( 422506c3fb27SDimitry Andric "xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, GroupName, F.hasComdat(), 422606c3fb27SDimitry Andric MCSection::NonUniqueID, LinkedToSym); 42270b57cec5SDimitry Andric } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { 422806c3fb27SDimitry Andric InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 422906c3fb27SDimitry Andric MachO::S_ATTR_LIVE_SUPPORT, 42300b57cec5SDimitry Andric SectionKind::getReadOnlyWithRel()); 423106c3fb27SDimitry Andric if (TM.Options.XRayFunctionIndex) 423206c3fb27SDimitry Andric FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx", 423306c3fb27SDimitry Andric MachO::S_ATTR_LIVE_SUPPORT, 423406c3fb27SDimitry Andric SectionKind::getReadOnly()); 42350b57cec5SDimitry Andric } else { 42360b57cec5SDimitry Andric llvm_unreachable("Unsupported target"); 42370b57cec5SDimitry Andric } 42380b57cec5SDimitry Andric 42390b57cec5SDimitry Andric auto WordSizeBytes = MAI->getCodePointerSize(); 42400b57cec5SDimitry Andric 42410b57cec5SDimitry Andric // Now we switch to the instrumentation map section. Because this is done 42420b57cec5SDimitry Andric // per-function, we are able to create an index entry that will represent the 42430b57cec5SDimitry Andric // range of sleds associated with a function. 42445ffd83dbSDimitry Andric auto &Ctx = OutContext; 424506c3fb27SDimitry Andric MCSymbol *SledsStart = 424606c3fb27SDimitry Andric OutContext.createLinkerPrivateSymbol("xray_sleds_start"); 424781ad6265SDimitry Andric OutStreamer->switchSection(InstMap); 42485ffd83dbSDimitry Andric OutStreamer->emitLabel(SledsStart); 42495ffd83dbSDimitry Andric for (const auto &Sled : Sleds) { 42505ffd83dbSDimitry Andric MCSymbol *Dot = Ctx.createTempSymbol(); 42515ffd83dbSDimitry Andric OutStreamer->emitLabel(Dot); 42525ffd83dbSDimitry Andric OutStreamer->emitValueImpl( 42535ffd83dbSDimitry Andric MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx), 42545ffd83dbSDimitry Andric MCSymbolRefExpr::create(Dot, Ctx), Ctx), 42555ffd83dbSDimitry Andric WordSizeBytes); 42565ffd83dbSDimitry Andric OutStreamer->emitValueImpl( 42575ffd83dbSDimitry Andric MCBinaryExpr::createSub( 42585ffd83dbSDimitry Andric MCSymbolRefExpr::create(CurrentFnBegin, Ctx), 4259e8d8bef9SDimitry Andric MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Dot, Ctx), 4260e8d8bef9SDimitry Andric MCConstantExpr::create(WordSizeBytes, Ctx), 4261e8d8bef9SDimitry Andric Ctx), 42625ffd83dbSDimitry Andric Ctx), 42635ffd83dbSDimitry Andric WordSizeBytes); 42645ffd83dbSDimitry Andric Sled.emit(WordSizeBytes, OutStreamer.get()); 42655ffd83dbSDimitry Andric } 42660b57cec5SDimitry Andric MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_sleds_end", true); 42675ffd83dbSDimitry Andric OutStreamer->emitLabel(SledsEnd); 42680b57cec5SDimitry Andric 42690b57cec5SDimitry Andric // We then emit a single entry in the index per function. We use the symbols 42700b57cec5SDimitry Andric // that bound the instrumentation map as the range for a specific function. 42710b57cec5SDimitry Andric // Each entry here will be 2 * word size aligned, as we're writing down two 42720b57cec5SDimitry Andric // pointers. This should work for both 32-bit and 64-bit platforms. 42735ffd83dbSDimitry Andric if (FnSledIndex) { 427481ad6265SDimitry Andric OutStreamer->switchSection(FnSledIndex); 4275bdd1243dSDimitry Andric OutStreamer->emitCodeAlignment(Align(2 * WordSizeBytes), 4276bdd1243dSDimitry Andric &getSubtargetInfo()); 427706c3fb27SDimitry Andric // For Mach-O, use an "l" symbol as the atom of this subsection. The label 427806c3fb27SDimitry Andric // difference uses a SUBTRACTOR external relocation which references the 427906c3fb27SDimitry Andric // symbol. 428006c3fb27SDimitry Andric MCSymbol *Dot = Ctx.createLinkerPrivateSymbol("xray_fn_idx"); 428106c3fb27SDimitry Andric OutStreamer->emitLabel(Dot); 428206c3fb27SDimitry Andric OutStreamer->emitValueImpl( 428306c3fb27SDimitry Andric MCBinaryExpr::createSub(MCSymbolRefExpr::create(SledsStart, Ctx), 428406c3fb27SDimitry Andric MCSymbolRefExpr::create(Dot, Ctx), Ctx), 428506c3fb27SDimitry Andric WordSizeBytes); 428606c3fb27SDimitry Andric OutStreamer->emitValueImpl(MCConstantExpr::create(Sleds.size(), Ctx), 428706c3fb27SDimitry Andric WordSizeBytes); 428881ad6265SDimitry Andric OutStreamer->switchSection(PrevSection); 42895ffd83dbSDimitry Andric } 42900b57cec5SDimitry Andric Sleds.clear(); 42910b57cec5SDimitry Andric } 42920b57cec5SDimitry Andric 42930b57cec5SDimitry Andric void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, 42940b57cec5SDimitry Andric SledKind Kind, uint8_t Version) { 42950b57cec5SDimitry Andric const Function &F = MI.getMF()->getFunction(); 42960b57cec5SDimitry Andric auto Attr = F.getFnAttribute("function-instrument"); 42970b57cec5SDimitry Andric bool LogArgs = F.hasFnAttribute("xray-log-args"); 42980b57cec5SDimitry Andric bool AlwaysInstrument = 42990b57cec5SDimitry Andric Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always"; 43000b57cec5SDimitry Andric if (Kind == SledKind::FUNCTION_ENTER && LogArgs) 43010b57cec5SDimitry Andric Kind = SledKind::LOG_ARGS_ENTER; 43020b57cec5SDimitry Andric Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind, 43030b57cec5SDimitry Andric AlwaysInstrument, &F, Version}); 43040b57cec5SDimitry Andric } 43050b57cec5SDimitry Andric 4306480093f4SDimitry Andric void AsmPrinter::emitPatchableFunctionEntries() { 4307480093f4SDimitry Andric const Function &F = MF->getFunction(); 430855e4f9d5SDimitry Andric unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0; 430955e4f9d5SDimitry Andric (void)F.getFnAttribute("patchable-function-prefix") 431055e4f9d5SDimitry Andric .getValueAsString() 431155e4f9d5SDimitry Andric .getAsInteger(10, PatchableFunctionPrefix); 431255e4f9d5SDimitry Andric (void)F.getFnAttribute("patchable-function-entry") 431355e4f9d5SDimitry Andric .getValueAsString() 431455e4f9d5SDimitry Andric .getAsInteger(10, PatchableFunctionEntry); 431555e4f9d5SDimitry Andric if (!PatchableFunctionPrefix && !PatchableFunctionEntry) 4316480093f4SDimitry Andric return; 4317480093f4SDimitry Andric const unsigned PointerSize = getPointerSize(); 4318480093f4SDimitry Andric if (TM.getTargetTriple().isOSBinFormatELF()) { 4319480093f4SDimitry Andric auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC; 43205ffd83dbSDimitry Andric const MCSymbolELF *LinkedToSym = nullptr; 43215ffd83dbSDimitry Andric StringRef GroupName; 4322480093f4SDimitry Andric 4323fe6060f1SDimitry Andric // GNU as < 2.35 did not support section flag 'o'. GNU ld < 2.36 did not 4324fe6060f1SDimitry Andric // support mixed SHF_LINK_ORDER and non-SHF_LINK_ORDER sections. 4325fe6060f1SDimitry Andric if (MAI->useIntegratedAssembler() || MAI->binutilsIsAtLeast(2, 36)) { 4326480093f4SDimitry Andric Flags |= ELF::SHF_LINK_ORDER; 4327480093f4SDimitry Andric if (F.hasComdat()) { 4328480093f4SDimitry Andric Flags |= ELF::SHF_GROUP; 4329480093f4SDimitry Andric GroupName = F.getComdat()->getName(); 4330480093f4SDimitry Andric } 43315ffd83dbSDimitry Andric LinkedToSym = cast<MCSymbolELF>(CurrentFnSym); 4332480093f4SDimitry Andric } 433381ad6265SDimitry Andric OutStreamer->switchSection(OutContext.getELFSection( 43345ffd83dbSDimitry Andric "__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName, 4335fe6060f1SDimitry Andric F.hasComdat(), MCSection::NonUniqueID, LinkedToSym)); 43365ffd83dbSDimitry Andric emitAlignment(Align(PointerSize)); 43375ffd83dbSDimitry Andric OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize); 4338480093f4SDimitry Andric } 4339480093f4SDimitry Andric } 4340480093f4SDimitry Andric 43410b57cec5SDimitry Andric uint16_t AsmPrinter::getDwarfVersion() const { 43420b57cec5SDimitry Andric return OutStreamer->getContext().getDwarfVersion(); 43430b57cec5SDimitry Andric } 43440b57cec5SDimitry Andric 43450b57cec5SDimitry Andric void AsmPrinter::setDwarfVersion(uint16_t Version) { 43460b57cec5SDimitry Andric OutStreamer->getContext().setDwarfVersion(Version); 43470b57cec5SDimitry Andric } 4348e8d8bef9SDimitry Andric 4349e8d8bef9SDimitry Andric bool AsmPrinter::isDwarf64() const { 4350e8d8bef9SDimitry Andric return OutStreamer->getContext().getDwarfFormat() == dwarf::DWARF64; 4351e8d8bef9SDimitry Andric } 4352e8d8bef9SDimitry Andric 4353e8d8bef9SDimitry Andric unsigned int AsmPrinter::getDwarfOffsetByteSize() const { 4354e8d8bef9SDimitry Andric return dwarf::getDwarfOffsetByteSize( 4355e8d8bef9SDimitry Andric OutStreamer->getContext().getDwarfFormat()); 4356e8d8bef9SDimitry Andric } 4357e8d8bef9SDimitry Andric 435804eeddc0SDimitry Andric dwarf::FormParams AsmPrinter::getDwarfFormParams() const { 435906c3fb27SDimitry Andric return {getDwarfVersion(), uint8_t(MAI->getCodePointerSize()), 436004eeddc0SDimitry Andric OutStreamer->getContext().getDwarfFormat(), 4361bdd1243dSDimitry Andric doesDwarfUseRelocationsAcrossSections()}; 436204eeddc0SDimitry Andric } 436304eeddc0SDimitry Andric 4364e8d8bef9SDimitry Andric unsigned int AsmPrinter::getUnitLengthFieldByteSize() const { 4365e8d8bef9SDimitry Andric return dwarf::getUnitLengthFieldByteSize( 4366e8d8bef9SDimitry Andric OutStreamer->getContext().getDwarfFormat()); 4367e8d8bef9SDimitry Andric } 43685f757f3fSDimitry Andric 43695f757f3fSDimitry Andric std::tuple<const MCSymbol *, uint64_t, const MCSymbol *, 43705f757f3fSDimitry Andric codeview::JumpTableEntrySize> 43715f757f3fSDimitry Andric AsmPrinter::getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, 43725f757f3fSDimitry Andric const MCSymbol *BranchLabel) const { 43735f757f3fSDimitry Andric const auto TLI = MF->getSubtarget().getTargetLowering(); 43745f757f3fSDimitry Andric const auto BaseExpr = 43755f757f3fSDimitry Andric TLI->getPICJumpTableRelocBaseExpr(MF, JTI, MMI->getContext()); 43765f757f3fSDimitry Andric const auto Base = &cast<MCSymbolRefExpr>(BaseExpr)->getSymbol(); 43775f757f3fSDimitry Andric 43785f757f3fSDimitry Andric // By default, for the architectures that support CodeView, 43795f757f3fSDimitry Andric // EK_LabelDifference32 is implemented as an Int32 from the base address. 43805f757f3fSDimitry Andric return std::make_tuple(Base, 0, BranchLabel, 43815f757f3fSDimitry Andric codeview::JumpTableEntrySize::Int32); 43825f757f3fSDimitry Andric } 4383