Skip to content

Commit c289083

Browse files
authored
[CIR][ABI][NFC] Prime AArch64 CC lowering (#679)
This patch is a preparation for the AArch64 calling convention lowering. It adds the basic infrastructure to initialize the AArch64 ABI details and validates it against a trivial void return and argument call conv lowering.
1 parent 2dd4609 commit c289083

File tree

15 files changed

+163
-28
lines changed

15 files changed

+163
-28
lines changed
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
#ifndef CIR_AAARCH64_H
3+
#define CIR_AAARCH64_H
4+
5+
namespace cir {
6+
7+
/// The ABI kind for AArch64 targets.
8+
enum class AArch64ABIKind {
9+
AAPCS = 0,
10+
DarwinPCS,
11+
Win64,
12+
AAPCSSoft,
13+
};
14+
15+
} // namespace cir
16+
17+
#endif // CIR_AAARCH64_H

clang/include/clang/CIR/Target/x86.h

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@
1515

1616
namespace cir {
1717

18+
/// The AVX ABI level for X86 targets.
19+
enum class X86AVXABILevel {
20+
None,
21+
AVX,
22+
AVX512,
23+
};
24+
1825
// Possible argument classifications according to the x86 ABI documentation.
1926
enum X86ArgClass {
2027
Integer = 0,

clang/lib/CIR/CodeGen/TargetInfo.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "CIRGenCXXABI.h"
44
#include "CIRGenFunctionInfo.h"
55
#include "CIRGenTypes.h"
6-
#include "CallingConv.h"
76

87
#include "clang/Basic/TargetInfo.h"
98
#include "clang/CIR/Target/x86.h"
@@ -136,10 +135,14 @@ class AArch64TargetCIRGenInfo : public TargetCIRGenInfo {
136135

137136
} // namespace
138137

138+
//===----------------------------------------------------------------------===//
139+
// X86 ABI Implementation
140+
//===----------------------------------------------------------------------===//
141+
139142
namespace {
140143

141144
/// The AVX ABI leel for X86 targets.
142-
enum class X86AVXABILevel { None, AVX, AVX512 };
145+
using X86AVXABILevel = ::cir::X86AVXABILevel;
143146

144147
class X86_64ABIInfo : public ABIInfo {
145148
using Class = X86ArgClass;

clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "LoweringPrepareCXXABI.h"
1010
#include "PassDetail.h"
11-
#include "mlir/Dialect/Func/IR/FuncOps.h"
1211
#include "mlir/IR/BuiltinAttributes.h"
1312
#include "mlir/IR/Region.h"
1413
#include "clang/AST/ASTContext.h"

clang/lib/CIR/Dialect/Transforms/LoweringPrepareCXXABI.h

+2-9
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,14 @@
2020
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
2121
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
2222
#include "clang/CIR/Dialect/IR/CIRDialect.h"
23+
#include "clang/CIR/Target/AArch64.h"
2324

2425
namespace cir {
25-
// TODO: This is a temporary solution to know AArch64 ABI Kind
26-
// This should be removed once we have a proper ABI info query
27-
enum class AArch64ABIKind {
28-
AAPCS = 0,
29-
DarwinPCS,
30-
Win64,
31-
AAPCSSoft,
32-
};
3326

3427
class LoweringPrepareCXXABI {
3528
public:
3629
static LoweringPrepareCXXABI *createItaniumABI();
37-
static LoweringPrepareCXXABI *createAArch64ABI(AArch64ABIKind k);
30+
static LoweringPrepareCXXABI *createAArch64ABI(::cir::AArch64ABIKind k);
3831

3932
virtual mlir::Value lowerVAArg(CIRBaseBuilderTy &builder,
4033
mlir::cir::VAArgOp op,

clang/lib/CIR/Dialect/Transforms/TargetLowering/CIRCXXABI.h

+2-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "mlir/IR/Value.h"
1919
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
2020
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
21+
#include "clang/CIR/Target/AArch64.h"
2122

2223
namespace mlir {
2324
namespace cir {
@@ -51,17 +52,10 @@ CIRCXXABI *CreateItaniumCXXABI(LowerModule &CGM);
5152
// should be updated to follow some level of codegen parity.
5253
namespace cir {
5354

54-
enum class AArch64ABIKind {
55-
AAPCS = 0,
56-
DarwinPCS,
57-
Win64,
58-
AAPCSSoft,
59-
};
60-
6155
class LoweringPrepareCXXABI {
6256
public:
6357
static LoweringPrepareCXXABI *createItaniumABI();
64-
static LoweringPrepareCXXABI *createAArch64ABI(AArch64ABIKind k);
58+
static LoweringPrepareCXXABI *createAArch64ABI(::cir::AArch64ABIKind k);
6559

6660
virtual mlir::Value lowerVAArg(CIRBaseBuilderTy &builder,
6761
mlir::cir::VAArgOp op,

clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ add_clang_library(TargetLowering
1212
RecordLayoutBuilder.cpp
1313
TargetInfo.cpp
1414
TargetLoweringInfo.cpp
15+
Targets/AArch64.cpp
1516
Targets/X86.cpp
1617
Targets/LoweringPrepareAArch64CXXABI.cpp
1718
Targets/LoweringPrepareItaniumCXXABI.cpp

clang/lib/CIR/Dialect/Transforms/TargetLowering/ItaniumCXXABI.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "CIRCXXABI.h"
2424
#include "LowerModule.h"
25+
#include "llvm/Support/ErrorHandling.h"
2526

2627
namespace mlir {
2728
namespace cir {
@@ -30,8 +31,16 @@ namespace {
3031

3132
class ItaniumCXXABI : public CIRCXXABI {
3233

34+
protected:
35+
bool UseARMMethodPtrABI;
36+
bool UseARMGuardVarABI;
37+
bool Use32BitVTableOffsetABI;
38+
3339
public:
34-
ItaniumCXXABI(LowerModule &LM) : CIRCXXABI(LM) {}
40+
ItaniumCXXABI(LowerModule &LM, bool UseARMMethodPtrABI = false,
41+
bool UseARMGuardVarABI = false)
42+
: CIRCXXABI(LM), UseARMMethodPtrABI(UseARMMethodPtrABI),
43+
UseARMGuardVarABI(UseARMGuardVarABI), Use32BitVTableOffsetABI(false) {}
3544

3645
bool classifyReturnType(LowerFunctionInfo &FI) const override;
3746
};
@@ -52,6 +61,13 @@ bool ItaniumCXXABI::classifyReturnType(LowerFunctionInfo &FI) const {
5261

5362
CIRCXXABI *CreateItaniumCXXABI(LowerModule &LM) {
5463
switch (LM.getCXXABIKind()) {
64+
// Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
65+
// include the other 32-bit ARM oddities: constructor/destructor return values
66+
// and array cookies.
67+
case clang::TargetCXXABI::GenericAArch64:
68+
return new ItaniumCXXABI(LM, /*UseARMMethodPtrABI=*/true,
69+
/*UseARMGuardVarABI=*/true);
70+
5571
case clang::TargetCXXABI::GenericItanium:
5672
if (LM.getTargetInfo().getTriple().getArch() == llvm::Triple::le32) {
5773
llvm_unreachable("NYI");

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
#include "mlir/IR/BuiltinAttributes.h"
2020
#include "mlir/IR/PatternMatch.h"
2121
#include "mlir/Support/LogicalResult.h"
22+
#include "clang/CIR/Target/AArch64.h"
2223
#include "llvm/Support/ErrorHandling.h"
2324

2425
using MissingFeatures = ::cir::MissingFeatures;
26+
using AArch64ABIKind = ::cir::AArch64ABIKind;
27+
using X86AVXABILevel = ::cir::X86AVXABILevel;
2528

2629
namespace mlir {
2730
namespace cir {
@@ -52,6 +55,17 @@ createTargetLoweringInfo(LowerModule &LM) {
5255
const llvm::Triple &Triple = Target.getTriple();
5356

5457
switch (Triple.getArch()) {
58+
case llvm::Triple::aarch64: {
59+
AArch64ABIKind Kind = AArch64ABIKind::AAPCS;
60+
if (Target.getABI() == "darwinpcs")
61+
llvm_unreachable("DarwinPCS ABI NYI");
62+
else if (Triple.isOSWindows())
63+
llvm_unreachable("Windows ABI NYI");
64+
else if (Target.getABI() == "aapcs-soft")
65+
llvm_unreachable("AAPCS-soft ABI NYI");
66+
67+
return createAArch64TargetLoweringInfo(LM, Kind);
68+
}
5569
case llvm::Triple::x86_64: {
5670
switch (Triple.getOS()) {
5771
case llvm::Triple::Win32:

clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetInfo.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@
1616

1717
#include "LowerModule.h"
1818
#include "TargetLoweringInfo.h"
19+
#include "clang/CIR/Target/AArch64.h"
20+
#include "clang/CIR/Target/x86.h"
1921

2022
namespace mlir {
2123
namespace cir {
2224

23-
/// The AVX ABI level for X86 targets.
24-
enum class X86AVXABILevel {
25-
None,
26-
AVX,
27-
AVX512,
28-
};
25+
std::unique_ptr<TargetLoweringInfo>
26+
createX86_64TargetLoweringInfo(LowerModule &CGM,
27+
::cir::X86AVXABILevel AVXLevel);
2928

3029
std::unique_ptr<TargetLoweringInfo>
31-
createX86_64TargetLoweringInfo(LowerModule &CGM, X86AVXABILevel AVXLevel);
30+
createAArch64TargetLoweringInfo(LowerModule &CGM,
31+
::cir::AArch64ABIKind AVXLevel);
3232

3333
} // namespace cir
3434
} // namespace mlir
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//===- AArch64.cpp --------------------------------------------------------===//
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+
9+
#include "clang/CIR/Target/AArch64.h"
10+
#include "ABIInfoImpl.h"
11+
#include "LowerFunctionInfo.h"
12+
#include "LowerTypes.h"
13+
#include "TargetInfo.h"
14+
#include "TargetLoweringInfo.h"
15+
#include "clang/CIR/ABIArgInfo.h"
16+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
17+
#include "clang/CIR/MissingFeatures.h"
18+
#include "llvm/Support/ErrorHandling.h"
19+
20+
using AArch64ABIKind = ::cir::AArch64ABIKind;
21+
using ABIArgInfo = ::cir::ABIArgInfo;
22+
using MissingFeature = ::cir::MissingFeatures;
23+
24+
namespace mlir {
25+
namespace cir {
26+
27+
//===----------------------------------------------------------------------===//
28+
// AArch64 ABI Implementation
29+
//===----------------------------------------------------------------------===//
30+
31+
namespace {
32+
33+
class AArch64ABIInfo : public ABIInfo {
34+
AArch64ABIKind Kind;
35+
36+
public:
37+
AArch64ABIInfo(LowerTypes &CGT, AArch64ABIKind Kind)
38+
: ABIInfo(CGT), Kind(Kind) {}
39+
40+
private:
41+
AArch64ABIKind getABIKind() const { return Kind; }
42+
43+
ABIArgInfo classifyReturnType(Type RetTy, bool IsVariadic) const;
44+
45+
void computeInfo(LowerFunctionInfo &FI) const override {
46+
if (!::mlir::cir::classifyReturnType(getCXXABI(), FI, *this))
47+
FI.getReturnInfo() =
48+
classifyReturnType(FI.getReturnType(), FI.isVariadic());
49+
50+
for (auto &_ : FI.arguments())
51+
llvm_unreachable("NYI");
52+
}
53+
};
54+
55+
class AArch64TargetLoweringInfo : public TargetLoweringInfo {
56+
public:
57+
AArch64TargetLoweringInfo(LowerTypes &LT, AArch64ABIKind Kind)
58+
: TargetLoweringInfo(std::make_unique<AArch64ABIInfo>(LT, Kind)) {
59+
assert(!MissingFeature::swift());
60+
}
61+
};
62+
63+
} // namespace
64+
65+
ABIArgInfo AArch64ABIInfo::classifyReturnType(Type RetTy,
66+
bool IsVariadic) const {
67+
if (RetTy.isa<VoidType>())
68+
return ABIArgInfo::getIgnore();
69+
70+
llvm_unreachable("NYI");
71+
}
72+
73+
std::unique_ptr<TargetLoweringInfo>
74+
createAArch64TargetLoweringInfo(LowerModule &CGM, AArch64ABIKind Kind) {
75+
return std::make_unique<AArch64TargetLoweringInfo>(CGM.getTypes(), Kind);
76+
}
77+
78+
} // namespace cir
79+
} // namespace mlir

clang/lib/CIR/Dialect/Transforms/TargetLowering/Targets/X86.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "llvm/Support/ErrorHandling.h"
1111
#include <memory>
1212

13+
using X86AVXABILevel = ::cir::X86AVXABILevel;
14+
1315
namespace mlir {
1416
namespace cir {
1517

clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ add_clang_library(clangCIRLoweringDirectToLLVM
3030
MLIRCIR
3131
MLIRAnalysis
3232
MLIRBuiltinToLLVMIRTranslation
33+
MLIRLLVMToLLVMIRTranslation
3334
MLIRCIRTransforms
3435
MLIRIR
3536
MLIRParser

clang/lib/CIR/Lowering/ThroughMLIR/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ add_clang_library(clangCIRLoweringThroughMLIR
3131
MLIRCIR
3232
MLIRAnalysis
3333
MLIRBuiltinToLLVMIRTranslation
34+
MLIRLLVMToLLVMIRTranslation
3435
MLIRIR
3536
MLIRParser
3637
MLIRSideEffectInterfaces
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -std=c++20 -triple aarch64-unknown-linux-gnu -fclangir -fclangir-call-conv-lowering -emit-cir -mmlir --mlir-print-ir-after=cir-call-conv-lowering %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
// CHECK: @_Z4Voidv()
5+
void Void(void) {
6+
// CHECK: cir.call @_Z4Voidv() : () -> ()
7+
Void();
8+
}

0 commit comments

Comments
 (0)