-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[CIR] Upstream initial TBAA implementation #169226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
89e04a2 to
cdfac7f
Compare
|
@llvm/pr-subscribers-clang Author: Hendrik Hübner (HendrikHuebner) ChangesThis PR implements the basic handling for emitting TBAA attributes during lowering. TODO: Tests Patch is 46.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/169226.diff 19 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index be9965ae3101f..371f046c25ba0 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
bool isVolatile = false, uint64_t alignment = 0) {
mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
- alignmentAttr, cir::MemOrderAttr{});
+ alignmentAttr, cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
}
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -321,14 +321,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
/// Create a copy with inferred length.
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
bool isVolatile = false) {
- return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile);
+ return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile, /*tbaa=*/mlir::ArrayAttr{});
}
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
bool isVolatile = false,
mlir::IntegerAttr align = {},
cir::MemOrderAttr order = {}) {
- return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order);
+ return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order, /*tbaa=*/mlir::ArrayAttr{});
}
[[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
@@ -353,7 +353,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
/*isVolatile=*/false, alignmentAttr,
- /*mem_order=*/{});
+ /*mem_order=*/{}, /*tbaa=*/mlir::ArrayAttr{});
}
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 12bc9cf7b5b04..5dbfe9334c867 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -447,6 +447,14 @@ def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
}];
}
+//===----------------------------------------------------------------------===//
+// TBAAAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> {
+ let summary = "CIR dialect TBAA base attribute";
+}
+
//===----------------------------------------------------------------------===//
// GlobalViewAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a19c4f951fff9..40710783c97c0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -586,7 +586,10 @@ def CIR_LoadOp : CIR_Op<"load", [
UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr<I64Attr>:$alignment,
- OptionalAttr<CIR_MemOrder>:$mem_order);
+ OptionalAttr<CIR_MemOrder>:$mem_order,
+ OptionalAttr<ArrayAttr>:$tbaa
+ );
+
let results = (outs CIR_AnyType:$result);
let assemblyFormat = [{
@@ -595,6 +598,7 @@ def CIR_LoadOp : CIR_Op<"load", [
(`align` `(` $alignment^ `)`)?
(`atomic` `(` $mem_order^ `)`)?
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
+ (`tbaa` `(` $tbaa^ `)`)?
}];
// FIXME: add verifier.
@@ -638,13 +642,16 @@ def CIR_StoreOp : CIR_Op<"store", [
[MemWrite]>:$addr,
UnitAttr:$is_volatile,
OptionalAttr<I64Attr>:$alignment,
- OptionalAttr<CIR_MemOrder>:$mem_order);
+ OptionalAttr<CIR_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^ `)`)?
}];
// FIXME: add verifier.
@@ -2979,12 +2986,16 @@ def CIR_CopyOp : CIR_Op<"copy",[
let arguments = (ins
Arg<CIR_PointerType, "", [MemWrite]>:$dst,
Arg<CIR_PointerType, "", [MemRead]>:$src,
- UnitAttr:$is_volatile
+ UnitAttr:$is_volatile,
+ OptionalAttr<ArrayAttr>:$tbaa
);
- let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
- attr-dict `:` qualified(type($dst))
+ let assemblyFormat = [{
+ $src `to` $dst (`volatile` $is_volatile^)?
+ attr-dict `:` qualified(type($dst))
+ (`tbaa` `(` $tbaa^ `)`)?
}];
+
let hasVerifier = 1;
let extraClassDeclaration = [{
@@ -2994,7 +3005,7 @@ def CIR_CopyOp : CIR_Op<"copy",[
/// Returns the number of bytes to be copied.
unsigned getLength(const mlir::DataLayout &dt) {
return dt.getTypeSize(getType().getPointee());
- }
+ }
}];
}
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index c99fd6f0bfcc4..defcb5dd600d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -302,6 +302,7 @@ struct MissingFeatures {
static bool openCL() { return false; }
static bool openMP() { return false; }
static bool opTBAA() { return false; }
+ static bool opTBAAStruct() { return false; }
static bool peepholeProtection() { return false; }
static bool pgoUse() { return false; }
static bool pointerAuthentication() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 48c082d89de18..aea832051b355 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -1011,7 +1011,7 @@ void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest,
if (isVolatile)
store.setIsVolatile(true);
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
+ cgm.decorateOperationWithTBAA(store, dest.getTBAAInfo());
return;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 85b38120169fd..98cabf899bfa7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -462,7 +462,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
mlir::IntegerAttr align = getAlignmentAttr(addr.getAlignment());
return cir::LoadOp::create(*this, loc, addr.getPointer(), /*isDeref=*/false,
isVolatile, /*alignment=*/align,
- /*mem_order=*/cir::MemOrderAttr{});
+ /*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
}
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
@@ -473,7 +473,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
mlir::IntegerAttr alignAttr = getAlignmentAttr(alignment);
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,
/*isVolatile=*/false, alignAttr,
- /*mem_order=*/cir::MemOrderAttr{});
+ /*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
}
cir::LoadOp
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 0f10347944fae..b775317a6a0c0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -429,7 +429,15 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());
Address vtableField = Address(vtablePtr, classAddr.getAlignment());
builder.createStore(loc, vtableAddressPoint, vtableField);
- assert(!cir::MissingFeatures::opTBAA());
+
+ cir::StoreOp 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());
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 70497258eb64a..dd1143c9301b1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -14,6 +14,7 @@
#include "CIRGenConstantEmitter.h"
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
+#include "CIRGenTBAA.h"
#include "CIRGenValue.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Value.h"
@@ -69,7 +70,8 @@ Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
/// Given an expression of pointer type, try to
/// derive a more accurate bound on the alignment of the pointer.
Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
- LValueBaseInfo *baseInfo) {
+ LValueBaseInfo *baseInfo,
+ TBAAAccessInfo *tbaaInfo) {
// We allow this with ObjC object pointers because of fragile ABIs.
assert(expr->getType()->isPointerType() ||
expr->getType()->isObjCObjectPointerType());
@@ -98,12 +100,18 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
*baseInfo = innerBaseInfo;
if (isa<ExplicitCastExpr>(ce)) {
- LValueBaseInfo targetTypeBaseInfo;
-
const QualType pointeeType = expr->getType()->getPointeeType();
+
+ LValueBaseInfo targetTypeBaseInfo;
const CharUnits align =
cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
+ if (tbaaInfo) {
+ TBAAAccessInfo targetTypeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
+ *tbaaInfo =
+ cgm.mergeTBAAInfoForCast(*tbaaInfo, targetTypeTbaaInfo);
+ }
+
// If the source l-value is opaque, honor the alignment of the
// casted-to type.
if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
@@ -315,7 +323,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
bool isVolatile, QualType ty,
- LValueBaseInfo baseInfo, bool isInit,
+ LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo,
+ bool isInit,
bool isNontemporal) {
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
@@ -338,8 +347,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
value = emitToMemory(value, ty);
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
- LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+ LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
if (ty->isAtomicType() ||
(!isInit && isLValueSuitableForInlineAtomic(atomicLValue))) {
emitAtomicStore(RValue::get(value), atomicLValue, isInit);
@@ -357,14 +365,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
}
assert(currSrcLoc && "must pass in source location");
- builder.createStore(*currSrcLoc, value, addr, isVolatile);
+ cir::StoreOp store = builder.createStore(*currSrcLoc, value, addr, isVolatile);
+ cgm.decorateOperationWithTBAA(store, tbaaInfo);
if (isNontemporal) {
cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
return;
}
-
- assert(!cir::MissingFeatures::opTBAA());
}
// TODO: Replace this with a proper TargetInfo function call.
@@ -426,6 +433,8 @@ Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
LValue CIRGenFunction::emitLValueForBitField(LValue base,
const FieldDecl *field) {
LValueBaseInfo baseInfo = base.getBaseInfo();
+ TBAAAccessInfo tbaaInfo{};
+
const CIRGenRecordLayout &layout =
cgm.getTypes().getCIRGenRecordLayout(field->getParent());
const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
@@ -444,7 +453,7 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base,
// TODO(cir): Support TBAA for bit fields.
assert(!cir::MissingFeatures::opTBAA());
LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
- return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
+ return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo, tbaaInfo);
}
LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
@@ -457,7 +466,10 @@ LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
const RecordDecl *rec = field->getParent();
AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();
LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));
- assert(!cir::MissingFeatures::opTBAA());
+ TBAAAccessInfo fieldTbaaInfo{};
+
+ // TODO(cir): Initialize tbaa info
+ assert(!MissingFeatures::opTBAA());
Address addr = base.getAddress();
if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
@@ -489,11 +501,11 @@ LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
// If this is a reference field, load the reference right now.
if (fieldType->isReferenceType()) {
assert(!cir::MissingFeatures::opTBAA());
- LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo);
+ LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo, fieldTbaaInfo);
if (recordCVR & Qualifiers::Volatile)
refLVal.getQuals().addVolatile();
addr = emitLoadOfReference(refLVal, getLoc(field->getSourceRange()),
- &fieldBaseInfo);
+ &fieldBaseInfo, &fieldTbaaInfo);
// Qualifiers on the struct don't apply to the referencee.
recordCVR = 0;
@@ -561,13 +573,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,
}
emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), lvalue.getBaseInfo(), isInit,
+ lvalue.getType(), lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
/*isNontemporal=*/false);
}
mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
QualType ty, SourceLocation loc,
- LValueBaseInfo baseInfo) {
+ LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo) {
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
mlir::Type eltTy = addr.getElementType();
@@ -586,8 +598,7 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
"emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
}
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
- LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+ LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
if (ty->isAtomicType() || isLValueSuitableForInlineAtomic(atomicLValue))
cgm.errorNYI("emitLoadOfScalar: load atomic");
@@ -596,19 +607,21 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck());
- mlir::Value loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
+ cir::LoadOp loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
+ cgm.decorateOperationWithTBAA(loadOp, tbaaInfo);
+
if (!ty->isBooleanType() && ty->hasBooleanRepresentation())
cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");
+
return loadOp;
}
mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
SourceLocation loc) {
assert(!cir::MissingFeatures::opLoadStoreNontemporal());
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), loc, lvalue.getBaseInfo());
+ lvalue.getType(), loc, lvalue.getBaseInfo(), lvalue.getTBAAInfo());
}
/// Given an expression that represents a value lvalue, this
@@ -2285,17 +2298,19 @@ RValue CIRGenFunction::emitReferenceBindingToExpr(const Expr *e) {
}
Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
- LValueBaseInfo *pointeeBaseInfo) {
+ LValueBaseInfo *pointeeBaseInfo, TBAAAccessInfo *pointeeTbaaInfo) {
if (refLVal.isVolatile())
cgm.errorNYI(loc, "load of volatile reference");
+ QualType pointeeType = refLVal.getType()->getPointeeType();
cir::LoadOp load =
cir::LoadOp::create(builder, loc, refLVal.getAddress().getElementType(),
refLVal.getAddress().getPointer());
- assert(!cir::MissingFeatures::opTBAA());
+ cgm.decorateOperationWithTBAA(load, refLVal.getTBAAInfo());
+ if (pointeeTbaaInfo)
+ *pointeeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
- QualType pointeeType = refLVal.getType()->getPointeeType();
CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
return Address(load, convertTypeForMem(pointeeType), align);
}
@@ -2306,10 +2321,10 @@ LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,
AlignmentSource source) {
LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
LValueBaseInfo pointeeBaseInfo;
- assert(!cir::MissingFeatures::opTBAA());
- Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
+ TBAAAccessInfo tbaaAccessInfo;
+ Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo, &tbaaAccessInfo);
return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
- pointeeBaseInfo);
+ pointeeBaseInfo, tbaaAccessInfo);
}
void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 872fc8d14ad95..b466b68b8f0ae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -983,7 +983,13 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
[[maybe_unused]] cir::CopyOp copyOp =
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), isVolatile);
- assert(!cir::MissingFeatures::opTBAA());
+ assert(!cir::MissingFeatures::opTBAAStruct());
+
+ if (cgm.getCodeGenOpts().NewStructPathTBAA) {
+ TBAAAccessInfo tbaaInfo = cgm.mergeTBAAInfoForMemoryTransfer(
+ dest.getTBAAInfo(), src.getTBAAInfo());
+ cgm.decorateOperationWithTBAA(copyOp, tbaaInfo);
+ }
}
// TODO(cir): This could be shared with classic codegen.
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 33bdfa315a9ea..c38bf6d90c915 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -14,6 +14,7 @@
#include "CIRGenCXXABI.h"
#include "CIRGenCall.h"
+#include "CIRGenTBAA.h"
#include "CIRGenValue.h"
#include "mlir/IR/Location.h"
#include "clang/AST/ExprCXX.h"
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index a3a7b4a207a81..53512163...
[truncated]
|
|
@llvm/pr-subscribers-clangir Author: Hendrik Hübner (HendrikHuebner) ChangesThis PR implements the basic handling for emitting TBAA attributes during lowering. TODO: Tests Patch is 46.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/169226.diff 19 Files Affected:
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index be9965ae3101f..371f046c25ba0 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
bool isVolatile = false, uint64_t alignment = 0) {
mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
- alignmentAttr, cir::MemOrderAttr{});
+ alignmentAttr, cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
}
mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -321,14 +321,14 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
/// Create a copy with inferred length.
cir::CopyOp createCopy(mlir::Value dst, mlir::Value src,
bool isVolatile = false) {
- return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile);
+ return cir::CopyOp::create(*this, dst.getLoc(), dst, src, isVolatile, /*tbaa=*/mlir::ArrayAttr{});
}
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
bool isVolatile = false,
mlir::IntegerAttr align = {},
cir::MemOrderAttr order = {}) {
- return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order);
+ return cir::StoreOp::create(*this, loc, val, dst, isVolatile, align, order, /*tbaa=*/mlir::ArrayAttr{});
}
[[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
@@ -353,7 +353,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
/*isVolatile=*/false, alignmentAttr,
- /*mem_order=*/{});
+ /*mem_order=*/{}, /*tbaa=*/mlir::ArrayAttr{});
}
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 12bc9cf7b5b04..5dbfe9334c867 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -447,6 +447,14 @@ def CIR_ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
}];
}
+//===----------------------------------------------------------------------===//
+// TBAAAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_TBAAAttr : CIR_Attr<"TBAA", "tbaa", []> {
+ let summary = "CIR dialect TBAA base attribute";
+}
+
//===----------------------------------------------------------------------===//
// GlobalViewAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a19c4f951fff9..40710783c97c0 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -586,7 +586,10 @@ def CIR_LoadOp : CIR_Op<"load", [
UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr<I64Attr>:$alignment,
- OptionalAttr<CIR_MemOrder>:$mem_order);
+ OptionalAttr<CIR_MemOrder>:$mem_order,
+ OptionalAttr<ArrayAttr>:$tbaa
+ );
+
let results = (outs CIR_AnyType:$result);
let assemblyFormat = [{
@@ -595,6 +598,7 @@ def CIR_LoadOp : CIR_Op<"load", [
(`align` `(` $alignment^ `)`)?
(`atomic` `(` $mem_order^ `)`)?
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
+ (`tbaa` `(` $tbaa^ `)`)?
}];
// FIXME: add verifier.
@@ -638,13 +642,16 @@ def CIR_StoreOp : CIR_Op<"store", [
[MemWrite]>:$addr,
UnitAttr:$is_volatile,
OptionalAttr<I64Attr>:$alignment,
- OptionalAttr<CIR_MemOrder>:$mem_order);
+ OptionalAttr<CIR_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^ `)`)?
}];
// FIXME: add verifier.
@@ -2979,12 +2986,16 @@ def CIR_CopyOp : CIR_Op<"copy",[
let arguments = (ins
Arg<CIR_PointerType, "", [MemWrite]>:$dst,
Arg<CIR_PointerType, "", [MemRead]>:$src,
- UnitAttr:$is_volatile
+ UnitAttr:$is_volatile,
+ OptionalAttr<ArrayAttr>:$tbaa
);
- let assemblyFormat = [{$src `to` $dst (`volatile` $is_volatile^)?
- attr-dict `:` qualified(type($dst))
+ let assemblyFormat = [{
+ $src `to` $dst (`volatile` $is_volatile^)?
+ attr-dict `:` qualified(type($dst))
+ (`tbaa` `(` $tbaa^ `)`)?
}];
+
let hasVerifier = 1;
let extraClassDeclaration = [{
@@ -2994,7 +3005,7 @@ def CIR_CopyOp : CIR_Op<"copy",[
/// Returns the number of bytes to be copied.
unsigned getLength(const mlir::DataLayout &dt) {
return dt.getTypeSize(getType().getPointee());
- }
+ }
}];
}
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index c99fd6f0bfcc4..defcb5dd600d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -302,6 +302,7 @@ struct MissingFeatures {
static bool openCL() { return false; }
static bool openMP() { return false; }
static bool opTBAA() { return false; }
+ static bool opTBAAStruct() { return false; }
static bool peepholeProtection() { return false; }
static bool pgoUse() { return false; }
static bool pointerAuthentication() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 48c082d89de18..aea832051b355 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -1011,7 +1011,7 @@ void CIRGenFunction::emitAtomicStore(RValue rvalue, LValue dest,
if (isVolatile)
store.setIsVolatile(true);
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
+ cgm.decorateOperationWithTBAA(store, dest.getTBAAInfo());
return;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 85b38120169fd..98cabf899bfa7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -462,7 +462,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
mlir::IntegerAttr align = getAlignmentAttr(addr.getAlignment());
return cir::LoadOp::create(*this, loc, addr.getPointer(), /*isDeref=*/false,
isVolatile, /*alignment=*/align,
- /*mem_order=*/cir::MemOrderAttr{});
+ /*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
}
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
@@ -473,7 +473,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
mlir::IntegerAttr alignAttr = getAlignmentAttr(alignment);
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,
/*isVolatile=*/false, alignAttr,
- /*mem_order=*/cir::MemOrderAttr{});
+ /*mem_order=*/cir::MemOrderAttr{}, /*tbaa=*/mlir::ArrayAttr{});
}
cir::LoadOp
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 0f10347944fae..b775317a6a0c0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -429,7 +429,15 @@ void CIRGenFunction::initializeVTablePointer(mlir::Location loc,
builder, loc, builder.getPtrToVPtrType(), classAddr.getPointer());
Address vtableField = Address(vtablePtr, classAddr.getAlignment());
builder.createStore(loc, vtableAddressPoint, vtableField);
- assert(!cir::MissingFeatures::opTBAA());
+
+ cir::StoreOp 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());
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 70497258eb64a..dd1143c9301b1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -14,6 +14,7 @@
#include "CIRGenConstantEmitter.h"
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
+#include "CIRGenTBAA.h"
#include "CIRGenValue.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Value.h"
@@ -69,7 +70,8 @@ Address CIRGenFunction::emitAddrOfFieldStorage(Address base,
/// Given an expression of pointer type, try to
/// derive a more accurate bound on the alignment of the pointer.
Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
- LValueBaseInfo *baseInfo) {
+ LValueBaseInfo *baseInfo,
+ TBAAAccessInfo *tbaaInfo) {
// We allow this with ObjC object pointers because of fragile ABIs.
assert(expr->getType()->isPointerType() ||
expr->getType()->isObjCObjectPointerType());
@@ -98,12 +100,18 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
*baseInfo = innerBaseInfo;
if (isa<ExplicitCastExpr>(ce)) {
- LValueBaseInfo targetTypeBaseInfo;
-
const QualType pointeeType = expr->getType()->getPointeeType();
+
+ LValueBaseInfo targetTypeBaseInfo;
const CharUnits align =
cgm.getNaturalTypeAlignment(pointeeType, &targetTypeBaseInfo);
+ if (tbaaInfo) {
+ TBAAAccessInfo targetTypeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
+ *tbaaInfo =
+ cgm.mergeTBAAInfoForCast(*tbaaInfo, targetTypeTbaaInfo);
+ }
+
// If the source l-value is opaque, honor the alignment of the
// casted-to type.
if (innerBaseInfo.getAlignmentSource() != AlignmentSource::Decl) {
@@ -315,7 +323,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
bool isVolatile, QualType ty,
- LValueBaseInfo baseInfo, bool isInit,
+ LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo,
+ bool isInit,
bool isNontemporal) {
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
@@ -338,8 +347,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
value = emitToMemory(value, ty);
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
- LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+ LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
if (ty->isAtomicType() ||
(!isInit && isLValueSuitableForInlineAtomic(atomicLValue))) {
emitAtomicStore(RValue::get(value), atomicLValue, isInit);
@@ -357,14 +365,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
}
assert(currSrcLoc && "must pass in source location");
- builder.createStore(*currSrcLoc, value, addr, isVolatile);
+ cir::StoreOp store = builder.createStore(*currSrcLoc, value, addr, isVolatile);
+ cgm.decorateOperationWithTBAA(store, tbaaInfo);
if (isNontemporal) {
cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
return;
}
-
- assert(!cir::MissingFeatures::opTBAA());
}
// TODO: Replace this with a proper TargetInfo function call.
@@ -426,6 +433,8 @@ Address CIRGenFunction::getAddrOfBitFieldStorage(LValue base,
LValue CIRGenFunction::emitLValueForBitField(LValue base,
const FieldDecl *field) {
LValueBaseInfo baseInfo = base.getBaseInfo();
+ TBAAAccessInfo tbaaInfo{};
+
const CIRGenRecordLayout &layout =
cgm.getTypes().getCIRGenRecordLayout(field->getParent());
const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field);
@@ -444,7 +453,7 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base,
// TODO(cir): Support TBAA for bit fields.
assert(!cir::MissingFeatures::opTBAA());
LValueBaseInfo fieldBaseInfo(baseInfo.getAlignmentSource());
- return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo);
+ return LValue::makeBitfield(addr, info, fieldType, fieldBaseInfo, tbaaInfo);
}
LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
@@ -457,7 +466,10 @@ LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
const RecordDecl *rec = field->getParent();
AlignmentSource baseAlignSource = baseInfo.getAlignmentSource();
LValueBaseInfo fieldBaseInfo(getFieldAlignmentSource(baseAlignSource));
- assert(!cir::MissingFeatures::opTBAA());
+ TBAAAccessInfo fieldTbaaInfo{};
+
+ // TODO(cir): Initialize tbaa info
+ assert(!MissingFeatures::opTBAA());
Address addr = base.getAddress();
if (auto *classDecl = dyn_cast<CXXRecordDecl>(rec)) {
@@ -489,11 +501,11 @@ LValue CIRGenFunction::emitLValueForField(LValue base, const FieldDecl *field) {
// If this is a reference field, load the reference right now.
if (fieldType->isReferenceType()) {
assert(!cir::MissingFeatures::opTBAA());
- LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo);
+ LValue refLVal = makeAddrLValue(addr, fieldType, fieldBaseInfo, fieldTbaaInfo);
if (recordCVR & Qualifiers::Volatile)
refLVal.getQuals().addVolatile();
addr = emitLoadOfReference(refLVal, getLoc(field->getSourceRange()),
- &fieldBaseInfo);
+ &fieldBaseInfo, &fieldTbaaInfo);
// Qualifiers on the struct don't apply to the referencee.
recordCVR = 0;
@@ -561,13 +573,13 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, LValue lvalue,
}
emitStoreOfScalar(value, lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), lvalue.getBaseInfo(), isInit,
+ lvalue.getType(), lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
/*isNontemporal=*/false);
}
mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
QualType ty, SourceLocation loc,
- LValueBaseInfo baseInfo) {
+ LValueBaseInfo baseInfo, TBAAAccessInfo tbaaInfo) {
assert(!cir::MissingFeatures::opLoadStoreThreadLocal());
mlir::Type eltTy = addr.getElementType();
@@ -586,8 +598,7 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
"emitLoadOfScalar Vec3 & PreserveVec3Type disabled");
}
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
- LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo);
+ LValue atomicLValue = LValue::makeAddr(addr, ty, baseInfo, tbaaInfo);
if (ty->isAtomicType() || isLValueSuitableForInlineAtomic(atomicLValue))
cgm.errorNYI("emitLoadOfScalar: load atomic");
@@ -596,19 +607,21 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck());
- mlir::Value loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
+ cir::LoadOp loadOp = builder.createLoad(getLoc(loc), addr, isVolatile);
+ cgm.decorateOperationWithTBAA(loadOp, tbaaInfo);
+
if (!ty->isBooleanType() && ty->hasBooleanRepresentation())
cgm.errorNYI("emitLoadOfScalar: boolean type with boolean representation");
+
return loadOp;
}
mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
SourceLocation loc) {
assert(!cir::MissingFeatures::opLoadStoreNontemporal());
- assert(!cir::MissingFeatures::opLoadStoreTbaa());
return emitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
- lvalue.getType(), loc, lvalue.getBaseInfo());
+ lvalue.getType(), loc, lvalue.getBaseInfo(), lvalue.getTBAAInfo());
}
/// Given an expression that represents a value lvalue, this
@@ -2285,17 +2298,19 @@ RValue CIRGenFunction::emitReferenceBindingToExpr(const Expr *e) {
}
Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
- LValueBaseInfo *pointeeBaseInfo) {
+ LValueBaseInfo *pointeeBaseInfo, TBAAAccessInfo *pointeeTbaaInfo) {
if (refLVal.isVolatile())
cgm.errorNYI(loc, "load of volatile reference");
+ QualType pointeeType = refLVal.getType()->getPointeeType();
cir::LoadOp load =
cir::LoadOp::create(builder, loc, refLVal.getAddress().getElementType(),
refLVal.getAddress().getPointer());
- assert(!cir::MissingFeatures::opTBAA());
+ cgm.decorateOperationWithTBAA(load, refLVal.getTBAAInfo());
+ if (pointeeTbaaInfo)
+ *pointeeTbaaInfo = cgm.getTBAAAccessInfo(pointeeType);
- QualType pointeeType = refLVal.getType()->getPointeeType();
CharUnits align = cgm.getNaturalTypeAlignment(pointeeType, pointeeBaseInfo);
return Address(load, convertTypeForMem(pointeeType), align);
}
@@ -2306,10 +2321,10 @@ LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr,
AlignmentSource source) {
LValue refLVal = makeAddrLValue(refAddr, refTy, LValueBaseInfo(source));
LValueBaseInfo pointeeBaseInfo;
- assert(!cir::MissingFeatures::opTBAA());
- Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo);
+ TBAAAccessInfo tbaaAccessInfo;
+ Address pointeeAddr = emitLoadOfReference(refLVal, loc, &pointeeBaseInfo, &tbaaAccessInfo);
return makeAddrLValue(pointeeAddr, refLVal.getType()->getPointeeType(),
- pointeeBaseInfo);
+ pointeeBaseInfo, tbaaAccessInfo);
}
void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 872fc8d14ad95..b466b68b8f0ae 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -983,7 +983,13 @@ void CIRGenFunction::emitAggregateCopy(LValue dest, LValue src, QualType ty,
[[maybe_unused]] cir::CopyOp copyOp =
builder.createCopy(destPtr.getPointer(), srcPtr.getPointer(), isVolatile);
- assert(!cir::MissingFeatures::opTBAA());
+ assert(!cir::MissingFeatures::opTBAAStruct());
+
+ if (cgm.getCodeGenOpts().NewStructPathTBAA) {
+ TBAAAccessInfo tbaaInfo = cgm.mergeTBAAInfoForMemoryTransfer(
+ dest.getTBAAInfo(), src.getTBAAInfo());
+ cgm.decorateOperationWithTBAA(copyOp, tbaaInfo);
+ }
}
// TODO(cir): This could be shared with classic codegen.
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 33bdfa315a9ea..c38bf6d90c915 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -14,6 +14,7 @@
#include "CIRGenCXXABI.h"
#include "CIRGenCall.h"
+#include "CIRGenTBAA.h"
#include "CIRGenValue.h"
#include "mlir/IR/Location.h"
#include "clang/AST/ExprCXX.h"
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index a3a7b4a207a81..53512163...
[truncated]
|
|
|
||
| /// FIXME: this could likely be a common helper and not necessarily related | ||
| /// with codegen. | ||
| clang::CharUnits getNaturalTypeAlignment(clang::QualType t, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In classic codegen this function actually takes a TBAAAccessInfo* too, and assigns it to the TBAA information obtained from the QualType. However, I omitted this here since the function does not have anything to do with TBAA. It seems like this was only added to avoid duplicating two lines of code at some of the call sites.
This PR implements the basic handling for emitting TBAA attributes during lowering.
In this initial PR, tbaa metadata is simply emitted as a "tbaa" attribute for loads and stores. A basic test confirms this. Lowering to LLVM IR was not implemented.