Skip to content

Commit

Permalink
[CIR][CIRGen][TBAA] Initial TBAA support (#1116)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
PikachuHyA authored Nov 19, 2024
1 parent affa8f8 commit e57a9da
Show file tree
Hide file tree
Showing 22 changed files with 579 additions and 181 deletions.
12 changes: 8 additions & 4 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
llvm_unreachable("Zero initializer for given type is NYI");
}

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

return create<cir::LoadOp>(loc, ptr, /*isDeref=*/false, isVolatile,
/*alignment=*/intAttr,
/*mem_order=*/cir::MemOrderAttr{});
/*mem_order=*/
cir::MemOrderAttr{},
/*tbaa=*/mlir::ArrayAttr{});
}

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

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

cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst,
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,9 @@ def GlobalAnnotationValuesAttr : CIR_Attr<"GlobalAnnotationValues",
let genVerifyDecl = 1;
}

def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> {
}

include "clang/CIR/Dialect/IR/CIROpenCLAttrs.td"

#endif // MLIR_CIR_DIALECT_CIR_ATTRS
15 changes: 11 additions & 4 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,8 @@ def LoadOp : CIR_Op<"load", [
[MemRead]>:$addr, UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr<I64Attr>:$alignment,
OptionalAttr<MemOrder>:$mem_order
OptionalAttr<MemOrder>:$mem_order,
OptionalAttr<ArrayAttr>:$tbaa
);
let results = (outs CIR_AnyType:$result);

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

let extraClassDeclaration = [{
Expand Down Expand Up @@ -654,13 +656,15 @@ def StoreOp : CIR_Op<"store", [
[MemWrite]>:$addr,
UnitAttr:$is_volatile,
OptionalAttr<I64Attr>:$alignment,
OptionalAttr<MemOrder>:$mem_order);
OptionalAttr<MemOrder>:$mem_order,
OptionalAttr<ArrayAttr>:$tbaa);

let assemblyFormat = [{
(`volatile` $is_volatile^)?
(`align` `(` $alignment^ `)`)?
(`atomic` `(` $mem_order^ `)`)?
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
(`tbaa` `(` $tbaa^ `)`)?
}];

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

let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
attr-dict `:` qualified(type($dst)) }];
attr-dict `:` qualified(type($dst))
(`tbaa` `(` $tbaa^ `)`)?
}];
let hasVerifier = 1;

let extraClassDeclaration = [{
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct MissingFeatures {
// sanitizer related type check features
static bool emitTypeCheck() { return false; }
static bool tbaa() { return false; }
static bool tbaa_struct() { return false; }
static bool cleanups() { return false; }
static bool emitNullabilityCheck() { return false; }
static bool ptrAuth() { return false; }
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ static void emitAtomicOp(CIRGenFunction &CGF, AtomicExpr *E, Address Dest,
case AtomicExpr::AO__atomic_load:
case AtomicExpr::AO__scoped_atomic_load_n:
case AtomicExpr::AO__scoped_atomic_load: {
auto *load = builder.createLoad(loc, Ptr).getDefiningOp();
auto load = builder.createLoad(loc, Ptr);
// FIXME(cir): add scope information.
assert(!cir::MissingFeatures::syncScopeID());
load->setAttr("mem_order", orderAttr);
Expand Down Expand Up @@ -1462,8 +1462,7 @@ void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest,
if (IsVolatile)
store.setIsVolatile(true);

// DecorateInstructionWithTBAA
assert(!cir::MissingFeatures::tbaa());
CGM.decorateOperationWithTBAA(store, dest.getTBAAInfo());
return;
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
addr.getAlignment());
}

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

mlir::Value createAlignedLoad(mlir::Location loc, mlir::Type ty,
Expand Down
16 changes: 12 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,14 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
assert(!cir::MissingFeatures::addressSpace());
VTableField = builder.createElementBitCast(loc, VTableField,
VTableAddressPoint.getType());
builder.createStore(loc, VTableAddressPoint, VTableField);
assert(!cir::MissingFeatures::tbaa());
auto storeOp = builder.createStore(loc, VTableAddressPoint, VTableField);
TBAAAccessInfo TBAAInfo =
CGM.getTBAAVTablePtrAccessInfo(VTableAddressPoint.getType());
CGM.decorateOperationWithTBAA(storeOp, TBAAInfo);
if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
CGM.getCodeGenOpts().StrictVTablePointers) {
assert(!cir::MissingFeatures::createInvariantGroup());
}
}

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

Address CIRGenFunction::emitCXXMemberDataPointerAddress(
const Expr *E, Address base, mlir::Value memberPtr,
const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo) {
const MemberPointerType *memberPtrType, LValueBaseInfo *baseInfo,
TBAAAccessInfo *tbaaInfo) {
assert(!cir::MissingFeatures::cxxABI());

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

QualType memberType = memberPtrType->getPointeeType();
CharUnits memberAlign = CGM.getNaturalTypeAlignment(memberType, baseInfo);
CharUnits memberAlign =
CGM.getNaturalTypeAlignment(memberType, baseInfo, tbaaInfo);
memberAlign = CGM.getDynamicOffsetAlignment(
base.getAlignment(), memberPtrType->getClass()->getAsCXXRecordDecl(),
memberAlign);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ void CIRGenFunction::emitAutoVarInit(const AutoVarEmission &emission) {
// its removal/optimization to the CIR lowering.
if (!constant || isa<CXXTemporaryObjectExpr>(Init)) {
initializeWhatIsTechnicallyUninitialized(Loc);
LValue lv = LValue::makeAddr(Loc, type, AlignmentSource::Decl);
LValue lv = makeAddrLValue(Loc, type, AlignmentSource::Decl);
emitExprAsInit(Init, &D, lv);
// In case lv has uses it means we indeed initialized something
// out of it while trying to build the expression, mark it as such.
Expand Down
Loading

0 comments on commit e57a9da

Please sign in to comment.