Skip to content

Commit 29d50a1

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

21 files changed

+372
-4
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,9 @@ 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 an import call directive, used to build the import call table.
573+
virtual void emitCOFFImpCall(MCSymbol const *Symbol);
574+
572575
/// Emits an lcomm directive with XCOFF csect information.
573576
///
574577
/// \param LabelSym - Label on the block of storage.

llvm/include/llvm/MC/MCWinCOFFObjectWriter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class WinCOFFObjectWriter final : public MCObjectWriter {
7272
const MCFixup &Fixup, MCValue Target,
7373
uint64_t &FixedValue) override;
7474
uint64_t writeObject(MCAssembler &Asm) override;
75+
void recordImportCall(const MCDataFragment &FB, const MCSymbol *Symbol);
76+
bool hasRecordedImportCalls() const;
7577
};
7678

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

llvm/include/llvm/MC/MCWinCOFFStreamer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ 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 emitCOFFImpCall(MCSymbol const *Symbol) override;
6162
void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
6263
Align ByteAlignment) override;
6364
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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ 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 emitCOFFImpCall(MCSymbol const *Symbol) override;
212213
void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
213214
MCSymbol *CsectSym, Align Alignment) override;
214215
void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
@@ -893,6 +894,14 @@ void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
893894
EmitEOL();
894895
}
895896

897+
void MCAsmStreamer::emitCOFFImpCall(MCSymbol const *Symbol) {
898+
assert(this->getContext().getObjectFileInfo()->getImportCallSection() &&
899+
"This target does not have a import call section");
900+
OS << "\t.impcall\t";
901+
Symbol->print(OS, MAI);
902+
EmitEOL();
903+
}
904+
896905
// We need an XCOFF-specific version of this directive as the AIX syntax
897906
// requires a QualName argument identifying the csect name and storage mapping
898907
// 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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/BinaryFormat/COFF.h"
1313
#include "llvm/MC/MCContext.h"
1414
#include "llvm/MC/MCDirectives.h"
15+
#include "llvm/MC/MCObjectFileInfo.h"
1516
#include "llvm/MC/MCParser/MCAsmLexer.h"
1617
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
1718
#include "llvm/MC/MCSectionCOFF.h"
@@ -70,6 +71,7 @@ class COFFAsmParser : public MCAsmParserExtension {
7071
addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(
7172
".weak_anti_dep");
7273
addDirectiveHandler<&COFFAsmParser::parseDirectiveCGProfile>(".cg_profile");
74+
addDirectiveHandler<&COFFAsmParser::parseDirectiveImpCall>(".impcall");
7375

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

130133
// Win64 EH directives.
131134
bool parseSEHDirectiveStartProc(StringRef, SMLoc);
@@ -577,6 +580,24 @@ bool COFFAsmParser::parseDirectiveSymIdx(StringRef, SMLoc) {
577580
return false;
578581
}
579582

583+
bool COFFAsmParser::parseDirectiveImpCall(StringRef, SMLoc) {
584+
if (!getContext().getObjectFileInfo()->getImportCallSection())
585+
return TokError("target does not have an import call section");
586+
587+
StringRef SymbolID;
588+
if (getParser().parseIdentifier(SymbolID))
589+
return TokError("expected identifier in directive");
590+
591+
if (getLexer().isNot(AsmToken::EndOfStatement))
592+
return TokError("unexpected token in directive");
593+
594+
MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
595+
596+
Lex();
597+
getStreamer().emitCOFFImpCall(Symbol);
598+
return false;
599+
}
600+
580601
/// ::= [ identifier ]
581602
bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
582603
StringRef TypeId = getTok().getIdentifier();

0 commit comments

Comments
 (0)