Skip to content

Commit 02e6c13

Browse files
committed
[CIR][NFC] move data member pointer lowering to CXXABI
This patch moves the lowering code for data member pointers from the conversion patterns to the implementation of CXXABI because this part should be ABI- specific.
1 parent bae7bd9 commit 02e6c13

File tree

5 files changed

+174
-71
lines changed

5 files changed

+174
-71
lines changed

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

+26
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,15 @@
1515
#define LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_CIRCXXABI_H
1616

1717
#include "LowerFunctionInfo.h"
18+
#include "mlir/IR/Attributes.h"
19+
#include "mlir/IR/Types.h"
1820
#include "mlir/IR/Value.h"
21+
#include "mlir/Interfaces/DataLayoutInterfaces.h"
22+
#include "mlir/Transforms/DialectConversion.h"
1923
#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
24+
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
2025
#include "clang/CIR/Dialect/IR/CIRDataLayout.h"
26+
#include "clang/CIR/Dialect/IR/CIRTypes.h"
2127
#include "clang/CIR/Target/AArch64.h"
2228

2329
namespace cir {
@@ -59,6 +65,26 @@ class CIRCXXABI {
5965
/// Returns how an argument of the given record type should be passed.
6066
/// FIXME(cir): This expects a CXXRecordDecl! Not any record type.
6167
virtual RecordArgABI getRecordArgABI(const StructType RD) const = 0;
68+
69+
/// Lower the given data member pointer type to its ABI type. The returned
70+
/// type is also a CIR type.
71+
virtual mlir::Type
72+
lowerDataMemberType(cir::DataMemberType type,
73+
const mlir::TypeConverter &typeConverter) const = 0;
74+
75+
/// Lower the given data member pointer constant to a constant of the ABI
76+
/// type. The returned constant is represented as an attribute as well.
77+
virtual mlir::TypedAttr
78+
lowerDataMemberConstant(cir::DataMemberAttr attr,
79+
const mlir::DataLayout &layout,
80+
const mlir::TypeConverter &typeConverter) const = 0;
81+
82+
/// Lower the given cir.get_runtime_member op to a sequence of more
83+
/// "primitive" CIR operations that act on the ABI types.
84+
virtual mlir::Operation *
85+
lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
86+
mlir::Value loweredAddr, mlir::Value loweredMember,
87+
mlir::OpBuilder &builder) const = 0;
6288
};
6389

6490
/// Creates an Itanium-family ABI.

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

+62
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "../LoweringPrepareCXXABI.h"
2424
#include "CIRCXXABI.h"
2525
#include "LowerModule.h"
26+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
2627
#include "llvm/Support/ErrorHandling.h"
2728

2829
namespace cir {
@@ -51,6 +52,19 @@ class ItaniumCXXABI : public CIRCXXABI {
5152
cir_cconv_assert(!cir::MissingFeatures::recordDeclCanPassInRegisters());
5253
return RAA_Default;
5354
}
55+
56+
mlir::Type
57+
lowerDataMemberType(cir::DataMemberType type,
58+
const mlir::TypeConverter &typeConverter) const override;
59+
60+
mlir::TypedAttr lowerDataMemberConstant(
61+
cir::DataMemberAttr attr, const mlir::DataLayout &layout,
62+
const mlir::TypeConverter &typeConverter) const override;
63+
64+
mlir::Operation *
65+
lowerGetRuntimeMember(cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
66+
mlir::Value loweredAddr, mlir::Value loweredMember,
67+
mlir::OpBuilder &builder) const override;
5468
};
5569

5670
} // namespace
@@ -67,6 +81,54 @@ bool ItaniumCXXABI::classifyReturnType(LowerFunctionInfo &FI) const {
6781
return false;
6882
}
6983

84+
mlir::Type ItaniumCXXABI::lowerDataMemberType(
85+
cir::DataMemberType type, const mlir::TypeConverter &typeConverter) const {
86+
// Itanium C++ ABI 2.3:
87+
// A pointer to data member is an offset from the base address of
88+
// the class object containing it, represented as a ptrdiff_t
89+
const clang::TargetInfo &target = LM.getTarget();
90+
clang::TargetInfo::IntType ptrdiffTy =
91+
target.getPtrDiffType(clang::LangAS::Default);
92+
return cir::IntType::get(type.getContext(), target.getTypeWidth(ptrdiffTy),
93+
target.isTypeSigned(ptrdiffTy));
94+
}
95+
96+
mlir::TypedAttr ItaniumCXXABI::lowerDataMemberConstant(
97+
cir::DataMemberAttr attr, const mlir::DataLayout &layout,
98+
const mlir::TypeConverter &typeConverter) const {
99+
uint64_t memberOffset;
100+
if (attr.isNullPtr()) {
101+
// Itanium C++ ABI 2.3:
102+
// A NULL pointer is represented as -1.
103+
memberOffset = -1ull;
104+
} else {
105+
// Itanium C++ ABI 2.3:
106+
// A pointer to data member is an offset from the base address of
107+
// the class object containing it, represented as a ptrdiff_t
108+
auto memberIndex = attr.getMemberIndex().value();
109+
memberOffset =
110+
attr.getType().getClsTy().getElementOffset(layout, memberIndex);
111+
}
112+
113+
mlir::Type abiTy = lowerDataMemberType(attr.getType(), typeConverter);
114+
return cir::IntAttr::get(abiTy, memberOffset);
115+
}
116+
117+
mlir::Operation *ItaniumCXXABI::lowerGetRuntimeMember(
118+
cir::GetRuntimeMemberOp op, mlir::Type loweredResultTy,
119+
mlir::Value loweredAddr, mlir::Value loweredMember,
120+
mlir::OpBuilder &builder) const {
121+
auto byteTy = IntType::get(op.getContext(), 8, true);
122+
auto bytePtrTy = PointerType::get(
123+
byteTy, mlir::cast<PointerType>(op.getAddr().getType()).getAddrSpace());
124+
auto objectBytesPtr = builder.create<CastOp>(op.getLoc(), bytePtrTy,
125+
CastKind::bitcast, op.getAddr());
126+
auto memberBytesPtr = builder.create<PtrStrideOp>(
127+
op.getLoc(), bytePtrTy, objectBytesPtr, loweredMember);
128+
return builder.create<CastOp>(op.getLoc(), op.getType(), CastKind::bitcast,
129+
memberBytesPtr);
130+
}
131+
70132
CIRCXXABI *CreateItaniumCXXABI(LowerModule &LM) {
71133
switch (LM.getCXXABIKind()) {
72134
// Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

+48-57
Original file line numberDiff line numberDiff line change
@@ -1521,28 +1521,6 @@ bool hasTrailingZeros(cir::ConstArrayAttr attr) {
15211521
}));
15221522
}
15231523

1524-
static mlir::Attribute
1525-
lowerDataMemberAttr(mlir::ModuleOp moduleOp, cir::DataMemberAttr attr,
1526-
const mlir::TypeConverter &typeConverter) {
1527-
mlir::DataLayout layout{moduleOp};
1528-
1529-
uint64_t memberOffset;
1530-
if (attr.isNullPtr()) {
1531-
// TODO(cir): the numerical value of a null data member pointer is
1532-
// ABI-specific and should be queried through ABI.
1533-
assert(!MissingFeatures::targetCodeGenInfoGetNullPointer());
1534-
memberOffset = -1ull;
1535-
} else {
1536-
auto memberIndex = attr.getMemberIndex().value();
1537-
memberOffset =
1538-
attr.getType().getClsTy().getElementOffset(layout, memberIndex);
1539-
}
1540-
1541-
auto underlyingIntTy = mlir::IntegerType::get(
1542-
moduleOp->getContext(), layout.getTypeSizeInBits(attr.getType()));
1543-
return mlir::IntegerAttr::get(underlyingIntTy, memberOffset);
1544-
}
1545-
15461524
mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
15471525
cir::ConstantOp op, OpAdaptor adaptor,
15481526
mlir::ConversionPatternRewriter &rewriter) const {
@@ -1602,9 +1580,13 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
16021580
}
16031581
attr = op.getValue();
16041582
} else if (mlir::isa<cir::DataMemberType>(op.getType())) {
1583+
assert(lowerMod && "lower module is not available");
16051584
auto dataMember = mlir::cast<cir::DataMemberAttr>(op.getValue());
1606-
attr = lowerDataMemberAttr(op->getParentOfType<mlir::ModuleOp>(),
1607-
dataMember, *typeConverter);
1585+
mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
1586+
mlir::TypedAttr abiValue = lowerMod->getCXXABI().lowerDataMemberConstant(
1587+
dataMember, layout, *typeConverter);
1588+
rewriter.replaceOpWithNewOp<ConstantOp>(op, abiValue);
1589+
return mlir::success();
16081590
}
16091591
// TODO(cir): constant arrays are currently just pushed into the stack using
16101592
// the store instruction, instead of being stored as global variables and
@@ -2208,8 +2190,15 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
22082190
return mlir::success();
22092191
} else if (auto dataMemberAttr =
22102192
mlir::dyn_cast<cir::DataMemberAttr>(init.value())) {
2211-
init = lowerDataMemberAttr(op->getParentOfType<mlir::ModuleOp>(),
2212-
dataMemberAttr, *typeConverter);
2193+
assert(lowerMod && "lower module is not available");
2194+
mlir::DataLayout layout(op->getParentOfType<mlir::ModuleOp>());
2195+
mlir::TypedAttr abiValue = lowerMod->getCXXABI().lowerDataMemberConstant(
2196+
dataMemberAttr, layout, *typeConverter);
2197+
auto abiOp = mlir::cast<GlobalOp>(rewriter.clone(*op.getOperation()));
2198+
abiOp.setInitialValueAttr(abiValue);
2199+
abiOp.setSymType(abiValue.getType());
2200+
rewriter.replaceOp(op, abiOp);
2201+
return mlir::success();
22132202
} else if (const auto structAttr =
22142203
mlir::dyn_cast<cir::ConstStructAttr>(init.value())) {
22152204
setupRegionInitializedLLVMGlobalOp(op, rewriter);
@@ -3237,11 +3226,11 @@ mlir::LogicalResult CIRToLLVMGetMemberOpLowering::matchAndRewrite(
32373226
mlir::LogicalResult CIRToLLVMGetRuntimeMemberOpLowering::matchAndRewrite(
32383227
cir::GetRuntimeMemberOp op, OpAdaptor adaptor,
32393228
mlir::ConversionPatternRewriter &rewriter) const {
3240-
auto llvmResTy = getTypeConverter()->convertType(op.getType());
3241-
auto llvmElementTy = mlir::IntegerType::get(op.getContext(), 8);
3242-
3243-
rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(
3244-
op, llvmResTy, llvmElementTy, adaptor.getAddr(), adaptor.getMember());
3229+
assert(lowerMod && "lowering module is not available");
3230+
mlir::Type llvmResTy = getTypeConverter()->convertType(op.getType());
3231+
mlir::Operation *llvmOp = lowerMod->getCXXABI().lowerGetRuntimeMember(
3232+
op, llvmResTy, adaptor.getAddr(), adaptor.getMember(), rewriter);
3233+
rewriter.replaceOp(op, llvmOp);
32453234
return mlir::success();
32463235
}
32473236

@@ -3850,14 +3839,17 @@ mlir::LogicalResult CIRToLLVMSignBitOpLowering::matchAndRewrite(
38503839

38513840
void populateCIRToLLVMConversionPatterns(
38523841
mlir::RewritePatternSet &patterns, mlir::TypeConverter &converter,
3853-
mlir::DataLayout &dataLayout,
3842+
mlir::DataLayout &dataLayout, cir::LowerModule *lowerModule,
38543843
llvm::StringMap<mlir::LLVM::GlobalOp> &stringGlobalsMap,
38553844
llvm::StringMap<mlir::LLVM::GlobalOp> &argStringGlobalsMap,
38563845
llvm::MapVector<mlir::ArrayAttr, mlir::LLVM::GlobalOp> &argsVarMap) {
38573846
patterns.add<CIRToLLVMReturnOpLowering>(patterns.getContext());
38583847
patterns.add<CIRToLLVMAllocaOpLowering>(converter, dataLayout,
38593848
stringGlobalsMap, argStringGlobalsMap,
38603849
argsVarMap, patterns.getContext());
3850+
patterns.add<CIRToLLVMConstantOpLowering, CIRToLLVMGlobalOpLowering,
3851+
CIRToLLVMGetRuntimeMemberOpLowering>(
3852+
converter, patterns.getContext(), lowerModule);
38613853
patterns.add<
38623854
CIRToLLVMCmpOpLowering, CIRToLLVMSelectOpLowering,
38633855
CIRToLLVMBitClrsbOpLowering, CIRToLLVMBitClzOpLowering,
@@ -3870,28 +3862,25 @@ void populateCIRToLLVMConversionPatterns(
38703862
CIRToLLVMTryCallOpLowering, CIRToLLVMEhInflightOpLowering,
38713863
CIRToLLVMUnaryOpLowering, CIRToLLVMBinOpLowering,
38723864
CIRToLLVMBinOpOverflowOpLowering, CIRToLLVMShiftOpLowering,
3873-
CIRToLLVMLoadOpLowering, CIRToLLVMConstantOpLowering,
3874-
CIRToLLVMStoreOpLowering, CIRToLLVMFuncOpLowering,
3875-
CIRToLLVMCastOpLowering, CIRToLLVMGlobalOpLowering,
3865+
CIRToLLVMLoadOpLowering, CIRToLLVMStoreOpLowering,
3866+
CIRToLLVMFuncOpLowering, CIRToLLVMCastOpLowering,
38763867
CIRToLLVMGetGlobalOpLowering, CIRToLLVMComplexCreateOpLowering,
38773868
CIRToLLVMComplexRealOpLowering, CIRToLLVMComplexImagOpLowering,
38783869
CIRToLLVMComplexRealPtrOpLowering, CIRToLLVMComplexImagPtrOpLowering,
38793870
CIRToLLVMVAStartOpLowering, CIRToLLVMVAEndOpLowering,
38803871
CIRToLLVMVACopyOpLowering, CIRToLLVMVAArgOpLowering,
38813872
CIRToLLVMBrOpLowering, CIRToLLVMGetMemberOpLowering,
3882-
CIRToLLVMGetRuntimeMemberOpLowering, CIRToLLVMSwitchFlatOpLowering,
3883-
CIRToLLVMPtrDiffOpLowering, CIRToLLVMCopyOpLowering,
3884-
CIRToLLVMMemCpyOpLowering, CIRToLLVMMemChrOpLowering,
3885-
CIRToLLVMAbsOpLowering, CIRToLLVMExpectOpLowering,
3886-
CIRToLLVMVTableAddrPointOpLowering, CIRToLLVMVecCreateOpLowering,
3887-
CIRToLLVMVecCmpOpLowering, CIRToLLVMVecSplatOpLowering,
3888-
CIRToLLVMVecTernaryOpLowering, CIRToLLVMVecShuffleDynamicOpLowering,
3889-
CIRToLLVMVecShuffleOpLowering, CIRToLLVMStackSaveOpLowering,
3890-
CIRToLLVMUnreachableOpLowering, CIRToLLVMTrapOpLowering,
3891-
CIRToLLVMInlineAsmOpLowering, CIRToLLVMSetBitfieldOpLowering,
3892-
CIRToLLVMGetBitfieldOpLowering, CIRToLLVMPrefetchOpLowering,
3893-
CIRToLLVMObjSizeOpLowering, CIRToLLVMIsConstantOpLowering,
3894-
CIRToLLVMCmpThreeWayOpLowering, CIRToLLVMMemCpyOpLowering,
3873+
CIRToLLVMSwitchFlatOpLowering, CIRToLLVMPtrDiffOpLowering,
3874+
CIRToLLVMCopyOpLowering, CIRToLLVMMemCpyOpLowering,
3875+
CIRToLLVMMemChrOpLowering, CIRToLLVMAbsOpLowering,
3876+
CIRToLLVMExpectOpLowering, CIRToLLVMVTableAddrPointOpLowering,
3877+
CIRToLLVMVecCreateOpLowering, CIRToLLVMVecCmpOpLowering,
3878+
CIRToLLVMVecSplatOpLowering, CIRToLLVMVecTernaryOpLowering,
3879+
CIRToLLVMVecShuffleDynamicOpLowering, CIRToLLVMVecShuffleOpLowering,
3880+
CIRToLLVMStackSaveOpLowering, CIRToLLVMUnreachableOpLowering,
3881+
CIRToLLVMTrapOpLowering, CIRToLLVMInlineAsmOpLowering,
3882+
CIRToLLVMSetBitfieldOpLowering, CIRToLLVMGetBitfieldOpLowering,
3883+
CIRToLLVMPrefetchOpLowering, CIRToLLVMObjSizeOpLowering,
38953884
CIRToLLVMIsConstantOpLowering, CIRToLLVMCmpThreeWayOpLowering,
38963885
CIRToLLVMReturnAddrOpLowering, CIRToLLVMClearCacheOpLowering,
38973886
CIRToLLVMEhTypeIdOpLowering, CIRToLLVMCatchParamOpLowering,
@@ -3901,10 +3890,9 @@ void populateCIRToLLVMConversionPatterns(
39013890
CIRToLLVMAssumeAlignedOpLowering, CIRToLLVMAssumeSepStorageOpLowering,
39023891
CIRToLLVMBaseClassAddrOpLowering, CIRToLLVMDerivedClassAddrOpLowering,
39033892
CIRToLLVMVTTAddrPointOpLowering, CIRToLLVMIsFPClassOpLowering,
3904-
CIRToLLVMAbsOpLowering, CIRToLLVMMemMoveOpLowering,
3905-
CIRToLLVMMemSetOpLowering, CIRToLLVMMemSetInlineOpLowering,
3906-
CIRToLLVMMemCpyInlineOpLowering, CIRToLLVMSignBitOpLowering,
3907-
CIRToLLVMPtrMaskOpLowering
3893+
CIRToLLVMMemMoveOpLowering, CIRToLLVMMemSetOpLowering,
3894+
CIRToLLVMMemSetInlineOpLowering, CIRToLLVMMemCpyInlineOpLowering,
3895+
CIRToLLVMSignBitOpLowering, CIRToLLVMPtrMaskOpLowering
39083896
#define GET_BUILTIN_LOWERING_LIST
39093897
#include "clang/CIR/Dialect/IR/CIRBuiltinsLowering.inc"
39103898
#undef GET_BUILTIN_LOWERING_LIST
@@ -3947,9 +3935,12 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
39473935

39483936
return mlir::LLVM::LLVMPointerType::get(type.getContext(), targetAS);
39493937
});
3950-
converter.addConversion([&](cir::DataMemberType type) -> mlir::Type {
3951-
return mlir::IntegerType::get(type.getContext(),
3952-
dataLayout.getTypeSizeInBits(type));
3938+
converter.addConversion([&, lowerModule](
3939+
cir::DataMemberType type) -> mlir::Type {
3940+
assert(lowerModule && "CXXABI is not available");
3941+
mlir::Type abiType =
3942+
lowerModule->getCXXABI().lowerDataMemberType(type, converter);
3943+
return converter.convertType(abiType);
39533944
});
39543945
converter.addConversion([&](cir::ArrayType type) -> mlir::Type {
39553946
auto ty = converter.convertType(type.getEltType());
@@ -4285,8 +4276,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
42854276
llvm::MapVector<mlir::ArrayAttr, mlir::LLVM::GlobalOp> argsVarMap;
42864277

42874278
populateCIRToLLVMConversionPatterns(patterns, converter, dataLayout,
4288-
stringGlobalsMap, argStringGlobalsMap,
4289-
argsVarMap);
4279+
lowerModule.get(), stringGlobalsMap,
4280+
argStringGlobalsMap, argsVarMap);
42904281
mlir::populateFuncToLLVMConversionPatterns(converter, patterns);
42914282

42924283
mlir::ConversionTarget target(getContext());

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

+22-3
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,15 @@ class CIRToLLVMStoreOpLowering
291291

292292
class CIRToLLVMConstantOpLowering
293293
: public mlir::OpConversionPattern<cir::ConstantOp> {
294+
cir::LowerModule *lowerMod;
295+
294296
public:
295-
using mlir::OpConversionPattern<cir::ConstantOp>::OpConversionPattern;
297+
CIRToLLVMConstantOpLowering(const mlir::TypeConverter &typeConverter,
298+
mlir::MLIRContext *context,
299+
cir::LowerModule *lowerModule)
300+
: OpConversionPattern(typeConverter, context), lowerMod(lowerModule) {
301+
setHasBoundedRewriteRecursion();
302+
}
296303

297304
mlir::LogicalResult
298305
matchAndRewrite(cir::ConstantOp op, OpAdaptor,
@@ -490,8 +497,15 @@ class CIRToLLVMSwitchFlatOpLowering
490497

491498
class CIRToLLVMGlobalOpLowering
492499
: public mlir::OpConversionPattern<cir::GlobalOp> {
500+
cir::LowerModule *lowerMod;
501+
493502
public:
494-
using mlir::OpConversionPattern<cir::GlobalOp>::OpConversionPattern;
503+
CIRToLLVMGlobalOpLowering(const mlir::TypeConverter &typeConverter,
504+
mlir::MLIRContext *context,
505+
cir::LowerModule *lowerModule)
506+
: OpConversionPattern(typeConverter, context), lowerMod(lowerModule) {
507+
setHasBoundedRewriteRecursion();
508+
}
495509

496510
mlir::LogicalResult
497511
matchAndRewrite(cir::GlobalOp op, OpAdaptor,
@@ -774,8 +788,13 @@ class CIRToLLVMGetMemberOpLowering
774788

775789
class CIRToLLVMGetRuntimeMemberOpLowering
776790
: public mlir::OpConversionPattern<cir::GetRuntimeMemberOp> {
791+
cir::LowerModule *lowerMod;
792+
777793
public:
778-
using mlir::OpConversionPattern<cir::GetRuntimeMemberOp>::OpConversionPattern;
794+
CIRToLLVMGetRuntimeMemberOpLowering(const mlir::TypeConverter &typeConverter,
795+
mlir::MLIRContext *context,
796+
cir::LowerModule *lowerModule)
797+
: OpConversionPattern(typeConverter, context), lowerMod(lowerModule) {}
779798

780799
mlir::LogicalResult
781800
matchAndRewrite(cir::GetRuntimeMemberOp op, OpAdaptor,

0 commit comments

Comments
 (0)