Skip to content

Commit 721fabc

Browse files
committed
Add unittest.
1 parent 254b001 commit 721fabc

File tree

7 files changed

+208
-7
lines changed

7 files changed

+208
-7
lines changed

llvm/include/llvm/MCLinker/MCLinker.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ namespace llvm {
3939
struct MCInfo {
4040
MCInfo(std::unique_ptr<llvm::MachineModuleInfo> &&MachineModuleInfo,
4141
LLVMModuleAndContext &&ModuleAndContext,
42-
llvm::StringMap<const llvm::Function *> &FnNameToFnPtr,
4342
std::unique_ptr<llvm::TargetMachine> &&TgtMachine,
4443
std::unique_ptr<llvm::MCContext> &&McContext,
4544
std::optional<int> SplitIdx);

llvm/include/llvm/MCLinker/MCPipeline.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace mclinker {
2222
/// Build a pipeline that does machine specific codgen but stops before
2323
/// AsmPrint.
2424
bool addPassesToEmitMC(llvm::TargetMachine &, llvm::legacy::PassManagerBase &,
25-
llvm::raw_pwrite_stream &, bool,
25+
bool,
2626
llvm::MachineModuleInfoWrapperPass *, unsigned);
2727

2828
/// Build a pipeline that does AsmPrint only.

llvm/lib/MCLinker/MCLinker.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,22 @@ using namespace llvm;
3030
//==============================================================================
3131

3232
MCInfo::MCInfo(std::unique_ptr<llvm::MachineModuleInfo> &&MachineModuleInfo,
33-
LLVMModuleAndContext &&ModuleAndContext,
34-
llvm::StringMap<const llvm::Function *> &FnNameToFnPtr,
33+
LLVMModuleAndContext &&MAndContext,
3534
std::unique_ptr<llvm::TargetMachine> &&TgtMachine,
3635
std::unique_ptr<llvm::MCContext> &&McContext,
3736
std::optional<int> SplitIdx)
38-
: ModuleAndContext(std::move(ModuleAndContext)),
37+
: ModuleAndContext(std::move(MAndContext)),
3938
McContext(std::move(McContext)),
4039
MachineModuleInfo(std::move(MachineModuleInfo)),
41-
FnNameToFnPtr(std::move(FnNameToFnPtr)),
4240
TgtMachine(std::move(TgtMachine)), SplitIdx(SplitIdx) {
4341
std::string BufStr;
4442
llvm::raw_string_ostream BufOS(BufStr);
4543
llvm::WriteBitcodeToFile(*ModuleAndContext, BufOS);
4644
ModuleBuf = WritableMemoryBuffer::getNewUninitMemBuffer(BufStr.size());
4745
memcpy(ModuleBuf->getBufferStart(), BufStr.c_str(), BufStr.size());
46+
for(Function& F: ModuleAndContext->functions()) {
47+
FnNameToFnPtr.insert( {F.getName(), &F});
48+
}
4849
}
4950

5051
//==============================================================================

llvm/lib/MCLinker/MCPipeline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ bool SetMachineFunctionBasePass::doFinalization(llvm::Module &) {
5757
/// AsmPrint. Returns true if failed.
5858
bool llvm::mclinker::addPassesToEmitMC(
5959
llvm::TargetMachine &TgtMachine, llvm::legacy::PassManagerBase &PM,
60-
llvm::raw_pwrite_stream &Out, bool DisableVerify,
60+
bool DisableVerify,
6161
llvm::MachineModuleInfoWrapperPass *MMIWP, unsigned NumFnBase) {
6262
// Targets may override createPassConfig to provide a target-specific
6363
// subclass.

llvm/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ add_subdirectory(IR)
4949
add_subdirectory(LineEditor)
5050
add_subdirectory(Linker)
5151
add_subdirectory(MC)
52+
add_subdirectory(MCLinker)
5253
add_subdirectory(MI)
5354
add_subdirectory(MIR)
5455
add_subdirectory(ObjCopy)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
set(LLVM_LINK_COMPONENTS
2+
${LLVM_TARGETS_TO_BUILD}
3+
Analysis
4+
AsmParser
5+
AsmPrinter
6+
CodeGen
7+
CodeGenTypes
8+
Core
9+
FileCheck
10+
IRPrinter
11+
MC
12+
MCLinker
13+
MIRParser
14+
ModuleSplitter
15+
Passes
16+
Support
17+
Target
18+
TargetParser
19+
TransformUtils
20+
)
21+
22+
add_llvm_unittest(MCLinkerTests
23+
MCLinkerTest.cpp
24+
)
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
//===- llvm/unittest/Linker/LinkModulesTest.cpp - IRBuilder tests ---------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "llvm/MCLinker/MCLinker.h"
9+
#include "llvm/MCLinker/MCPipeline.h"
10+
#include "llvm/ModuleSplitter/ModuleSplitter.h"
11+
12+
#include "llvm/ADT/STLExtras.h"
13+
#include "llvm/Analysis/MemoryLocation.h"
14+
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
15+
#include "llvm/AsmParser/Parser.h"
16+
#include "llvm/CodeGen/AsmPrinter.h"
17+
#include "llvm/CodeGen/MachineModuleInfo.h"
18+
#include "llvm/CodeGen/SelectionDAG.h"
19+
#include "llvm/CodeGen/TargetLowering.h"
20+
#include "llvm/CodeGen/TargetPassConfig.h"
21+
#include "llvm/IR/BasicBlock.h"
22+
#include "llvm/IR/DataLayout.h"
23+
#include "llvm/IR/Function.h"
24+
#include "llvm/IR/IRBuilder.h"
25+
#include "llvm/IR/LegacyPassManager.h"
26+
#include "llvm/IR/MDBuilder.h"
27+
#include "llvm/IR/Module.h"
28+
#include "llvm/MC/MCStreamer.h"
29+
#include "llvm/MC/TargetRegistry.h"
30+
#include "llvm/Support/KnownBits.h"
31+
#include "llvm/Support/SourceMgr.h"
32+
#include "llvm/Support/TargetSelect.h"
33+
#include "llvm/Target/TargetLoweringObjectFile.h"
34+
#include "llvm/Target/TargetMachine.h"
35+
#include "llvm/Testing/Support/Error.h"
36+
#include "gmock/gmock.h"
37+
#include "gtest/gtest.h"
38+
39+
using namespace llvm;
40+
41+
namespace {
42+
43+
class MCLinkerTest : public testing::Test {
44+
protected:
45+
static void SetUpTestCase() {
46+
LLVMInitializeX86TargetInfo();
47+
LLVMInitializeX86TargetMC();
48+
LLVMInitializeX86Target();
49+
LLVMInitializeX86AsmPrinter();
50+
}
51+
52+
// Get TargetMachine.
53+
std::unique_ptr<TargetMachine> getTargetMachine() {
54+
// Get target triple for X86_64
55+
Triple TargetTriple("x86_64--");
56+
std::string Error;
57+
const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
58+
if (!T)
59+
return nullptr;
60+
61+
TargetOptions Options;
62+
return std::unique_ptr<TargetMachine>(T->createTargetMachine(
63+
TargetTriple, "", "", Options, Reloc::Model::PIC_, {},
64+
CodeGenOptLevel::Default));
65+
}
66+
67+
std::unique_ptr<MCContext> getMCContext(TargetMachine &TM) {
68+
Triple TargetTriple("x86_64--");
69+
std::unique_ptr<MCContext> Ctx(
70+
new MCContext(TargetTriple, TM.getMCAsmInfo(), TM.getMCRegisterInfo(),
71+
TM.getMCSubtargetInfo()));
72+
73+
Ctx->setObjectFileInfo(TM.getObjFileLowering());
74+
TM.getObjFileLowering()->Initialize(*Ctx, TM);
75+
Ctx->setObjectFileInfo(TM.getObjFileLowering());
76+
return Ctx;
77+
}
78+
79+
MachineModuleInfoWrapperPass *getMMIWP(TargetMachine &TM,
80+
MCContext &ExternMC) {
81+
return new MachineModuleInfoWrapperPass(&TM, &ExternMC);
82+
}
83+
84+
void SetUp() override {
85+
// Module to compile.
86+
const char *FooStr = R""""(
87+
define void @foo() {
88+
call void @baz()
89+
ret void
90+
}
91+
92+
define void @baz() {
93+
ret void
94+
}
95+
96+
define void @bar() {
97+
call void @baz()
98+
ret void
99+
}
100+
101+
define void @boo() {
102+
ret void
103+
}
104+
)"""";
105+
StringRef AssemblyF(FooStr);
106+
107+
TM = getTargetMachine();
108+
109+
if (!TM)
110+
GTEST_SKIP();
111+
112+
// Parse the module.
113+
Expected<bool> MResult = M.create(
114+
[&](llvm::LLVMContext &Context) -> Expected<std::unique_ptr<Module>> {
115+
SMDiagnostic SMError;
116+
std::unique_ptr<Module> M =
117+
parseAssemblyString(AssemblyF, SMError, Context);
118+
if (!M) {
119+
return make_error<StringError>("could not load LLVM file",
120+
inconvertibleErrorCode());
121+
}
122+
return M;
123+
});
124+
125+
ASSERT_FALSE((!MResult));
126+
127+
M->setDataLayout(TM->createDataLayout());
128+
}
129+
130+
LLVMModuleAndContext M;
131+
std::unique_ptr<TargetMachine> TM;
132+
};
133+
134+
TEST_F(MCLinkerTest, SplitModuleCompilerMCLink) {
135+
136+
SymbolAndMCInfo SMCInfo;
137+
bool Failed = false;
138+
139+
auto OutputLambda =
140+
[&](llvm::unique_function<LLVMModuleAndContext()> ProduceModule,
141+
std::optional<int64_t> Idx, unsigned NumFunctionsBase) mutable {
142+
LLVMModuleAndContext SubModule = ProduceModule();
143+
std::unique_ptr<TargetMachine> TM = getTargetMachine();
144+
std::unique_ptr<MCContext> MCCtx = getMCContext(*TM);
145+
MachineModuleInfoWrapperPass *MMIWP = getMMIWP(*TM, *MCCtx);
146+
147+
legacy::PassManager PassMgr;
148+
mclinker::addPassesToEmitMC(*TM, PassMgr, true, MMIWP,
149+
NumFunctionsBase);
150+
if (!PassMgr.run(*SubModule))
151+
Failed = true;
152+
153+
SMCInfo.McInfos.emplace_back(std::make_unique<MCInfo>(
154+
std::make_unique<MachineModuleInfo>(std::move(MMIWP->getMMI())),
155+
std::move(SubModule), std::move(TM), std::move(MCCtx), Idx));
156+
};
157+
158+
splitPerFunction(std::move(M), OutputLambda, SMCInfo.SymbolLinkageTypes, 0);
159+
160+
std::unique_ptr<TargetMachine> TMMCLink = getTargetMachine();
161+
SmallVector<SymbolAndMCInfo *> SMCInfos{&SMCInfo};
162+
llvm::StringMap<llvm::GlobalValue::LinkageTypes> SymbolLinkageTypes;
163+
164+
MCLinker Linker(SMCInfos, *TMMCLink, SymbolLinkageTypes);
165+
166+
Expected<std::unique_ptr<WritableMemoryBuffer>> LinkResult =
167+
Linker.linkAndPrint("SplitModuleCompilerMCLink",
168+
llvm::CodeGenFileType::AssemblyFile, true);
169+
170+
ASSERT_FALSE((!LinkResult));
171+
llvm::dbgs() << "Size: " << (*LinkResult)->getBufferSize() << "\n";
172+
173+
llvm::dbgs() << StringRef((*LinkResult)->getBufferStart()) << "\n";
174+
}
175+
176+
} // end anonymous namespace

0 commit comments

Comments
 (0)