class MDNode;
class Module;
class raw_ostream;
+class StackMaps;
class TargetLoweringObjectFile;
class TargetMachine;
/// emit the proxies we previously omitted in EmitGlobalVariable.
void emitGlobalGOTEquivs();
+ /// Emit the stack maps.
+ void emitStackMaps(StackMaps &SM);
+
//===------------------------------------------------------------------===//
// Overridable Hooks
//===------------------------------------------------------------------===//
class GCModuleInfo;
class GCStrategy;
class Module;
+class StackMaps;
/// GCMetadataPrinterRegistry - The GC assembly printer registry uses all the
/// defaults from Registry.
/// Called after the assembly for the module is generated by
/// the AsmPrinter (but before target specific hooks)
virtual void finishAssembly(Module &M, GCModuleInfo &Info, AsmPrinter &AP) {}
+
+ /// Called when the stack maps are generated. Return true if
+ /// stack maps with a custom format are generated. Otherwise
+ /// returns false and the default format will be used.
+ virtual bool emitStackMaps(StackMaps &SM, AsmPrinter &AP) { return false; }
};
} // end namespace llvm
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
+#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
if (!S.usesMetadata())
return nullptr;
- assert(!S.useStatepoints() && "statepoints do not currently support custom"
- " stackmap formats, please see the documentation for a description of"
- " the default format. If you really need a custom serialized format,"
- " please file a bug");
-
gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
gcp_map_type::iterator GCPI = GCMap.find(&S);
if (GCPI != GCMap.end())
report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
}
+void AsmPrinter::emitStackMaps(StackMaps &SM) {
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
+ assert(MI && "AsmPrinter didn't require GCModuleInfo?");
+ bool NeedsDefault = false;
+ if (MI->begin() == MI->end())
+ // No GC strategy, use the default format.
+ NeedsDefault = true;
+ else
+ for (auto &I : *MI) {
+ if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
+ if (MP->emitStackMaps(SM, *this))
+ continue;
+ // The strategy doesn't have printer or doesn't emit custom stack maps.
+ // Use the default format.
+ NeedsDefault = true;
+ }
+
+ if (NeedsDefault)
+ SM.serializeToStackMapSection();
+}
+
/// Pin vtable to this file.
AsmPrinterHandler::~AsmPrinterHandler() = default;
// linker can safely perform dead code stripping. Since LLVM never
// generates code that does this, it is always safe to set.
OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
- SM.serializeToStackMapSection();
+ emitStackMaps(SM);
}
}
}
void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
- SM.serializeToStackMapSection();
+ emitStackMaps(SM);
}
void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
}
void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
- SM.serializeToStackMapSection();
+ emitStackMaps(SM);
}
// Force static initialization.
emitNonLazyStubs(MMI, *OutStreamer);
// Emit stack and fault map information.
- SM.serializeToStackMapSection();
+ emitStackMaps(SM);
FM.serializeToFaultMapSection();
// This flag tells the linker that no global symbols contain code that fall
}
if (TT.isOSBinFormatCOFF()) {
- SM.serializeToStackMapSection();
+ emitStackMaps(SM);
return;
}
if (TT.isOSBinFormatELF()) {
- SM.serializeToStackMapSection();
+ emitStackMaps(SM);
FM.serializeToFaultMapSection();
return;
}