Skip to content

Commit b9f3b7f

Browse files
committed
[flang][driver] Add support for consuming LLVM IR/BC files
This change makes sure that Flang's driver recognises LLVM IR and BC as supported file formats. To this end, `isFortran` is extended and renamed as `isSupportedByFlang` (the latter better reflects the new functionality). New tests are added to verify that the target triple is correctly overridden by the frontend driver's default value or the value specified with `-triple`. Strictly speaking, this is not a functionality that's new in this patch (it was added in D124664). This patch simply enables us to write such tests and hence I'm including them here. Differential Revision: https://reviews.llvm.org/D124667
1 parent ad2263d commit b9f3b7f

File tree

11 files changed

+139
-17
lines changed

11 files changed

+139
-17
lines changed

clang/include/clang/Driver/Types.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ namespace types {
6666
/// isAcceptedByClang - Can clang handle this input type.
6767
bool isAcceptedByClang(ID Id);
6868

69+
/// isAcceptedByFlang - Can flang handle this input type.
70+
bool isAcceptedByFlang(ID Id);
71+
6972
/// isDerivedFromC - Is the input derived from C.
7073
///
7174
/// That is, does the lexer follow the rules of
@@ -92,9 +95,6 @@ namespace types {
9295
/// isOpenCL - Is this an "OpenCL" input.
9396
bool isOpenCL(ID Id);
9497

95-
/// isFortran - Is this a Fortran input.
96-
bool isFortran(ID Id);
97-
9898
/// isSrcFile - Is this a source file, i.e. something that still has to be
9999
/// preprocessed. The logic behind this is the same that decides if the first
100100
/// compilation phase is a preprocessing one.

clang/lib/Driver/Driver.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6050,11 +6050,12 @@ bool Driver::ShouldUseClangCompiler(const JobAction &JA) const {
60506050
bool Driver::ShouldUseFlangCompiler(const JobAction &JA) const {
60516051
// Say "no" if there is not exactly one input of a type flang understands.
60526052
if (JA.size() != 1 ||
6053-
!types::isFortran((*JA.input_begin())->getType()))
6053+
!types::isAcceptedByFlang((*JA.input_begin())->getType()))
60546054
return false;
60556055

60566056
// And say "no" if this is not a kind of action flang understands.
6057-
if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
6057+
if (!isa<PreprocessJobAction>(JA) && !isa<CompileJobAction>(JA) &&
6058+
!isa<BackendJobAction>(JA))
60586059
return false;
60596060

60606061
return true;

clang/lib/Driver/Types.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,20 @@ bool types::isAcceptedByClang(ID Id) {
159159
}
160160
}
161161

162+
bool types::isAcceptedByFlang(ID Id) {
163+
switch (Id) {
164+
default:
165+
return false;
166+
167+
case TY_Fortran:
168+
case TY_PP_Fortran:
169+
return true;
170+
case TY_LLVM_IR:
171+
case TY_LLVM_BC:
172+
return true;
173+
}
174+
}
175+
162176
bool types::isDerivedFromC(ID Id) {
163177
switch (Id) {
164178
default:
@@ -272,16 +286,6 @@ bool types::isHIP(ID Id) {
272286
}
273287
}
274288

275-
bool types::isFortran(ID Id) {
276-
switch (Id) {
277-
default:
278-
return false;
279-
280-
case TY_Fortran: case TY_PP_Fortran:
281-
return true;
282-
}
283-
}
284-
285289
bool types::isSrcFile(ID Id) {
286290
return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
287291
}

flang/lib/Frontend/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ add_flang_library(flangFrontend
4040
LINK_COMPONENTS
4141
Passes
4242
Analysis
43+
IRReader
4344
Option
4445
Support
4546
Target

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ bool PrescanAndSemaDebugAction::BeginSourceFileAction() {
7373
}
7474

7575
bool CodeGenAction::BeginSourceFileAction() {
76+
llvmCtx = std::make_unique<llvm::LLVMContext>();
77+
78+
// If the input is an LLVM file, just parse it and return.
79+
if (this->currentInput().kind().GetLanguage() == Language::LLVM_IR) {
80+
llvm::SMDiagnostic err;
81+
llvmModule = llvm::parseIRFile(currentInput().file(), err, *llvmCtx);
82+
83+
return (nullptr != llvmModule);
84+
}
85+
86+
// Otherwise, generate an MLIR module from the input Fortran source
87+
assert(currentInput().kind().GetLanguage() == Language::Fortran &&
88+
"Invalid input type - expecting a Fortran file");
7689
bool res = RunPrescan() && RunParse() && RunSemanticChecks();
7790
if (!res)
7891
return res;
@@ -448,7 +461,6 @@ void CodeGenAction::GenerateLLVMIR() {
448461

449462
// Translate to LLVM IR
450463
llvm::Optional<llvm::StringRef> moduleName = mlirModule->getName();
451-
llvmCtx = std::make_unique<llvm::LLVMContext>();
452464
llvmModule = mlir::translateModuleToLLVMIR(
453465
*mlirModule, *llvmCtx, moduleName ? *moduleName : "FIRModule");
454466

flang/lib/Frontend/FrontendOptions.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,9 @@ InputKind FrontendOptions::GetInputKindForExtension(llvm::StringRef extension) {
3535
if (isFixedFormSuffix(extension) || isFreeFormSuffix(extension)) {
3636
return Language::Fortran;
3737
}
38+
39+
if (extension == "bc" || extension == "ll")
40+
return Language::LLVM_IR;
41+
3842
return Language::Unknown;
3943
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; Verify that the driver can consume LLVM BC files. The expected assembly is
2+
; fairly generic (tested on AArch64 and X86_64), but we may need to tweak when
3+
; testing on other platforms. Note that the actual output doesn't matter as
4+
; long as it's in Assembly format.
5+
6+
;-------------
7+
; RUN COMMANDS
8+
;-------------
9+
; RUN: rm -f %t.bc
10+
; RUN: %flang_fc1 -emit-llvm-bc %s -o %t.bc
11+
; RUN: %flang_fc1 -S -o - %t.bc | FileCheck %s
12+
; RUN: rm -f %t.bc
13+
14+
; RUN: rm -f %t.bc
15+
; RUN: %flang -c -emit-llvm %s -o %t.bc
16+
; RUN: %flang -S -o - %t.bc | FileCheck %s
17+
; RUN: rm -f %t.bc
18+
19+
;----------------
20+
; EXPECTED OUTPUT
21+
;----------------
22+
; CHECK-LABEL: foo:
23+
; CHECK: ret
24+
25+
;------
26+
; INPUT
27+
;------
28+
define void @foo() {
29+
ret void
30+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; Verify that the driver can consume LLVM IR files. The expected assembly is
2+
; fairly generic (verified on AArch64 and X86_64), but we may need to tweak when
3+
; testing on other platforms. Note that the actual output doesn't matter
4+
; as long as it's in Assembly format.
5+
6+
;-------------
7+
; RUN COMMANDS
8+
;-------------
9+
; RUN: %flang_fc1 -S %s -o - | FileCheck %s
10+
; RUN: %flang -S %s -o - | FileCheck %s
11+
12+
;----------------
13+
; EXPECTED OUTPUT
14+
;----------------
15+
; CHECK-LABEL: foo:
16+
; CHECK: ret
17+
18+
;------
19+
; INPUT
20+
;------
21+
define void @foo() {
22+
ret void
23+
}

flang/test/Driver/missing-triple.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
; Verify that the module triple is overridden by the driver - even when the
2+
; module triple is missing.
3+
; NOTE: At the time of writing, the tested behaviour was consistent with Clang
4+
5+
;-------------
6+
; RUN COMMANDS
7+
;-------------
8+
; RUN: %flang_fc1 -S %s -o - 2>&1 | FileCheck %s
9+
; RUN: %flang -S %s -o - 2>&1 | FileCheck %s
10+
11+
;----------------
12+
; EXPECTED OUTPUT
13+
;----------------
14+
; CHECK: warning: overriding the module target triple with {{.*}}
15+
16+
;------
17+
; INPUT
18+
;------
19+
define void @foo() {
20+
ret void
21+
}

flang/test/Driver/override-triple.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; Verify that the module triple is overridden by the driver - even in the presence
2+
; of a module triple.
3+
; NOTE: At the time of writing, the tested behaviour was consistent with Clang
4+
5+
;-------------
6+
; RUN COMMANDS
7+
;-------------
8+
; RUN: %flang_fc1 -S %s -o - 2>&1 | FileCheck %s
9+
; RUN: %flang -S %s -o - 2>&1 | FileCheck %s
10+
11+
;----------------
12+
; EXPECTED OUTPUT
13+
;----------------
14+
; CHECK: warning: overriding the module target triple with {{.*}}
15+
16+
;------
17+
; INPUT
18+
;------
19+
; For the triple to be overridden by the driver, it needs to be different to the host triple.
20+
; Use a random string to guarantee that.
21+
target triple = "invalid-triple"
22+
23+
define void @foo() {
24+
ret void
25+
}

0 commit comments

Comments
 (0)