Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ 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,
Expand Down Expand Up @@ -321,14 +322,16 @@ 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,
Expand All @@ -353,7 +356,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,
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down
23 changes: 17 additions & 6 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [{
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 = [{
Expand All @@ -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());
}
}
}];
}

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 @@ -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; }
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
6 changes: 4 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,8 @@ 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,
Expand All @@ -473,7 +474,8 @@ 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
Expand Down
11 changes: 10 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,16 @@ 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());
}

Expand Down
73 changes: 47 additions & 26 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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());

Expand All @@ -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);
Expand All @@ -357,14 +365,14 @@ 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.
Expand Down Expand Up @@ -426,6 +434,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);
Expand All @@ -444,7 +454,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) {
Expand All @@ -457,7 +467,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)) {
Expand Down Expand Up @@ -489,11 +502,12 @@ 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;
Expand Down Expand Up @@ -561,13 +575,15 @@ 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();

Expand All @@ -586,8 +602,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");

Expand All @@ -596,7 +611,9 @@ 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");

Expand All @@ -606,9 +623,9 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(Address addr, bool isVolatile,
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
Expand Down Expand Up @@ -2285,17 +2302,20 @@ 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);
}
Expand All @@ -2306,10 +2326,11 @@ 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) {
Expand Down
Loading