Skip to content

Commit e57a9da

Browse files
authored
[CIR][CIRGen][TBAA] Initial TBAA support (#1116)
This is the first patch to support TBAA, following the discussion at #1076 (comment) - add skeleton for CIRGen, utilizing `decorateOperationWithTBAA` - add empty implementation in `CIRGenTBAA` - introduce `CIR_TBAAAttr` with empty body - attach `CIR_TBAAAttr` to `LoadOp` and `StoreOp` - no handling of vtable pointer - no LLVM lowering
1 parent affa8f8 commit e57a9da

22 files changed

+579
-181
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
158158
llvm_unreachable("Zero initializer for given type is NYI");
159159
}
160160

161-
mlir::Value createLoad(mlir::Location loc, mlir::Value ptr,
161+
cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
162162
bool isVolatile = false, uint64_t alignment = 0) {
163163
mlir::IntegerAttr intAttr;
164164
if (alignment)
@@ -167,7 +167,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
167167

168168
return create<cir::LoadOp>(loc, ptr, /*isDeref=*/false, isVolatile,
169169
/*alignment=*/intAttr,
170-
/*mem_order=*/cir::MemOrderAttr{});
170+
/*mem_order=*/
171+
cir::MemOrderAttr{},
172+
/*tbaa=*/mlir::ArrayAttr{});
171173
}
172174

173175
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -353,7 +355,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
353355
if (mlir::cast<cir::PointerType>(dst.getType()).getPointee() !=
354356
val.getType())
355357
dst = createPtrBitcast(dst, val.getType());
356-
return create<cir::StoreOp>(loc, val, dst, _volatile, align, order);
358+
return create<cir::StoreOp>(loc, val, dst, _volatile, align, order,
359+
/*tbaa=*/mlir::ArrayAttr{});
357360
}
358361

359362
mlir::Value createAlloca(mlir::Location loc, cir::PointerType addrType,
@@ -400,7 +403,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
400403
/// Create a copy with inferred length.
401404
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
402405
bool isVolatile = false) {
403-
return create<cir::CopyOp>(dst.getLoc(), dst, src, isVolatile);
406+
return create<cir::CopyOp>(dst.getLoc(), dst, src, isVolatile,
407+
/*tbaa=*/mlir::ArrayAttr{});
404408
}
405409

406410
cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst,

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

+3
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,9 @@ def GlobalAnnotationValuesAttr : CIR_Attr<"GlobalAnnotationValues",
12161216
let genVerifyDecl = 1;
12171217
}
12181218

1219+
def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> {
1220+
}
1221+
12191222
include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td"
12201223

12211224
#endif // MLIR_CIR_DIALECT_CIR_ATTRS

clang/include/clang/CIR/Dialect/IR/CIROps.td

+11-4
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,8 @@ def LoadOp : CIR_Op<"load", [
587587
[MemRead]>:$addr, UnitAttr:$isDeref,
588588
UnitAttr:$is_volatile,
589589
OptionalAttr<I64Attr>:$alignment,
590-
OptionalAttr<MemOrder>:$mem_order
590+
OptionalAttr<MemOrder>:$mem_order,
591+
OptionalAttr<ArrayAttr>:$tbaa
591592
);
592593
let results = (outs CIR_AnyType:$result);
593594

@@ -597,6 +598,7 @@ def LoadOp : CIR_Op<"load", [
597598
(`align` `(` $alignment^ `)`)?
598599
(`atomic` `(` $mem_order^ `)`)?
599600
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
601+
(`tbaa` `(` $tbaa^ `)`)?
600602
}];
601603

602604
let extraClassDeclaration = [{
@@ -654,13 +656,15 @@ def StoreOp : CIR_Op<"store", [
654656
[MemWrite]>:$addr,
655657
UnitAttr:$is_volatile,
656658
OptionalAttr<I64Attr>:$alignment,
657-
OptionalAttr<MemOrder>:$mem_order);
659+
OptionalAttr<MemOrder>:$mem_order,
660+
OptionalAttr<ArrayAttr>:$tbaa);
658661

659662
let assemblyFormat = [{
660663
(`volatile` $is_volatile^)?
661664
(`align` `(` $alignment^ `)`)?
662665
(`atomic` `(` $mem_order^ `)`)?
663666
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
667+
(`tbaa` `(` $tbaa^ `)`)?
664668
}];
665669

666670
let extraClassDeclaration = [{
@@ -3980,7 +3984,8 @@ def CopyOp : CIR_Op<"copy",
39803984
DeclareOpInterfaceMethods<PromotableMemOpInterface>]> {
39813985
let arguments = (ins Arg<CIR_PointerType, "", [MemWrite]>:$dst,
39823986
Arg<CIR_PointerType, "", [MemRead]>:$src,
3983-
UnitAttr:$is_volatile);
3987+
UnitAttr:$is_volatile,
3988+
OptionalAttr<ArrayAttr>:$tbaa);
39843989
let summary = "Copies contents from a CIR pointer to another";
39853990
let description = [{
39863991
Given two CIR pointers, `src` and `dst`, `cir.copy` will copy the memory
@@ -3999,7 +4004,9 @@ def CopyOp : CIR_Op<"copy",
39994004
}];
40004005

40014006
let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
4002-
attr-dict `:` qualified(type($dst)) }];
4007+
attr-dict `:` qualified(type($dst))
4008+
(`tbaa` `(` $tbaa^ `)`)?
4009+
}];
40034010
let hasVerifier = 1;
40044011

40054012
let extraClassDeclaration = [{

clang/include/clang/CIR/MissingFeatures.h

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct MissingFeatures {
5858
// sanitizer related type check features
5959
static bool emitTypeCheck() { return false; }
6060
static bool tbaa() { return false; }
61+
static bool tbaa_struct() { return false; }
6162
static bool cleanups() { return false; }
6263
static bool emitNullabilityCheck() { return false; }
6364
static bool ptrAuth() { return false; }

clang/lib/CIR/CodeGen/CIRGenAtomic.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
585585
case AtomicExpr::AO__atomic_load:
586586
case AtomicExpr::AO__scoped_atomic_load_n:
587587
case AtomicExpr::AO__scoped_atomic_load: {
588-
auto *load = builder.createLoad(loc, Ptr).getDefiningOp();
588+
auto load = builder.createLoad(loc, Ptr);
589589
// FIXME(cir): add scope information.
590590
assert(!cir::MissingFeatures::syncScopeID());
591591
load->setAttr("mem_order", orderAttr);
@@ -1462,8 +1462,7 @@ void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest,
14621462
if (IsVolatile)
14631463
store.setIsVolatile(true);
14641464

1465-
// DecorateInstructionWithTBAA
1466-
assert(!cir::MissingFeatures::tbaa());
1465+
CGM.decorateOperationWithTBAA(store, dest.getTBAAInfo());
14671466
return;
14681467
}
14691468

clang/lib/CIR/CodeGen/CIRGenBuilder.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
832832
addr.getAlignment());
833833
}
834834

835-
mlir::Value createLoad(mlir::Location loc, Address addr,
835+
cir::LoadOp createLoad(mlir::Location loc, Address addr,
836836
bool isVolatile = false) {
837837
auto ptrTy = mlir::dyn_cast<cir::PointerType>(addr.getPointer().getType());
838838
if (addr.getElementType() != ptrTy.getPointee())
@@ -842,7 +842,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
842842
return create<cir::LoadOp>(
843843
loc, addr.getElementType(), addr.getPointer(), /*isDeref=*/false,
844844
/*is_volatile=*/isVolatile, /*alignment=*/mlir::IntegerAttr{},
845-
/*mem_order=*/cir::MemOrderAttr{});
845+
/*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
846846
}
847847

848848
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Type ty,

clang/lib/CIR/CodeGen/CIRGenClass.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -751,8 +751,14 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
751751
assert(!cir::MissingFeatures::addressSpace());
752752
VTableField = builder.createElementBitCast(loc, VTableField,
753753
VTableAddressPoint.getType());
754-
builder.createStore(loc, VTableAddressPoint, VTableField);
755-
assert(!cir::MissingFeatures::tbaa());
754+
auto storeOp = builder.createStore(loc, VTableAddressPoint, VTableField);
755+
TBAAAccessInfo TBAAInfo =
756+
CGM.getTBAAVTablePtrAccessInfo(VTableAddressPoint.getType());
757+
CGM.decorateOperationWithTBAA(storeOp, TBAAInfo);
758+
if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
759+
CGM.getCodeGenOpts().StrictVTablePointers) {
760+
assert(!cir::MissingFeatures::createInvariantGroup());
761+
}
756762
}
757763

758764
void CIRGenFunction::initializeVTablePointers(mlir::Location loc,
@@ -1659,14 +1665,16 @@ mlir::Value CIRGenFunction::getVTablePtr(mlir::Location Loc, Address This,
16591665

16601666
Address CIRGenFunction::emitCXXMemberDataPointerAddress(
16611667
const Expr *E, Address base, mlir::Value memberPtr,
1662-
const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo) {
1668+
const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo,
1669+
TBAAAccessInfo *tbaaInfo) {
16631670
assert(!cir::MissingFeatures::cxxABI());
16641671

16651672
auto op = builder.createGetIndirectMember(getLoc(E->getSourceRange()),
16661673
base.getPointer(), memberPtr);
16671674

16681675
QualType memberType = memberPtrType->getPointeeType();
1669-
CharUnits memberAlign = CGM.getNaturalTypeAlignment(memberType, baseInfo);
1676+
CharUnits memberAlign =
1677+
CGM.getNaturalTypeAlignment(memberType, baseInfo, tbaaInfo);
16701678
memberAlign = CGM.getDynamicOffsetAlignment(
16711679
base.getAlignment(), memberPtrType->getClass()->getAsCXXRecordDecl(),
16721680
memberAlign);

clang/lib/CIR/CodeGen/CIRGenDecl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ void CIRGenFunction::emitAutoVarInit(const AutoVarEmission &emission) {
327327
// its removal/optimization to the CIR lowering.
328328
if (!constant || isa<CXXTemporaryObjectExpr>(Init)) {
329329
initializeWhatIsTechnicallyUninitialized(Loc);
330-
LValue lv = LValue::makeAddr(Loc, type, AlignmentSource::Decl);
330+
LValue lv = makeAddrLValue(Loc, type, AlignmentSource::Decl);
331331
emitExprAsInit(Init, &D, lv);
332332
// In case lv has uses it means we indeed initialized something
333333
// out of it while trying to build the expression, mark it as such.

0 commit comments

Comments
 (0)