summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp20
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp14
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp38
-rw-r--r--llvm/lib/MC/MCParser/ELFAsmParser.cpp45
-rw-r--r--llvm/lib/MC/MCSectionELF.cpp2
-rw-r--r--llvm/lib/MC/MCStreamer.cpp4
6 files changed, 123 insertions, 0 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 14300642303..f4117e75516 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -976,6 +976,7 @@ void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
break;
case ELF::SHT_SYMTAB_SHNDX:
+ case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
sh_link = SymbolTableIndex;
break;
@@ -1091,6 +1092,14 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
}
}
+ MCSectionELF *CGProfileSection = nullptr;
+ if (!Asm.CGProfile.empty()) {
+ CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile",
+ ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
+ ELF::SHF_EXCLUDE, 16, "");
+ SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection);
+ }
+
for (MCSectionELF *Group : Groups) {
align(Group->getAlignment());
@@ -1132,6 +1141,17 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
}
}
+ if (CGProfileSection) {
+ uint64_t SecStart = W.OS.tell();
+ for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
+ W.write<uint32_t>(CGPE.From->getSymbol().getIndex());
+ W.write<uint32_t>(CGPE.To->getSymbol().getIndex());
+ W.write<uint64_t>(CGPE.Count);
+ }
+ uint64_t SecEnd = W.OS.tell();
+ SectionOffsets[CGProfileSection] = std::make_pair(SecStart, SecEnd);
+ }
+
{
uint64_t SecStart = W.OS.tell();
const MCSectionELF *Sec = createStringTable(Ctx);
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index d19c8c21dd0..5c7bbeafec2 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -304,6 +304,9 @@ public:
SMLoc Loc) override;
void EmitWinEHHandlerData(SMLoc Loc) override;
+ void emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To, uint64_t Count) override;
+
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
bool PrintSchedInfo) override;
@@ -1650,6 +1653,17 @@ void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
EmitEOL();
}
+void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To,
+ uint64_t Count) {
+ OS << "\t.cg_profile ";
+ From->getSymbol().print(OS, MAI);
+ OS << ", ";
+ To->getSymbol().print(OS, MAI);
+ OS << ", " << Count;
+ EmitEOL();
+}
+
void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
const MCSubtargetInfo &STI,
bool PrintSchedInfo) {
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 3a008f9fea0..b112bd9639d 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -355,6 +355,12 @@ void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
ValueSize, MaxBytesToEmit);
}
+void MCELFStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To,
+ uint64_t Count) {
+ getAssembler().CGProfile.push_back({From, To, Count});
+}
+
void MCELFStreamer::EmitIdent(StringRef IdentString) {
MCSection *Comment = getAssembler().getContext().getELFSection(
".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
@@ -447,6 +453,37 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
}
}
+void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
+ const MCSymbol *S = &SRE->getSymbol();
+ if (S->isTemporary()) {
+ if (!S->isInSection()) {
+ getContext().reportError(
+ SRE->getLoc(), Twine("Reference to undefined temporary symbol ") +
+ "`" + S->getName() + "`");
+ return;
+ }
+ S = S->getSection().getBeginSymbol();
+ S->setUsedInReloc();
+ SRE =
+ MCSymbolRefExpr::create(S, SRE->getKind(), getContext(), SRE->getLoc());
+ return;
+ }
+ // Not a temporary, referece it as a weak undefined.
+ bool Created;
+ getAssembler().registerSymbol(*S, &Created);
+ if (Created) {
+ cast<MCSymbolELF>(S)->setBinding(ELF::STB_WEAK);
+ cast<MCSymbolELF>(S)->setExternal(true);
+ }
+}
+
+void MCELFStreamer::finalizeCGProfile() {
+ for (MCAssembler::CGProfileEntry &E : getAssembler().CGProfile) {
+ finalizeCGProfileEntry(E.From);
+ finalizeCGProfileEntry(E.To);
+ }
+}
+
void MCELFStreamer::EmitInstToFragment(const MCInst &Inst,
const MCSubtargetInfo &STI) {
this->MCObjectStreamer::EmitInstToFragment(Inst, STI);
@@ -612,6 +649,7 @@ void MCELFStreamer::FinishImpl() {
MCSection *CurSection = getCurrentSectionOnly();
setSectionAlignmentForBundling(getAssembler(), CurSection);
+ finalizeCGProfile();
EmitFrames(nullptr);
this->MCObjectStreamer::FinishImpl();
diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
index cb0616db39e..5194e8a29b8 100644
--- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp
@@ -85,6 +85,7 @@ public:
addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
}
// FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
@@ -149,6 +150,7 @@ public:
bool ParseDirectiveWeakref(StringRef, SMLoc);
bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
bool ParseDirectiveSubsection(StringRef, SMLoc);
+ bool ParseDirectiveCGProfile(StringRef, SMLoc);
private:
bool ParseSectionName(StringRef &SectionName);
@@ -610,6 +612,8 @@ EndStmt:
Type = ELF::SHT_LLVM_ODRTAB;
else if (TypeName == "llvm_linker_options")
Type = ELF::SHT_LLVM_LINKER_OPTIONS;
+ else if (TypeName == "llvm_call_graph_profile")
+ Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
@@ -840,6 +844,47 @@ bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
return false;
}
+/// ParseDirectiveCGProfile
+/// ::= .cg_profile identifier, identifier, <number>
+bool ELFAsmParser::ParseDirectiveCGProfile(StringRef, SMLoc) {
+ StringRef From;
+ SMLoc FromLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(From))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected a comma");
+ Lex();
+
+ StringRef To;
+ SMLoc ToLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(To))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected a comma");
+ Lex();
+
+ int64_t Count;
+ if (getParser().parseIntToken(
+ Count, "expected integer count in '.cg_profile' directive"))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *FromSym = getContext().getOrCreateSymbol(From);
+ MCSymbol *ToSym = getContext().getOrCreateSymbol(To);
+
+ getStreamer().emitCGProfileEntry(
+ MCSymbolRefExpr::create(FromSym, MCSymbolRefExpr::VK_None, getContext(),
+ FromLoc),
+ MCSymbolRefExpr::create(ToSym, MCSymbolRefExpr::VK_None, getContext(),
+ ToLoc),
+ Count);
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createELFAsmParser() {
diff --git a/llvm/lib/MC/MCSectionELF.cpp b/llvm/lib/MC/MCSectionELF.cpp
index 36cdb421655..4d77d05cc50 100644
--- a/llvm/lib/MC/MCSectionELF.cpp
+++ b/llvm/lib/MC/MCSectionELF.cpp
@@ -150,6 +150,8 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
OS << "llvm_odrtab";
else if (Type == ELF::SHT_LLVM_LINKER_OPTIONS)
OS << "llvm_linker_options";
+ else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
+ OS << "llvm_call_graph_profile";
else
report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
" for section " + getSectionName());
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 89d418d6743..491fec3e9ab 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -661,6 +661,10 @@ void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
}
+void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To, uint64_t Count) {
+}
+
static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
MCSection *MainCFISec,
const MCSection *TextSec) {
OpenPOWER on IntegriCloud