Skip to content

Commit 929fc69

Browse files
committed
[Patmos][Clang] Now correctly links object files given as input.
Also can handle files with unknown inputs, archives, and c-files give using the -x flag.
1 parent b5b38c5 commit 929fc69

13 files changed

+217
-34
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3590,6 +3590,17 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
35903590
if (!Current)
35913591
break;
35923592

3593+
// For patmos, if linking is the final result, we only compile to bitcode
3594+
if (llvm::Triple(getTargetTriple()).getArch() == llvm::Triple::patmos &&
3595+
PL.back() == phases::Link &&
3596+
// Stop before llc
3597+
Phase == phases::Backend
3598+
) {
3599+
LinkerInputs.push_back(Current);
3600+
Current = nullptr;
3601+
break;
3602+
}
3603+
35933604
// Queue linker inputs.
35943605
if (Phase == phases::Link) {
35953606
assert(Phase == PL.back() && "linking must be final compilation step.");

clang/lib/Driver/ToolChains/Patmos.cpp

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -185,18 +185,43 @@ std::string patmos::PatmosBaseTool::getLibPath(const char* LibName) const {
185185
return path;
186186
}
187187

188+
/// Return whether the given command line argument is an input file (i.e., .c .o .s files etc.)
189+
static bool isInputFileArg(const Arg* arg) {
190+
return
191+
arg->getOption().getName().compare("<input>") == 0 &&
192+
arg->getNumValues() == 1;
193+
}
194+
195+
static bool isBitcodeFileInput(const InputInfo* in) {
196+
return in->isFilename() && StringRef(in->getFilename()).endswith(".bc");
197+
}
198+
199+
/// Returns the command line argument (if any) matches the given input
200+
static llvm::Optional<const Arg*> getInputArg(const InputInfo &input, const llvm::opt::ArgList &Args) {
201+
202+
if(input.isFilename()) {
203+
for(auto arg: Args) {
204+
if(isInputFileArg(arg) && StringRef(arg->getValue()).compare(input.getFilename())==0 ) {
205+
return arg;
206+
}
207+
}
208+
}
209+
return llvm::None;
210+
}
211+
188212
void patmos::PatmosBaseTool::PrepareLink1Inputs(
189213
const llvm::opt::ArgList &Args,
190214
const InputInfoList &Inputs,
191215
llvm::opt::ArgStringList &LinkInputs) const
192216
{
193217
for (InputInfoList::const_iterator
194218
it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
195-
const InputInfo &II = *it;
219+
const InputInfo &II = *it;
196220

197-
if (II.isFilename()) {
198-
LinkInputs.push_back(II.getFilename());
199-
}
221+
// Add any bitcode files to linking
222+
if(isBitcodeFileInput(&II)) {
223+
LinkInputs.push_back(II.getFilename());
224+
}
200225
}
201226

202227
if(Args.hasArg(options::OPT_v)) {
@@ -206,14 +231,14 @@ void patmos::PatmosBaseTool::PrepareLink1Inputs(
206231

207232
void patmos::PatmosBaseTool::PrepareLink2Inputs(
208233
const llvm::opt::ArgList &Args,
209-
const char* Input,
234+
llvm::Optional<const char*> Input,
210235
llvm::opt::ArgStringList &LinkInputs) const
211236
{
212237
LinkInputs.push_back(Args.MakeArgString(getLibPath("lib/crt0.o")));
213238
LinkInputs.push_back(Args.MakeArgString(getLibPath("lib/crtbegin.o")));
214239
LinkInputs.push_back(Args.MakeArgString(getLibPath("lib/crtend.o")));
215240

216-
LinkInputs.push_back(Input);
241+
if(Input) LinkInputs.push_back(*Input);
217242

218243
// We hide symbols to allow redefinition of stdlib symbols without
219244
// clashing with stdlib
@@ -597,6 +622,7 @@ void patmos::Compile::ConstructJob(Compilation &C, const JobAction &JA,
597622
{
598623
if( // Compile to bitcode
599624
matchesJob(JA, types::TY_LLVM_BC, Action::BackendJobClass) ||
625+
matchesJob(JA, types::TY_LLVM_BC, Action::CompileJobClass) ||
600626
// Compile to LLVM-IR (textual format)
601627
matchesJob(JA, types::TY_LLVM_IR, Action::BackendJobClass) ||
602628
// Compile to assembly (textual format)
@@ -607,28 +633,16 @@ void patmos::Compile::ConstructJob(Compilation &C, const JobAction &JA,
607633
// Compile to machine code
608634
matchesJob(JA, types::TY_Object, Action::AssembleJobClass)
609635
){
610-
// Make job to compile to BC
636+
// Make job to compile to bitcode first
611637
BackendJobAction prelink_job((Action*) &JA, types::TY_LLVM_BC);
638+
const char *BCFilename = CreateOutputFilename(C, Output, "clang-", "bc", false);
639+
const InputInfo TmpOutput(types::TY_LLVM_BC, BCFilename, Inputs[0].getFilename());
612640

613-
if( C.getActions().size() > 0 &&
614-
matchesJob(**C.getActions().begin(), types::TY_Image, Action::LinkJobClass)
615-
){
616-
// The ultimate job is to produce an executable, therefore, produce only bitcode
617-
// which is compiled into machine code in FinalLink
618-
Clang::ConstructJob(C, prelink_job, Output, Inputs, Args, LinkingOutput);
619-
} else {
620-
// We just need an object file
621-
const char *BCFilename = CreateOutputFilename(C, Output, "clang-", "bc", false);
622-
623-
const InputInfo TmpOutput(types::TY_LLVM_BC, BCFilename, Inputs[0].getFilename());
624-
Clang::ConstructJob(C, prelink_job, TmpOutput, Inputs, Args, LinkingOutput);
625-
626-
////////////////////////////////////////////////////////////////////////////
627-
// build LLC command
628-
ConstructLLCJob(*this, C, JA, Output, Inputs, Output.getFilename(),
629-
BCFilename, Args);
630-
}
641+
Clang::ConstructJob(C, prelink_job, TmpOutput, Inputs, Args, LinkingOutput);
631642

643+
// Then compile it to machine code
644+
ConstructLLCJob(*this, C, JA, Output, Inputs, Output.getFilename(),
645+
BCFilename, Args);
632646
} else {
633647
auto &Diag = TC.getDriver().getDiags();
634648
auto DiagID = Diag.getCustomDiagID(DiagnosticsEngine::Error,
@@ -643,12 +657,19 @@ void patmos::FinalLink::ConstructJob(Compilation &C, const JobAction &JA,
643657
const ArgList &Args,
644658
const char *LinkingOutput) const
645659
{
646-
//////////////////////////////////////////////////////////////////////////////
647-
// build LINK 1 command
648-
const char *link1Out = CreateOutputFilename(C, Output, "link-", "bc", false);
649-
ArgStringList LinkInputs;
650-
PrepareLink1Inputs(Args, Inputs, LinkInputs);
651-
ConstructLLVMLinkJob(*this, C, JA, Output, Inputs, link1Out, LinkInputs, Args);
660+
auto any_bc_files = std::any_of(Inputs.begin(), Inputs.end(), [&](auto input){
661+
return isBitcodeFileInput(&input);
662+
});
663+
664+
llvm::Optional<const char*> link1Out = llvm::None;
665+
if(any_bc_files) {
666+
//////////////////////////////////////////////////////////////////////////////
667+
// build LINK 1 command
668+
link1Out = CreateOutputFilename(C, Output, "link-", "bc", false);
669+
ArgStringList LinkInputs;
670+
PrepareLink1Inputs(Args, Inputs, LinkInputs);
671+
ConstructLLVMLinkJob(*this, C, JA, Output, Inputs, *link1Out, LinkInputs, Args);
672+
}
652673

653674
//////////////////////////////////////////////////////////////////////////////
654675
// build LINK 2 command
@@ -683,13 +704,20 @@ void patmos::FinalLink::ConstructJob(Compilation &C, const JobAction &JA,
683704
ConstructLLVMLinkJob(*this, C, JA, Output, Inputs, link4Out, Link4Inputs, Args);
684705

685706
////////////////////////////////////////////////////////////////////////////
686-
// build LLC command
707+
// build LLC and LLD commands
687708
const char *llcOut = CreateOutputFilename(C, Output, "llc-", "bc", false);
688709
ConstructLLCJob(*this, C, JA, Output, Inputs, llcOut,
689710
link4Out, Args);
690711

691712
ArgStringList LLDInputs;
692713
LLDInputs.push_back(llcOut);
714+
/// Add object files to link
715+
for(auto input: Inputs) {
716+
if(input.isFilename() && !isBitcodeFileInput(&input)) {
717+
LLDInputs.push_back(input.getFilename());
718+
}
719+
}
720+
693721
ConstructLLDJob(*this, C, JA, Output, Inputs, Output.getFilename(),
694722
LLDInputs, Args, true);
695723

clang/lib/Driver/ToolChains/Patmos.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class PatmosBaseTool {
6969
const InputInfoList &Inputs,
7070
llvm::opt::ArgStringList &LinkInputs) const;
7171
void PrepareLink2Inputs(const llvm::opt::ArgList &Args,
72-
const char* Input,
72+
llvm::Optional<const char*> Input,
7373
llvm::opt::ArgStringList &LinkInputs) const;
7474
void PrepareLink3Inputs(const llvm::opt::ArgList &Args,
7575
const char* Input,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang --target=patmos %S/helpers/helper-function.c -c -o %t-object.o
2+
// RUN: %clang --target=patmos %S/helpers/helper-function2.c -c -o %t-object2.o
3+
// RUN: ar cr %t-archive.a %t-object.o %t-object2.o
4+
// RUN: %clang --target=patmos %s %t-archive.a -o %t
5+
// RUN: llvm-objdump -rd %t | FileCheck %s
6+
// END.
7+
///////////////////////////////////////////////////////////////////////////////////////////////////
8+
//
9+
// Tests can add archive file to compile command
10+
//
11+
///////////////////////////////////////////////////////////////////////////////////////////////////
12+
13+
// CHECK-DAG: <helper_source_function>
14+
extern int helper_source_function(int x);
15+
// CHECK-DAG: <helper_source_function2>
16+
extern int helper_source_function2(int x);
17+
18+
// CHECK-DAG: <main>
19+
int main() {
20+
return helper_source_function2(helper_source_function(0));
21+
}
22+
23+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang --target=patmos %S/helpers/helper-function.c -c -o %t-object.o
2+
// RUN: %clang --target=patmos %s %t-object.o -o %t
3+
// RUN: llvm-objdump -rd %t | FileCheck %s
4+
// END.
5+
///////////////////////////////////////////////////////////////////////////////////////////////////
6+
//
7+
// Tests can add object file to compile command
8+
//
9+
///////////////////////////////////////////////////////////////////////////////////////////////////
10+
11+
// CHECK-DAG: <helper_source_function>
12+
extern int helper_source_function(int x);
13+
14+
// CHECK-DAG: <main>
15+
int main() {
16+
return helper_source_function(0);
17+
}
18+
19+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clang --target=patmos %S/helpers/helper-function.c -c -o %t-object.unknown-ext
2+
// RUN: %clang --target=patmos %s %t-object.unknown-ext -o %t
3+
// RUN: llvm-objdump -rd %t | FileCheck %s
4+
// END.
5+
///////////////////////////////////////////////////////////////////////////////////////////////////
6+
//
7+
// Tests can add object files with unkown extensions to compile
8+
//
9+
///////////////////////////////////////////////////////////////////////////////////////////////////
10+
11+
// CHECK-DAG: <helper_source_function>
12+
extern int helper_source_function(int x);
13+
14+
// CHECK-DAG: <main>
15+
int main() {
16+
return helper_source_function(0);
17+
}
18+
19+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang --target=patmos %S/helpers/helper-function.c -c -o %t-object.o
2+
// RUN: %clang --target=patmos %S/helpers/helper-function2.c -c -o %t-object2.o
3+
// RUN: ar cr %t-archive.a %t-object.o %t-object2.o
4+
// RUN: %clang --target=patmos %s -c -o %t-object3.o
5+
// RUN: ar cr %t-archive2.a %t-object3.o
6+
// RUN: %clang -v --target=patmos %t-archive.a %t-archive2.a -o %t
7+
// RUN: llvm-objdump -rd %t | FileCheck %s
8+
// END.
9+
///////////////////////////////////////////////////////////////////////////////////////////////////
10+
//
11+
// Tests can compile only archive files
12+
//
13+
///////////////////////////////////////////////////////////////////////////////////////////////////
14+
15+
// CHECK-DAG: <helper_source_function>
16+
extern int helper_source_function(int x);
17+
// CHECK-DAG: <helper_source_function2>
18+
extern int helper_source_function2(int x);
19+
20+
// CHECK-DAG: <main>
21+
int main(int x) {
22+
return helper_source_function(helper_source_function2(x));
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang --target=patmos %S/helpers/helper-main.c -c -o %t-object.o
2+
// RUN: %clang --target=patmos %S/helpers/helper-function.c -c -o %t-object2.o
3+
// RUN: %clang --target=patmos %t-object.o %t-object2.o -o %t
4+
// RUN: llvm-objdump -rd %t | FileCheck %s
5+
// END.
6+
///////////////////////////////////////////////////////////////////////////////////////////////////
7+
//
8+
// Tests can compile only an object files
9+
//
10+
///////////////////////////////////////////////////////////////////////////////////////////////////
11+
12+
// CHECK-DAG: <main>
13+
// CHECK-DAG: <helper_source_function>
14+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang --target=patmos %S/helpers/helper-main.c -c -o %t-object.unknown-ext
2+
// RUN: %clang --target=patmos %S/helpers/helper-function.c -c -o %t-object2.unknown-ext
3+
// RUN: %clang --target=patmos %t-object.unknown-ext %t-object2.unknown-ext -o %t
4+
// RUN: llvm-objdump -rd %t | FileCheck %s
5+
// END.
6+
///////////////////////////////////////////////////////////////////////////////////////////////////
7+
//
8+
// Tests can compile only object files with unknown extension
9+
//
10+
///////////////////////////////////////////////////////////////////////////////////////////////////
11+
12+
// CHECK-DAG: <main>
13+
// CHECK-DAG: <helper_source_function>
14+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: cp %S/helpers/helper-function.c %t.unknown-ext
2+
// RUN: %clang --target=patmos %S/two-source-files.c -x c %t.unknown-ext -o %t
3+
// RUN: llvm-objdump -rd %t | FileCheck %s
4+
// END.
5+
///////////////////////////////////////////////////////////////////////////////////////////////////
6+
//
7+
// Tests can define a file explicitly (using '-x' flag) as a C file.
8+
//
9+
///////////////////////////////////////////////////////////////////////////////////////////////////
10+
11+
// CHECK-DAG: <main>
12+
// CHECK-DAG: <helper_source_function>
13+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
///////////////////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// This is a helper .c file that isn't itself a test.
4+
//
5+
///////////////////////////////////////////////////////////////////////////////////////////////////
6+
volatile int HELPER_SOURCE_INT_2 = 2;
7+
8+
int helper_source_function2(int x) {
9+
return x + HELPER_SOURCE_INT_2;
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
///////////////////////////////////////////////////////////////////////////////////////////////////
2+
//
3+
// This is a helper .c file that isn't itself a test.
4+
//
5+
///////////////////////////////////////////////////////////////////////////////////////////////////
6+
volatile int HELPER_SOURCE_INT_1 = 1;
7+
8+
int main() {
9+
return HELPER_SOURCE_INT_1;
10+
}

clang/test/Driver/Patmos/output-llvm.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@
99

1010
// CHECK: i32 @main()
1111
int main() {
12-
// CHECK: entry:
1312
// CHECK: ret i32 0
1413
}

0 commit comments

Comments
 (0)