Skip to content

Commit cdfac7f

Browse files
[CIR] Upstream initial TBAA implementation
1 parent e6f60a6 commit cdfac7f

19 files changed

+516
-61
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
205205
bool isVolatile = false, uint64_t alignment = 0) {
206206
mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
207207
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
208-
alignmentAttr, cir::MemOrderAttr{});
208+
alignmentAttr, cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
209209
}
210210

211211
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -321,14 +321,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
321321
/// Create a copy with inferred length.
322322
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
323323
bool isVolatile = false) {
324-
return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile);
324+
return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile, /*tbaa=*/mlir::ArrayAttr{});
325325
}
326326

327327
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
328328
bool isVolatile = false,
329329
mlir::IntegerAttr align = {},
330330
cir::MemOrderAttr order = {}) {
331-
return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order);
331+
return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order, /*tbaa=*/mlir::ArrayAttr{});
332332
}
333333

334334
[[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
@@ -353,7 +353,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
353353
auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
354354
return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
355355
/*isVolatile=*/false, alignmentAttr,
356-
/*mem_order=*/{});
356+
/*mem_order=*/{}, /*tbaa=*/mlir::ArrayAttr{});
357357
}
358358

359359
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,14 @@ def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
447447
}];
448448
}
449449

450+
//===----------------------------------------------------------------------===//
451+
// TBAAAttr
452+
//===----------------------------------------------------------------------===//
453+
454+
def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> {
455+
let summary = "CIR dialect TBAA base attribute";
456+
}
457+
450458
//===----------------------------------------------------------------------===//
451459
// GlobalViewAttr
452460
//===----------------------------------------------------------------------===//

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,10 @@ def CIR_LoadOp : CIR_Op<"load", [
586586
UnitAttr:$isDeref,
587587
UnitAttr:$is_volatile,
588588
OptionalAttr<I64Attr>:$alignment,
589-
OptionalAttr<CIR_MemOrder>:$mem_order);
589+
OptionalAttr<CIR_MemOrder>:$mem_order,
590+
OptionalAttr<ArrayAttr>:$tbaa
591+
);
592+
590593
let results = (outs CIR_AnyType:$result);
591594

592595
let assemblyFormat = [{
@@ -595,6 +598,7 @@ def CIR_LoadOp : CIR_Op<"load", [
595598
(`align` `(` $alignment^ `)`)?
596599
(`atomic` `(` $mem_order^ `)`)?
597600
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
601+
(`tbaa` `(` $tbaa^ `)`)?
598602
}];
599603

600604
// FIXME: add verifier.
@@ -638,13 +642,16 @@ def CIR_StoreOp : CIR_Op<"store", [
638642
[MemWrite]>:$addr,
639643
UnitAttr:$is_volatile,
640644
OptionalAttr<I64Attr>:$alignment,
641-
OptionalAttr<CIR_MemOrder>:$mem_order);
645+
OptionalAttr<CIR_MemOrder>:$mem_order,
646+
OptionalAttr<ArrayAttr>:$tbaa
647+
);
642648

643649
let assemblyFormat = [{
644650
(`volatile` $is_volatile^)?
645651
(`align` `(` $alignment^ `)`)?
646652
(`atomic` `(` $mem_order^ `)`)?
647653
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
654+
(`tbaa` `(` $tbaa^ `)`)?
648655
}];
649656

650657
// FIXME: add verifier.
@@ -2979,12 +2986,16 @@ def CIR_CopyOp : CIR_Op<"copy",[
29792986
let arguments = (ins
29802987
Arg<CIR_PointerType, "", [MemWrite]>:$dst,
29812988
Arg<CIR_PointerType, "", [MemRead]>:$src,
2982-
UnitAttr:$is_volatile
2989+
UnitAttr:$is_volatile,
2990+
OptionalAttr<ArrayAttr>:$tbaa
29832991
);
29842992

2985-
let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
2986-
attr-dict `:` qualified(type($dst))
2993+
let assemblyFormat = [{
2994+
$src `to` $dst (`volatile` $is_volatile^)?
2995+
attr-dict `:` qualified(type($dst))
2996+
(`tbaa` `(` $tbaa^ `)`)?
29872997
}];
2998+
29882999
let hasVerifier = 1;
29893000

29903001
let extraClassDeclaration = [{
@@ -2994,7 +3005,7 @@ def CIR_CopyOp : CIR_Op<"copy",[
29943005
/// Returns the number of bytes to be copied.
29953006
unsigned getLength(const mlir::DataLayout &dt) {
29963007
return dt.getTypeSize(getType().getPointee());
2997-
}
3008+
}
29983009
}];
29993010
}
30003011

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ struct MissingFeatures {
302302
static bool openCL() { return false; }
303303
static bool openMP() { return false; }
304304
static bool opTBAA() { return false; }
305+
static bool opTBAAStruct() { return false; }
305306
static bool peepholeProtection() { return false; }
306307
static bool pgoUse() { return false; }
307308
static bool pointerAuthentication() { return false; }

clang/lib/CIR/CodeGen/CIRGenAtomic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,7 @@ void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest,
10111011
if (isVolatile)
10121012
store.setIsVolatile(true);
10131013

1014-
assert(!cir::MissingFeatures::opLoadStoreTbaa());
1014+
cgm.decorateOperationWithTBAA(store, dest.getTBAAInfo());
10151015
return;
10161016
}
10171017

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
462462
mlir::IntegerAttr align = getAlignmentAttr(addr.getAlignment());
463463
return cir::LoadOp::create(*this, loc, addr.getPointer(), /*isDeref=*/false,
464464
isVolatile, /*alignment=*/align,
465-
/*mem_order=*/cir::MemOrderAttr{});
465+
/*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
466466
}
467467

468468
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
@@ -473,7 +473,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
473473
mlir::IntegerAttr alignAttr = getAlignmentAttr(alignment);
474474
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,
475475
/*isVolatile=*/false, alignAttr,
476-
/*mem_order=*/cir::MemOrderAttr{});
476+
/*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
477477
}
478478

479479
cir::LoadOp

clang/lib/CIR/CodeGen/CIRGenClass.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,15 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
429429
builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());
430430
Address vtableField = Address(vtablePtr, classAddr.getAlignment());
431431
builder.createStore(loc, vtableAddressPoint, vtableField);
432-
assert(!cir::MissingFeatures::opTBAA());
432+
433+
cir::StoreOp storeOp = builder.createStore(loc, vtableAddressPoint, vtableField);
434+
TBAAAccessInfo tbaaInfo =
435+
cgm.getTBAAVTablePtrAccessInfo(vtableAddressPoint.getType());
436+
cgm.decorateOperationWithTBAA(storeOp, tbaaInfo);
437+
if (cgm.getCodeGenOpts().OptimizationLevel > 0 &&
438+
cgm.getCodeGenOpts().StrictVTablePointers) {
439+
}
440+
433441
assert(!cir::MissingFeatures::createInvariantGroup());
434442
}
435443

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "CIRGenConstantEmitter.h"
1515
#include "CIRGenFunction.h"
1616
#include "CIRGenModule.h"
17+
#include "CIRGenTBAA.h"
1718
#include "CIRGenValue.h"
1819
#include "mlir/IR/BuiltinAttributes.h"
1920
#include "mlir/IR/Value.h"
@@ -69,7 +70,8 @@ Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
6970
/// Given an expression of pointer type, try to
7071
/// derive a more accurate bound on the alignment of the pointer.
7172
Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
72-
LValueBaseInfo *baseInfo) {
73+
LValueBaseInfo *baseInfo,
74+
TBAAAccessInfo *tbaaInfo) {
7375
// We allow this with ObjC object pointers because of fragile ABIs.
7476
assert(expr->getType()->isPointerType() ||
7577
expr->getType()->isObjCObjectPointerType());
@@ -98,12 +100,18 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
98100
*baseInfo = innerBaseInfo;
99101

100102
if (isa<ExplicitCastExpr>(ce)) {
101-
LValueBaseInfo targetTypeBaseInfo;
102-
103103
const QualType pointeeType = expr->getType()->getPointeeType();
104+
105+
LValueBaseInfo targetTypeBaseInfo;
104106
const CharUnits align =
105107
cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
106108

109+
if (tbaaInfo) {
110+
TBAAAccessInfo targetTypeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
111+
*tbaaInfo =
112+
cgm.mergeTBAAInfoForCast(*tbaaInfo, targetTypeTbaaInfo);
113+
}
114+
107115
// If the source l-value is opaque, honor the alignment of the
108116
// casted-to type.
109117
if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
@@ -315,7 +323,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
315323

316324
void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
317325
bool isVolatile, QualType ty,
318-
LValueBaseInfo baseInfo, bool isInit,
326+
LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo,
327+
bool isInit,
319328
bool isNontemporal) {
320329
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
321330

@@ -338,8 +347,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
338347

339348
value = emitToMemory(value, ty);
340349

341-
assert(!cir::MissingFeatures::opLoadStoreTbaa());
342-
LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
350+
LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
343351
if (ty->isAtomicType() ||
344352
(!isInit && isLValueSuitableForInlineAtomic(atomicLValue))) {
345353
emitAtomicStore(RValue::get(value), atomicLValue, isInit);
@@ -357,14 +365,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
357365
}
358366

359367
assert(currSrcLoc && "must pass in source location");
360-
builder.createStore(*currSrcLoc, value, addr, isVolatile);
368+
cir::StoreOp store = builder.createStore(*currSrcLoc, value, addr, isVolatile);
369+
cgm.decorateOperationWithTBAA(store, tbaaInfo);
361370

362371
if (isNontemporal) {
363372
cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
364373
return;
365374
}
366-
367-
assert(!cir::MissingFeatures::opTBAA());
368375
}
369376

370377
// TODO: Replace this with a proper TargetInfo function call.
@@ -426,6 +433,8 @@ Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
426433
LValue CIRGenFunction::emitLValueForBitField(LValue base,
427434
const FieldDecl *field) {
428435
LValueBaseInfo baseInfo = base.getBaseInfo();
436+
TBAAAccessInfo tbaaInfo{};
437+
429438
const CIRGenRecordLayout &layout =
430439
cgm.getTypes().getCIRGenRecordLayout(field->getParent());
431440
const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
@@ -444,7 +453,7 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base,
444453
// TODO(cir): Support TBAA for bit fields.
445454
assert(!cir::MissingFeatures::opTBAA());
446455
LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
447-
return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
456+
return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo, tbaaInfo);
448457
}
449458

450459
LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
@@ -457,7 +466,10 @@ LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
457466
const RecordDecl *rec = field->getParent();
458467
AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();
459468
LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));
460-
assert(!cir::MissingFeatures::opTBAA());
469+
TBAAAccessInfo fieldTbaaInfo{};
470+
471+
// TODO(cir): Initialize tbaa info
472+
assert(!MissingFeatures::opTBAA());
461473

462474
Address addr = base.getAddress();
463475
if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
@@ -489,11 +501,11 @@ LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
489501
// If this is a reference field, load the reference right now.
490502
if (fieldType->isReferenceType()) {
491503
assert(!cir::MissingFeatures::opTBAA());
492-
LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo);
504+
LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo, fieldTbaaInfo);
493505
if (recordCVR & Qualifiers::Volatile)
494506
refLVal.getQuals().addVolatile();
495507
addr = emitLoadOfReference(refLVal, getLoc(field->getSourceRange()),
496-
&fieldBaseInfo);
508+
&fieldBaseInfo, &fieldTbaaInfo);
497509

498510
// Qualifiers on the struct don't apply to the referencee.
499511
recordCVR = 0;
@@ -561,13 +573,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,
561573
}
562574

563575
emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
564-
lvalue.getType(), lvalue.getBaseInfo(), isInit,
576+
lvalue.getType(), lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
565577
/*isNontemporal=*/false);
566578
}
567579

568580
mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
569581
QualType ty, SourceLocation loc,
570-
LValueBaseInfo baseInfo) {
582+
LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo) {
571583
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
572584
mlir::Type eltTy = addr.getElementType();
573585

@@ -586,8 +598,7 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
586598
"emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
587599
}
588600

589-
assert(!cir::MissingFeatures::opLoadStoreTbaa());
590-
LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
601+
LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
591602
if (ty->isAtomicType() || isLValueSuitableForInlineAtomic(atomicLValue))
592603
cgm.errorNYI("emitLoadOfScalar: load atomic");
593604

@@ -596,19 +607,21 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
596607

597608
assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck());
598609

599-
mlir::Value loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
610+
cir::LoadOp loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
611+
cgm.decorateOperationWithTBAA(loadOp, tbaaInfo);
612+
600613
if (!ty->isBooleanType() && ty->hasBooleanRepresentation())
601614
cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");
602615

616+
603617
return loadOp;
604618
}
605619

606620
mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
607621
SourceLocation loc) {
608622
assert(!cir::MissingFeatures::opLoadStoreNontemporal());
609-
assert(!cir::MissingFeatures::opLoadStoreTbaa());
610623
return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
611-
lvalue.getType(), loc, lvalue.getBaseInfo());
624+
lvalue.getType(), loc, lvalue.getBaseInfo(), lvalue.getTBAAInfo());
612625
}
613626

614627
/// Given an expression that represents a value lvalue, this
@@ -2285,17 +2298,19 @@ RValue CIRGenFunction::emitReferenceBindingToExpr(const Expr *e) {
22852298
}
22862299

22872300
Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
2288-
LValueBaseInfo *pointeeBaseInfo) {
2301+
LValueBaseInfo *pointeeBaseInfo, TBAAAccessInfo *pointeeTbaaInfo) {
22892302
if (refLVal.isVolatile())
22902303
cgm.errorNYI(loc, "load of volatile reference");
22912304

2305+
QualType pointeeType = refLVal.getType()->getPointeeType();
22922306
cir::LoadOp load =
22932307
cir::LoadOp::create(builder, loc, refLVal.getAddress().getElementType(),
22942308
refLVal.getAddress().getPointer());
22952309

2296-
assert(!cir::MissingFeatures::opTBAA());
2310+
cgm.decorateOperationWithTBAA(load, refLVal.getTBAAInfo());
2311+
if (pointeeTbaaInfo)
2312+
*pointeeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
22972313

2298-
QualType pointeeType = refLVal.getType()->getPointeeType();
22992314
CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
23002315
return Address(load, convertTypeForMem(pointeeType), align);
23012316
}
@@ -2306,10 +2321,10 @@ LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,
23062321
AlignmentSource source) {
23072322
LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
23082323
LValueBaseInfo pointeeBaseInfo;
2309-
assert(!cir::MissingFeatures::opTBAA());
2310-
Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
2324+
TBAAAccessInfo tbaaAccessInfo;
2325+
Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo, &tbaaAccessInfo);
23112326
return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
2312-
pointeeBaseInfo);
2327+
pointeeBaseInfo, tbaaAccessInfo);
23132328
}
23142329

23152330
void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {

clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,13 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
983983
[[maybe_unused]] cir::CopyOp copyOp =
984984
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), isVolatile);
985985

986-
assert(!cir::MissingFeatures::opTBAA());
986+
assert(!cir::MissingFeatures::opTBAAStruct());
987+
988+
if (cgm.getCodeGenOpts().NewStructPathTBAA) {
989+
TBAAAccessInfo tbaaInfo = cgm.mergeTBAAInfoForMemoryTransfer(
990+
dest.getTBAAInfo(), src.getTBAAInfo());
991+
cgm.decorateOperationWithTBAA(copyOp, tbaaInfo);
992+
}
987993
}
988994

989995
// TODO(cir): This could be shared with classic codegen.

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "CIRGenCXXABI.h"
1616
#include "CIRGenCall.h"
17+
#include "CIRGenTBAA.h"
1718
#include "CIRGenValue.h"
1819
#include "mlir/IR/Location.h"
1920
#include "clang/AST/ExprCXX.h"

0 commit comments

Comments
 (0)