Skip to content

Commit 69e2a67

Browse files
committed
[aarch64][win] Add support for import call optimization (equivalent to MSVC /d2ImportCallOptimization)
1 parent cbff02b commit 69e2a67

19 files changed

+471
-13
lines changed

llvm/include/llvm/CodeGen/MachineFunction.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ class LLVM_ABI MachineFunction {
354354
/// a table of valid targets for Windows EHCont Guard.
355355
std::vector<MCSymbol *> CatchretTargets;
356356

357+
/// Mapping of call instruction to the global value and target flags that it
358+
/// calls, if applicable.
359+
DenseMap<const MachineInstr *, std::pair<const GlobalValue *, unsigned>>
360+
CalledGlobalsMap;
361+
357362
/// \name Exception Handling
358363
/// \{
359364

@@ -1182,6 +1187,19 @@ class LLVM_ABI MachineFunction {
11821187
CatchretTargets.push_back(Target);
11831188
}
11841189

1190+
/// Tries to get the global and target flags for a call site, if the
1191+
/// instruction is a call to a global.
1192+
std::pair<const GlobalValue *, unsigned>
1193+
tryGetCalledGlobal(const MachineInstr *MI) const {
1194+
return CalledGlobalsMap.lookup(MI);
1195+
}
1196+
1197+
/// Notes the global and target flags for a call site.
1198+
void addCalledGlobal(const MachineInstr *MI,
1199+
std::pair<const GlobalValue *, unsigned> Details) {
1200+
CalledGlobalsMap.insert({MI, Details});
1201+
}
1202+
11851203
/// \name Exception Handling
11861204
/// \{
11871205

llvm/include/llvm/CodeGen/SelectionDAG.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ class SelectionDAG {
293293
MDNode *HeapAllocSite = nullptr;
294294
MDNode *PCSections = nullptr;
295295
MDNode *MMRA = nullptr;
296+
std::pair<const GlobalValue *, unsigned> CalledGlobal{};
296297
bool NoMerge = false;
297298
};
298299
/// Out-of-line extra information for SDNodes.
@@ -2373,6 +2374,19 @@ class SelectionDAG {
23732374
auto It = SDEI.find(Node);
23742375
return It != SDEI.end() ? It->second.MMRA : nullptr;
23752376
}
2377+
/// Set CalledGlobal to be associated with Node.
2378+
void addCalledGlobal(const SDNode *Node, const GlobalValue *GV,
2379+
unsigned OpFlags) {
2380+
SDEI[Node].CalledGlobal = {GV, OpFlags};
2381+
}
2382+
/// Return CalledGlobal associated with Node, or a nullopt if none exists.
2383+
std::optional<std::pair<const GlobalValue *, unsigned>>
2384+
getCalledGlobal(const SDNode *Node) {
2385+
auto I = SDEI.find(Node);
2386+
return I != SDEI.end()
2387+
? std::make_optional(std::move(I->second).CalledGlobal)
2388+
: std::nullopt;
2389+
}
23762390
/// Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
23772391
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
23782392
if (NoMerge)

llvm/include/llvm/MC/MCObjectFileInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ class MCObjectFileInfo {
7373
/// to emit them into.
7474
MCSection *CompactUnwindSection = nullptr;
7575

76+
/// If import call optimization is supported by the target, this is the
77+
/// section to emit import call data to.
78+
MCSection *ImportCallSection = nullptr;
79+
7680
// Dwarf sections for debug info. If a target supports debug info, these must
7781
// be set.
7882
MCSection *DwarfAbbrevSection = nullptr;
@@ -269,6 +273,7 @@ class MCObjectFileInfo {
269273
MCSection *getBSSSection() const { return BSSSection; }
270274
MCSection *getReadOnlySection() const { return ReadOnlySection; }
271275
MCSection *getLSDASection() const { return LSDASection; }
276+
MCSection *getImportCallSection() const { return ImportCallSection; }
272277
MCSection *getCompactUnwindSection() const { return CompactUnwindSection; }
273278
MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
274279
MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,14 @@ class MCStreamer {
569569
/// \param Symbol - Symbol the image relative relocation should point to.
570570
virtual void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset);
571571

572+
/// Emits the physical number of the section containing the given symbol as
573+
/// assigned during object writing (i.e., this is not a runtime relocation).
574+
virtual void emitCOFFSecNumber(MCSymbol const *Symbol);
575+
576+
/// Emits the offset of the symbol from the beginning of the section during
577+
/// object writing (i.e., this is not a runtime relocation).
578+
virtual void emitCOFFSecOffset(MCSymbol const *Symbol);
579+
572580
/// Emits an lcomm directive with XCOFF csect information.
573581
///
574582
/// \param LabelSym - Label on the block of storage.

llvm/include/llvm/MC/MCWinCOFFObjectWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class WinCOFFObjectWriter final : public MCObjectWriter {
7272
const MCFixup &Fixup, MCValue Target,
7373
uint64_t &FixedValue) override;
7474
uint64_t writeObject(MCAssembler &Asm) override;
75+
int getSectionNumber(const MCSection &Section) const;
7576
};
7677

7778
/// Construct a new Win COFF writer instance.

llvm/include/llvm/MC/MCWinCOFFStreamer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class MCWinCOFFStreamer : public MCObjectStreamer {
5858
void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
5959
void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
6060
void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
61+
void emitCOFFSecNumber(MCSymbol const *Symbol) override;
62+
void emitCOFFSecOffset(MCSymbol const *Symbol) override;
6163
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
6264
Align ByteAlignment) override;
6365
void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,

llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,9 @@ EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
908908
It->setMMRAMetadata(MF, MMRA);
909909
}
910910

911+
if (auto CalledGlobal = DAG->getCalledGlobal(Node))
912+
MF.addCalledGlobal(MI, *CalledGlobal);
913+
911914
return MI;
912915
};
913916

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ class MCAsmStreamer final : public MCStreamer {
209209
void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
210210
void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
211211
void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
212+
void emitCOFFSecNumber(MCSymbol const *Symbol) override;
213+
void emitCOFFSecOffset(MCSymbol const *Symbol) override;
212214
void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
213215
MCSymbol *CsectSym, Align Alignment) override;
214216
void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
@@ -893,6 +895,18 @@ void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
893895
EmitEOL();
894896
}
895897

898+
void MCAsmStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {
899+
OS << "\t.secnum\t";
900+
Symbol->print(OS, MAI);
901+
EmitEOL();
902+
}
903+
904+
void MCAsmStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {
905+
OS << "\t.secoffset\t";
906+
Symbol->print(OS, MAI);
907+
EmitEOL();
908+
}
909+
896910
// We need an XCOFF-specific version of this directive as the AIX syntax
897911
// requires a QualName argument identifying the csect name and storage mapping
898912
// class to appear before the alignment if we are specifying it.

llvm/lib/MC/MCObjectFileInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
596596
COFF::IMAGE_SCN_MEM_READ);
597597
}
598598

599+
if (T.getArch() == Triple::aarch64) {
600+
ImportCallSection =
601+
Ctx->getCOFFSection(".impcall", COFF::IMAGE_SCN_LNK_INFO);
602+
}
603+
599604
// Debug info.
600605
COFFDebugSymbolsSection =
601606
Ctx->getCOFFSection(".debug$S", (COFF::IMAGE_SCN_MEM_DISCARDABLE |

llvm/lib/MC/MCParser/COFFAsmParser.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class COFFAsmParser : public MCAsmParserExtension {
7070
addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(
7171
".weak_anti_dep");
7272
addDirectiveHandler<&COFFAsmParser::parseDirectiveCGProfile>(".cg_profile");
73+
addDirectiveHandler<&COFFAsmParser::parseDirectiveSecNum>(".secnum");
74+
addDirectiveHandler<&COFFAsmParser::parseDirectiveSecOffset>(".secoffset");
7375

7476
// Win64 EH directives.
7577
addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartProc>(
@@ -126,6 +128,8 @@ class COFFAsmParser : public MCAsmParserExtension {
126128
bool parseDirectiveLinkOnce(StringRef, SMLoc);
127129
bool parseDirectiveRVA(StringRef, SMLoc);
128130
bool parseDirectiveCGProfile(StringRef, SMLoc);
131+
bool parseDirectiveSecNum(StringRef, SMLoc);
132+
bool parseDirectiveSecOffset(StringRef, SMLoc);
129133

130134
// Win64 EH directives.
131135
bool parseSEHDirectiveStartProc(StringRef, SMLoc);
@@ -577,6 +581,36 @@ bool COFFAsmParser::parseDirectiveSymIdx(StringRef, SMLoc) {
577581
return false;
578582
}
579583

584+
bool COFFAsmParser::parseDirectiveSecNum(StringRef, SMLoc) {
585+
StringRef SymbolID;
586+
if (getParser().parseIdentifier(SymbolID))
587+
return TokError("expected identifier in directive");
588+
589+
if (getLexer().isNot(AsmToken::EndOfStatement))
590+
return TokError("unexpected token in directive");
591+
592+
MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
593+
594+
Lex();
595+
getStreamer().emitCOFFSecNumber(Symbol);
596+
return false;
597+
}
598+
599+
bool COFFAsmParser::parseDirectiveSecOffset(StringRef, SMLoc) {
600+
StringRef SymbolID;
601+
if (getParser().parseIdentifier(SymbolID))
602+
return TokError("expected identifier in directive");
603+
604+
if (getLexer().isNot(AsmToken::EndOfStatement))
605+
return TokError("unexpected token in directive");
606+
607+
MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
608+
609+
Lex();
610+
getStreamer().emitCOFFSecOffset(Symbol);
611+
return false;
612+
}
613+
580614
/// ::= [ identifier ]
581615
bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
582616
StringRef TypeId = getTok().getIdentifier();

0 commit comments

Comments
 (0)