aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenAsm.cpp6
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuilder.cpp10
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp20
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXX.cpp2
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp4
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCall.cpp16
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenClass.cpp7
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExpr.cpp63
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp42
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp19
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp149
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.cpp30
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h3
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp166
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp8
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp12
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp45
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenStmt.cpp99
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp51
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp4
20 files changed, 492 insertions, 264 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenAsm.cpp b/clang/lib/CIR/CodeGen/CIRGenAsm.cpp
index 17dffb3..88a7e85 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAsm.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAsm.cpp
@@ -117,9 +117,9 @@ mlir::LogicalResult CIRGenFunction::emitAsmStmt(const AsmStmt &s) {
bool hasSideEffect = s.isVolatile() || s.getNumOutputs() == 0;
- cir::InlineAsmOp ia = builder.create<cir::InlineAsmOp>(
- getLoc(s.getAsmLoc()), resultType, operands, asmString, constraints,
- hasSideEffect, inferFlavor(cgm, s), mlir::ArrayAttr());
+ cir::InlineAsmOp ia = cir::InlineAsmOp::create(
+ builder, getLoc(s.getAsmLoc()), resultType, operands, asmString,
+ constraints, hasSideEffect, inferFlavor(cgm, s), mlir::ArrayAttr());
if (isGCCAsmGoto) {
assert(!cir::MissingFeatures::asmGoto());
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
index 670a431..75355ee 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.cpp
@@ -22,8 +22,8 @@ mlir::Value CIRGenBuilderTy::maybeBuildArrayDecay(mlir::Location loc,
if (arrayTy) {
const cir::PointerType flatPtrTy = getPointerTo(arrayTy.getElementType());
- return create<cir::CastOp>(loc, flatPtrTy, cir::CastKind::array_to_ptrdecay,
- arrayPtr);
+ return cir::CastOp::create(*this, loc, flatPtrTy,
+ cir::CastKind::array_to_ptrdecay, arrayPtr);
}
assert(arrayPtrTy.getPointee() == eltTy &&
@@ -40,7 +40,7 @@ mlir::Value CIRGenBuilderTy::getArrayElement(mlir::Location arrayLocBegin,
if (shouldDecay)
basePtr = maybeBuildArrayDecay(arrayLocBegin, arrayPtr, eltTy);
const mlir::Type flatPtrTy = basePtr.getType();
- return create<cir::PtrStrideOp>(arrayLocEnd, flatPtrTy, basePtr, idx);
+ return cir::PtrStrideOp::create(*this, arrayLocEnd, flatPtrTy, basePtr, idx);
}
cir::ConstantOp CIRGenBuilderTy::getConstInt(mlir::Location loc,
@@ -60,14 +60,14 @@ cir::ConstantOp CIRGenBuilderTy::getConstInt(mlir::Location loc,
cir::ConstantOp CIRGenBuilderTy::getConstInt(mlir::Location loc, mlir::Type t,
uint64_t c) {
assert(mlir::isa<cir::IntType>(t) && "expected cir::IntType");
- return create<cir::ConstantOp>(loc, cir::IntAttr::get(t, c));
+ return cir::ConstantOp::create(*this, loc, cir::IntAttr::get(t, c));
}
cir::ConstantOp
clang::CIRGen::CIRGenBuilderTy::getConstFP(mlir::Location loc, mlir::Type t,
llvm::APFloat fpVal) {
assert(mlir::isa<cir::FPTypeInterface>(t) && "expected floating point type");
- return create<cir::ConstantOp>(loc, cir::FPAttr::get(t, fpVal));
+ return cir::ConstantOp::create(*this, loc, cir::FPAttr::get(t, fpVal));
}
void CIRGenBuilderTy::computeGlobalViewIndicesFromFlatOffset(
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 798e9d9..27c4d11 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -46,9 +46,9 @@ static RValue emitBuiltinBitOp(CIRGenFunction &cgf, const CallExpr *e,
Op op;
if constexpr (std::is_same_v<Op, cir::BitClzOp> ||
std::is_same_v<Op, cir::BitCtzOp>)
- op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg, poisonZero);
+ op = Op::create(builder, cgf.getLoc(e->getSourceRange()), arg, poisonZero);
else
- op = builder.create<Op>(cgf.getLoc(e->getSourceRange()), arg);
+ op = Op::create(builder, cgf.getLoc(e->getSourceRange()), arg);
mlir::Value result = op.getResult();
mlir::Type exprTy = cgf.convertType(e->getType());
@@ -67,8 +67,8 @@ RValue CIRGenFunction::emitRotate(const CallExpr *e, bool isRotateLeft) {
// to the type of input when necessary.
assert(!cir::MissingFeatures::msvcBuiltins());
- auto r = builder.create<cir::RotateOp>(getLoc(e->getSourceRange()), input,
- amount, isRotateLeft);
+ auto r = cir::RotateOp::create(builder, getLoc(e->getSourceRange()), input,
+ amount, isRotateLeft);
return RValue::get(r);
}
@@ -227,14 +227,14 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(nullptr);
mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
- builder.create<cir::AssumeOp>(loc, argValue);
+ cir::AssumeOp::create(builder, loc, argValue);
return RValue::get(nullptr);
}
case Builtin::BI__builtin_assume_separate_storage: {
mlir::Value value0 = emitScalarExpr(e->getArg(0));
mlir::Value value1 = emitScalarExpr(e->getArg(1));
- builder.create<cir::AssumeSepStorageOp>(loc, value0, value1);
+ cir::AssumeSepStorageOp::create(builder, loc, value0, value1);
return RValue::get(nullptr);
}
@@ -363,8 +363,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
probability);
}
- auto result = builder.create<cir::ExpectOp>(
- loc, argValue.getType(), argValue, expectedValue, probAttr);
+ auto result = cir::ExpectOp::create(builder, loc, argValue.getType(),
+ argValue, expectedValue, probAttr);
return RValue::get(result);
}
@@ -375,7 +375,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI_byteswap_ulong:
case Builtin::BI_byteswap_uint64: {
mlir::Value arg = emitScalarExpr(e->getArg(0));
- return RValue::get(builder.create<cir::ByteSwapOp>(loc, arg));
+ return RValue::get(cir::ByteSwapOp::create(builder, loc, arg));
}
case Builtin::BI__builtin_bitreverse8:
@@ -383,7 +383,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
case Builtin::BI__builtin_bitreverse32:
case Builtin::BI__builtin_bitreverse64: {
mlir::Value arg = emitScalarExpr(e->getArg(0));
- return RValue::get(builder.create<cir::BitReverseOp>(loc, arg));
+ return RValue::get(cir::BitReverseOp::create(builder, loc, arg));
}
case Builtin::BI__builtin_rotateleft8:
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp
index 171ce1c..ca421e5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp
@@ -151,7 +151,7 @@ static void emitDeclDestroy(CIRGenFunction &cgf, const VarDecl *vd,
// Don't confuse lexical cleanup.
builder.clearInsertionPoint();
} else {
- builder.create<cir::YieldOp>(addr.getLoc());
+ cir::YieldOp::create(builder, addr.getLoc());
}
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
index eef3739..aa0182e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
@@ -70,8 +70,8 @@ cir::GlobalLinkageKind CIRGenCXXABI::getCXXDestructorLinkage(
mlir::Value CIRGenCXXABI::loadIncomingCXXThis(CIRGenFunction &cgf) {
ImplicitParamDecl *vd = getThisDecl(cgf);
Address addr = cgf.getAddrOfLocalVar(vd);
- return cgf.getBuilder().create<cir::LoadOp>(
- cgf.getLoc(vd->getLocation()), addr.getElementType(), addr.getPointer());
+ return cir::LoadOp::create(cgf.getBuilder(), cgf.getLoc(vd->getLocation()),
+ addr.getElementType(), addr.getPointer());
}
void CIRGenCXXABI::setCXXABIThisValue(CIRGenFunction &cgf,
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 61072f0..88aef89 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -690,6 +690,22 @@ void CallArg::copyInto(CIRGenFunction &cgf, Address addr,
isUsed = true;
}
+mlir::Value CIRGenFunction::emitRuntimeCall(mlir::Location loc,
+ cir::FuncOp callee,
+ ArrayRef<mlir::Value> args) {
+ // TODO(cir): set the calling convention to this runtime call.
+ assert(!cir::MissingFeatures::opFuncCallingConv());
+
+ cir::CallOp call = builder.createCallOp(loc, callee, args);
+ assert(call->getNumResults() <= 1 &&
+ "runtime functions have at most 1 result");
+
+ if (call->getNumResults() == 0)
+ return nullptr;
+
+ return call->getResult(0);
+}
+
void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
clang::QualType argType) {
assert(argType->isReferenceType() == e->isGLValue() &&
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
index 89f4926..5046e09 100644
--- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp
@@ -725,8 +725,9 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
// Emit the constructor call that will execute for every array element.
mlir::Value arrayOp =
builder.createPtrBitcast(arrayBase.getPointer(), arrayTy);
- builder.create<cir::ArrayCtor>(
- *currSrcLoc, arrayOp, [&](mlir::OpBuilder &b, mlir::Location loc) {
+ cir::ArrayCtor::create(
+ builder, *currSrcLoc, arrayOp,
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
mlir::BlockArgument arg =
b.getInsertionBlock()->addArgument(ptrToElmType, loc);
Address curAddr = Address(arg, elementType, eltAlignment);
@@ -738,7 +739,7 @@ void CIRGenFunction::emitCXXAggrConstructorCall(
emitCXXConstructorCall(ctor, Ctor_Complete,
/*ForVirtualBase=*/false,
/*Delegating=*/false, currAVS, e);
- builder.create<cir::YieldOp>(loc);
+ cir::YieldOp::create(builder, loc);
});
}
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 52021fc..9df88ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -251,8 +251,8 @@ void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst,
const mlir::Location loc = dst.getVectorPointer().getLoc();
const mlir::Value vector =
builder.createLoad(loc, dst.getVectorAddress());
- const mlir::Value newVector = builder.create<cir::VecInsertOp>(
- loc, vector, src.getValue(), dst.getVectorIdx());
+ const mlir::Value newVector = cir::VecInsertOp::create(
+ builder, loc, vector, src.getValue(), dst.getVectorIdx());
builder.createStore(loc, newVector, dst.getVectorAddress());
return;
}
@@ -615,8 +615,8 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
if (lv.isVectorElt()) {
const mlir::Value load =
builder.createLoad(getLoc(loc), lv.getVectorAddress());
- return RValue::get(builder.create<cir::VecExtractOp>(getLoc(loc), load,
- lv.getVectorIdx()));
+ return RValue::get(cir::VecExtractOp::create(builder, getLoc(loc), load,
+ lv.getVectorIdx()));
}
cgm.errorNYI(loc, "emitLoadOfLValue");
@@ -671,8 +671,8 @@ static LValue emitFunctionDeclLValue(CIRGenFunction &cgf, const Expr *e,
mlir::Type fnTy = funcOp.getFunctionType();
mlir::Type ptrTy = cir::PointerType::get(fnTy);
- mlir::Value addr = cgf.getBuilder().create<cir::GetGlobalOp>(
- loc, ptrTy, funcOp.getSymName());
+ mlir::Value addr = cir::GetGlobalOp::create(cgf.getBuilder(), loc, ptrTy,
+ funcOp.getSymName());
if (funcOp.getFunctionType() != cgf.convertType(fd->getType())) {
fnTy = cgf.convertType(fd->getType());
@@ -1685,8 +1685,8 @@ CIRGenCallee CIRGenFunction::emitDirectCallee(const GlobalDecl &gd) {
mlir::OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToStart(cgm.getModule().getBody());
- clone = builder.create<cir::FuncOp>(calleeFunc.getLoc(), fdInlineName,
- calleeFunc.getFunctionType());
+ clone = cir::FuncOp::create(builder, calleeFunc.getLoc(), fdInlineName,
+ calleeFunc.getFunctionType());
clone.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
&cgm.getMLIRContext(), cir::GlobalLinkageKind::InternalLinkage));
clone.setSymVisibility("private");
@@ -1778,8 +1778,8 @@ RValue CIRGenFunction::emitCall(clang::QualType calleeTy,
mlir::Operation *fn = callee.getFunctionPointer();
mlir::Value addr;
if (auto funcOp = mlir::dyn_cast<cir::FuncOp>(fn)) {
- addr = builder.create<cir::GetGlobalOp>(
- getLoc(e->getSourceRange()),
+ addr = cir::GetGlobalOp::create(
+ builder, getLoc(e->getSourceRange()),
cir::PointerType::get(funcOp.getFunctionType()), funcOp.getSymName());
} else {
addr = fn->getResult(0);
@@ -1820,10 +1820,12 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
// Resolve direct calls.
const auto *funcDecl = cast<FunctionDecl>(declRef->getDecl());
return emitDirectCallee(funcDecl);
- } else if (isa<MemberExpr>(e)) {
- cgm.errorNYI(e->getSourceRange(),
- "emitCallee: call to member function is NYI");
- return {};
+ } else if (auto me = dyn_cast<MemberExpr>(e)) {
+ if (const auto *fd = dyn_cast<FunctionDecl>(me->getMemberDecl())) {
+ emitIgnoredExpr(me->getBase());
+ return emitDirectCallee(fd);
+ }
+ // Else fall through to the indirect reference handling below.
} else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
return CIRGenCallee::forPseudoDestructor(pde);
}
@@ -1996,9 +1998,9 @@ cir::IfOp CIRGenFunction::emitIfOnBoolExpr(
// Emit the code with the fully general case.
mlir::Value condV = emitOpOnBoolExpr(loc, cond);
- return builder.create<cir::IfOp>(loc, condV, elseLoc.has_value(),
- /*thenBuilder=*/thenBuilder,
- /*elseBuilder=*/elseBuilder);
+ return cir::IfOp::create(builder, loc, condV, elseLoc.has_value(),
+ /*thenBuilder=*/thenBuilder,
+ /*elseBuilder=*/elseBuilder);
}
/// TODO(cir): see EmitBranchOnBoolExpr for extra ideas).
@@ -2020,18 +2022,17 @@ mlir::Value CIRGenFunction::emitOpOnBoolExpr(mlir::Location loc,
mlir::Value condV = emitOpOnBoolExpr(loc, condOp->getCond());
mlir::Value ternaryOpRes =
- builder
- .create<cir::TernaryOp>(
- loc, condV, /*thenBuilder=*/
- [this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
- mlir::Value lhs = emitScalarExpr(trueExpr);
- b.create<cir::YieldOp>(loc, lhs);
- },
- /*elseBuilder=*/
- [this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
- mlir::Value rhs = emitScalarExpr(falseExpr);
- b.create<cir::YieldOp>(loc, rhs);
- })
+ cir::TernaryOp::create(
+ builder, loc, condV, /*thenBuilder=*/
+ [this, trueExpr](mlir::OpBuilder &b, mlir::Location loc) {
+ mlir::Value lhs = emitScalarExpr(trueExpr);
+ cir::YieldOp::create(b, loc, lhs);
+ },
+ /*elseBuilder=*/
+ [this, falseExpr](mlir::OpBuilder &b, mlir::Location loc) {
+ mlir::Value rhs = emitScalarExpr(falseExpr);
+ cir::YieldOp::create(b, loc, rhs);
+ })
.getResult();
return emitScalarConversion(ternaryOpRes, condOp->getType(),
@@ -2211,8 +2212,8 @@ Address CIRGenFunction::emitLoadOfReference(LValue refLVal, mlir::Location loc,
cgm.errorNYI(loc, "load of volatile reference");
cir::LoadOp load =
- builder.create<cir::LoadOp>(loc, refLVal.getAddress().getElementType(),
- refLVal.getAddress().getPointer());
+ cir::LoadOp::create(builder, loc, refLVal.getAddress().getElementType(),
+ refLVal.getAddress().getPointer());
assert(!cir::MissingFeatures::opTBAA());
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index d8f4943..047f359 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -390,7 +390,7 @@ ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
}
auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
- return builder.create<cir::ConstantOp>(loc, complexAttr);
+ return cir::ConstantOp::create(builder, loc, complexAttr);
}
mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
@@ -601,7 +601,7 @@ mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {
if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
mlir::isa<cir::ComplexType>(op.rhs.getType()))
- return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs);
+ return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs);
if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
@@ -623,7 +623,7 @@ mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {
if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
mlir::isa<cir::ComplexType>(op.rhs.getType()))
- return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs);
+ return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs);
if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
@@ -664,7 +664,8 @@ mlir::Value ComplexExprEmitter::emitBinMul(const BinOpInfo &op) {
mlir::isa<cir::ComplexType>(op.rhs.getType())) {
cir::ComplexRangeKind rangeKind =
getComplexRangeAttr(op.fpFeatures.getComplexRange());
- return builder.create<cir::ComplexMulOp>(op.loc, op.lhs, op.rhs, rangeKind);
+ return cir::ComplexMulOp::create(builder, op.loc, op.lhs, op.rhs,
+ rangeKind);
}
if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
@@ -968,23 +969,22 @@ mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
Expr *cond = e->getCond()->IgnoreParens();
mlir::Value condValue = cgf.evaluateExprAsBool(cond);
- return builder
- .create<cir::TernaryOp>(
- loc, condValue,
- /*thenBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- eval.beginEvaluation();
- mlir::Value trueValue = Visit(e->getTrueExpr());
- b.create<cir::YieldOp>(loc, trueValue);
- eval.endEvaluation();
- },
- /*elseBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- eval.beginEvaluation();
- mlir::Value falseValue = Visit(e->getFalseExpr());
- b.create<cir::YieldOp>(loc, falseValue);
- eval.endEvaluation();
- })
+ return cir::TernaryOp::create(
+ builder, loc, condValue,
+ /*thenBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ eval.beginEvaluation();
+ mlir::Value trueValue = Visit(e->getTrueExpr());
+ cir::YieldOp::create(b, loc, trueValue);
+ eval.endEvaluation();
+ },
+ /*elseBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ eval.beginEvaluation();
+ mlir::Value falseValue = Visit(e->getFalseExpr());
+ cir::YieldOp::create(b, loc, falseValue);
+ eval.endEvaluation();
+ })
.getResult();
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 800262a..8f05014 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -179,8 +179,23 @@ bool ConstantAggregateBuilder::add(mlir::TypedAttr typedAttr, CharUnits offset,
}
// Uncommon case: constant overlaps what we've already created.
- cgm.errorNYI("overlapping constants");
- return false;
+ std::optional<size_t> firstElemToReplace = splitAt(offset);
+ if (!firstElemToReplace)
+ return false;
+
+ CharUnits cSize = getSize(typedAttr);
+ std::optional<size_t> lastElemToReplace = splitAt(offset + cSize);
+ if (!lastElemToReplace)
+ return false;
+
+ assert((firstElemToReplace == lastElemToReplace || allowOverwrite) &&
+ "unexpectedly overwriting field");
+
+ Element newElt(typedAttr, offset);
+ replace(elements, *firstElemToReplace, *lastElemToReplace, {newElt});
+ size = std::max(size, offset + cSize);
+ naturalLayout = false;
+ return true;
}
bool ConstantAggregateBuilder::addBits(llvm::APInt bits, uint64_t offsetInBits,
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 33eb748..db6878d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -164,22 +164,22 @@ public:
mlir::Value VisitIntegerLiteral(const IntegerLiteral *e) {
mlir::Type type = cgf.convertType(e->getType());
- return builder.create<cir::ConstantOp>(
- cgf.getLoc(e->getExprLoc()), cir::IntAttr::get(type, e->getValue()));
+ return cir::ConstantOp::create(builder, cgf.getLoc(e->getExprLoc()),
+ cir::IntAttr::get(type, e->getValue()));
}
mlir::Value VisitFloatingLiteral(const FloatingLiteral *e) {
mlir::Type type = cgf.convertType(e->getType());
assert(mlir::isa<cir::FPTypeInterface>(type) &&
"expect floating-point type");
- return builder.create<cir::ConstantOp>(
- cgf.getLoc(e->getExprLoc()), cir::FPAttr::get(type, e->getValue()));
+ return cir::ConstantOp::create(builder, cgf.getLoc(e->getExprLoc()),
+ cir::FPAttr::get(type, e->getValue()));
}
mlir::Value VisitCharacterLiteral(const CharacterLiteral *e) {
mlir::Type ty = cgf.convertType(e->getType());
auto init = cir::IntAttr::get(ty, e->getValue());
- return builder.create<cir::ConstantOp>(cgf.getLoc(e->getExprLoc()), init);
+ return cir::ConstantOp::create(builder, cgf.getLoc(e->getExprLoc()), init);
}
mlir::Value VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *e) {
@@ -227,7 +227,7 @@ public:
const mlir::Location loc = cgf.getLoc(e->getSourceRange());
const mlir::Value vecValue = Visit(e->getBase());
const mlir::Value indexValue = Visit(e->getIdx());
- return cgf.builder.create<cir::VecExtractOp>(loc, vecValue, indexValue);
+ return cir::VecExtractOp::create(cgf.builder, loc, vecValue, indexValue);
}
// Just load the lvalue formed by the subscript expression.
return emitLoadOfLValue(e);
@@ -238,8 +238,8 @@ public:
// The undocumented form of __builtin_shufflevector.
mlir::Value inputVec = Visit(e->getExpr(0));
mlir::Value indexVec = Visit(e->getExpr(1));
- return cgf.builder.create<cir::VecShuffleDynamicOp>(
- cgf.getLoc(e->getSourceRange()), inputVec, indexVec);
+ return cir::VecShuffleDynamicOp::create(
+ cgf.builder, cgf.getLoc(e->getSourceRange()), inputVec, indexVec);
}
mlir::Value vec1 = Visit(e->getExpr(0));
@@ -257,9 +257,10 @@ public:
.getSExtValue()));
}
- return cgf.builder.create<cir::VecShuffleOp>(
- cgf.getLoc(e->getSourceRange()), cgf.convertType(e->getType()), vec1,
- vec2, cgf.builder.getArrayAttr(indices));
+ return cir::VecShuffleOp::create(cgf.builder,
+ cgf.getLoc(e->getSourceRange()),
+ cgf.convertType(e->getType()), vec1, vec2,
+ cgf.builder.getArrayAttr(indices));
}
mlir::Value VisitConvertVectorExpr(ConvertVectorExpr *e) {
@@ -296,8 +297,8 @@ public:
mlir::Value emitFloatToBoolConversion(mlir::Value src, mlir::Location loc) {
cir::BoolType boolTy = builder.getBoolTy();
- return builder.create<cir::CastOp>(loc, boolTy,
- cir::CastKind::float_to_bool, src);
+ return cir::CastOp::create(builder, loc, boolTy,
+ cir::CastKind::float_to_bool, src);
}
mlir::Value emitIntToBoolConversion(mlir::Value srcVal, mlir::Location loc) {
@@ -307,8 +308,8 @@ public:
// TODO: optimize this common case here or leave it for later
// CIR passes?
cir::BoolType boolTy = builder.getBoolTy();
- return builder.create<cir::CastOp>(loc, boolTy, cir::CastKind::int_to_bool,
- srcVal);
+ return cir::CastOp::create(builder, loc, boolTy, cir::CastKind::int_to_bool,
+ srcVal);
}
/// Convert the specified expression value to a boolean (!cir.bool) truth
@@ -411,7 +412,8 @@ public:
}
assert(castKind.has_value() && "Internal error: CastKind not set.");
- return builder.create<cir::CastOp>(src.getLoc(), fullDstTy, *castKind, src);
+ return cir::CastOp::create(builder, src.getLoc(), fullDstTy, *castKind,
+ src);
}
mlir::Value
@@ -658,9 +660,9 @@ public:
mlir::Value emitUnaryOp(const UnaryOperator *e, cir::UnaryOpKind kind,
mlir::Value input, bool nsw = false) {
- return builder.create<cir::UnaryOp>(
- cgf.getLoc(e->getSourceRange().getBegin()), input.getType(), kind,
- input, nsw);
+ return cir::UnaryOp::create(builder,
+ cgf.getLoc(e->getSourceRange().getBegin()),
+ input.getType(), kind, input, nsw);
}
mlir::Value VisitUnaryNot(const UnaryOperator *e) {
@@ -967,9 +969,9 @@ public:
} else {
// Other kinds of vectors. Element-wise comparison returning
// a vector.
- result = builder.create<cir::VecCmpOp>(
- cgf.getLoc(boInfo.loc), cgf.convertType(boInfo.fullType), kind,
- boInfo.lhs, boInfo.rhs);
+ result = cir::VecCmpOp::create(builder, cgf.getLoc(boInfo.loc),
+ cgf.convertType(boInfo.fullType), kind,
+ boInfo.lhs, boInfo.rhs);
}
} else if (boInfo.isFixedPointOp()) {
assert(!cir::MissingFeatures::fixedPointType());
@@ -991,7 +993,7 @@ public:
assert(e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE);
BinOpInfo boInfo = emitBinOps(e);
- result = builder.create<cir::CmpOp>(loc, kind, boInfo.lhs, boInfo.rhs);
+ result = cir::CmpOp::create(builder, loc, kind, boInfo.lhs, boInfo.rhs);
}
return emitScalarConversion(result, cgf.getContext().BoolTy, e->getType(),
@@ -1093,8 +1095,8 @@ public:
CIRGenFunction::ConditionalEvaluation eval(cgf);
mlir::Value lhsCondV = cgf.evaluateExprAsBool(e->getLHS());
- auto resOp = builder.create<cir::TernaryOp>(
- loc, lhsCondV, /*trueBuilder=*/
+ auto resOp = cir::TernaryOp::create(
+ builder, loc, lhsCondV, /*trueBuilder=*/
[&](mlir::OpBuilder &b, mlir::Location loc) {
CIRGenFunction::LexicalScope lexScope{cgf, loc,
b.getInsertionBlock()};
@@ -1139,8 +1141,8 @@ public:
CIRGenFunction::ConditionalEvaluation eval(cgf);
mlir::Value lhsCondV = cgf.evaluateExprAsBool(e->getLHS());
- auto resOp = builder.create<cir::TernaryOp>(
- loc, lhsCondV, /*trueBuilder=*/
+ auto resOp = cir::TernaryOp::create(
+ builder, loc, lhsCondV, /*trueBuilder=*/
[&](mlir::OpBuilder &b, mlir::Location loc) {
CIRGenFunction::LexicalScope lexScope{cgf, loc,
b.getInsertionBlock()};
@@ -1566,8 +1568,9 @@ static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf,
}
assert(!cir::MissingFeatures::sanitizers());
- return cgf.getBuilder().create<cir::PtrStrideOp>(
- cgf.getLoc(op.e->getExprLoc()), pointer.getType(), pointer, index);
+ return cir::PtrStrideOp::create(cgf.getBuilder(),
+ cgf.getLoc(op.e->getExprLoc()),
+ pointer.getType(), pointer, index);
}
mlir::Value ScalarExprEmitter::emitMul(const BinOpInfo &ops) {
@@ -1609,19 +1612,19 @@ mlir::Value ScalarExprEmitter::emitMul(const BinOpInfo &ops) {
return nullptr;
}
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::Mul, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType), cir::BinOpKind::Mul,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitDiv(const BinOpInfo &ops) {
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::Div, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType), cir::BinOpKind::Div,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitRem(const BinOpInfo &ops) {
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::Rem, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType), cir::BinOpKind::Rem,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitAdd(const BinOpInfo &ops) {
@@ -1668,8 +1671,8 @@ mlir::Value ScalarExprEmitter::emitAdd(const BinOpInfo &ops) {
return {};
}
- return builder.create<cir::BinOp>(loc, cgf.convertType(ops.fullType),
- cir::BinOpKind::Add, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, loc, cgf.convertType(ops.fullType),
+ cir::BinOpKind::Add, ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) {
@@ -1716,9 +1719,9 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) {
return {};
}
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::Sub, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType),
+ cir::BinOpKind::Sub, ops.lhs, ops.rhs);
}
// If the RHS is not a pointer, then we have normal pointer
@@ -1796,19 +1799,19 @@ mlir::Value ScalarExprEmitter::emitShr(const BinOpInfo &ops) {
}
mlir::Value ScalarExprEmitter::emitAnd(const BinOpInfo &ops) {
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::And, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType), cir::BinOpKind::And,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitXor(const BinOpInfo &ops) {
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::Xor, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType), cir::BinOpKind::Xor,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitOr(const BinOpInfo &ops) {
- return builder.create<cir::BinOp>(cgf.getLoc(ops.loc),
- cgf.convertType(ops.fullType),
- cir::BinOpKind::Or, ops.lhs, ops.rhs);
+ return cir::BinOp::create(builder, cgf.getLoc(ops.loc),
+ cgf.convertType(ops.fullType), cir::BinOpKind::Or,
+ ops.lhs, ops.rhs);
}
// Emit code for an explicit or implicit cast. Implicit
@@ -2011,9 +2014,9 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
case CK_VectorSplat: {
// Create a vector object and fill all elements with the same scalar value.
assert(destTy->isVectorType() && "CK_VectorSplat to non-vector type");
- return builder.create<cir::VecSplatOp>(
- cgf.getLoc(subExpr->getSourceRange()), cgf.convertType(destTy),
- Visit(subExpr));
+ return cir::VecSplatOp::create(builder,
+ cgf.getLoc(subExpr->getSourceRange()),
+ cgf.convertType(destTy), Visit(subExpr));
}
case CK_FunctionToPointerDecay:
return cgf.emitLValue(subExpr).getPointer();
@@ -2073,8 +2076,9 @@ mlir::Value ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) {
vectorType.getSize() - numInitElements, zeroValue);
}
- return cgf.getBuilder().create<cir::VecCreateOp>(
- cgf.getLoc(e->getSourceRange()), vectorType, elements);
+ return cir::VecCreateOp::create(cgf.getBuilder(),
+ cgf.getLoc(e->getSourceRange()), vectorType,
+ elements);
}
// C++11 value-initialization for the scalar.
@@ -2310,8 +2314,8 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
mlir::Value condValue = Visit(condExpr);
mlir::Value lhsValue = Visit(lhsExpr);
mlir::Value rhsValue = Visit(rhsExpr);
- return builder.create<cir::VecTernaryOp>(loc, condValue, lhsValue,
- rhsValue);
+ return cir::VecTernaryOp::create(builder, loc, condValue, lhsValue,
+ rhsValue);
}
// If this is a really simple expression (like x ? 4 : 5), emit this as a
@@ -2354,7 +2358,7 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
if (branch) {
yieldTy = branch.getType();
- b.create<cir::YieldOp>(loc, branch);
+ cir::YieldOp::create(b, loc, branch);
} else {
// If LHS or RHS is a throw or void expression we need to patch
// arms as to properly match yield types.
@@ -2362,17 +2366,16 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
}
};
- mlir::Value result = builder
- .create<cir::TernaryOp>(
- loc, condV,
- /*trueBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- emitBranch(b, loc, lhsExpr);
- },
- /*falseBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- emitBranch(b, loc, rhsExpr);
- })
+ mlir::Value result = cir::TernaryOp::create(
+ builder, loc, condV,
+ /*trueBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ emitBranch(b, loc, lhsExpr);
+ },
+ /*falseBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ emitBranch(b, loc, rhsExpr);
+ })
.getResult();
if (!insertPoints.empty()) {
@@ -2387,10 +2390,10 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
// Block does not return: build empty yield.
if (mlir::isa<cir::VoidType>(yieldTy)) {
- builder.create<cir::YieldOp>(loc);
+ cir::YieldOp::create(builder, loc);
} else { // Block returns: set null yield value.
mlir::Value op0 = builder.getNullValue(yieldTy, loc);
- builder.create<cir::YieldOp>(loc, op0);
+ cir::YieldOp::create(builder, loc, op0);
}
}
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index d3c0d9f..58feb36 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -264,11 +264,11 @@ void CIRGenFunction::LexicalScope::cleanup() {
// If we now have one after `applyCleanup`, hook it up properly.
if (!cleanupBlock && localScope->getCleanupBlock(builder)) {
cleanupBlock = localScope->getCleanupBlock(builder);
- builder.create<cir::BrOp>(insPt->back().getLoc(), cleanupBlock);
+ cir::BrOp::create(builder, insPt->back().getLoc(), cleanupBlock);
if (!cleanupBlock->mightHaveTerminator()) {
mlir::OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToEnd(cleanupBlock);
- builder.create<cir::YieldOp>(localScope->endLoc);
+ cir::YieldOp::create(builder, localScope->endLoc);
}
}
@@ -286,7 +286,7 @@ void CIRGenFunction::LexicalScope::cleanup() {
}
}
- builder.create<cir::BrOp>(*returnLoc, returnBlock);
+ cir::BrOp::create(builder, *returnLoc, returnBlock);
return;
}
}
@@ -298,8 +298,8 @@ void CIRGenFunction::LexicalScope::cleanup() {
// Ternary ops have to deal with matching arms for yielding types
// and do return a value, it must do its own cir.yield insertion.
if (!localScope->isTernary() && !insPt->mightHaveTerminator()) {
- !retVal ? builder.create<cir::YieldOp>(localScope->endLoc)
- : builder.create<cir::YieldOp>(localScope->endLoc, retVal);
+ !retVal ? cir::YieldOp::create(builder, localScope->endLoc)
+ : cir::YieldOp::create(builder, localScope->endLoc, retVal);
}
};
@@ -331,7 +331,7 @@ void CIRGenFunction::LexicalScope::cleanup() {
// If there's a cleanup block, branch to it, nothing else to do.
if (cleanupBlock) {
- builder.create<cir::BrOp>(curBlock->back().getLoc(), cleanupBlock);
+ cir::BrOp::create(builder, curBlock->back().getLoc(), cleanupBlock);
return;
}
@@ -349,12 +349,12 @@ cir::ReturnOp CIRGenFunction::LexicalScope::emitReturn(mlir::Location loc) {
assert(fn && "emitReturn from non-function");
if (!fn.getFunctionType().hasVoidReturn()) {
// Load the value from `__retval` and return it via the `cir.return` op.
- auto value = builder.create<cir::LoadOp>(
- loc, fn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
- return builder.create<cir::ReturnOp>(loc,
- llvm::ArrayRef(value.getResult()));
+ auto value = cir::LoadOp::create(
+ builder, loc, fn.getFunctionType().getReturnType(), *cgf.fnRetAlloca);
+ return cir::ReturnOp::create(builder, loc,
+ llvm::ArrayRef(value.getResult()));
}
- return builder.create<cir::ReturnOp>(loc);
+ return cir::ReturnOp::create(builder, loc);
}
// This is copied from CodeGenModule::MayDropFunctionReturn. This is a
@@ -389,9 +389,9 @@ void CIRGenFunction::LexicalScope::emitImplicitReturn() {
if (shouldEmitUnreachable) {
assert(!cir::MissingFeatures::sanitizers());
if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0)
- builder.create<cir::TrapOp>(localScope->endLoc);
+ cir::TrapOp::create(builder, localScope->endLoc);
else
- builder.create<cir::UnreachableOp>(localScope->endLoc);
+ cir::UnreachableOp::create(builder, localScope->endLoc);
builder.clearInsertionPoint();
return;
}
@@ -561,8 +561,8 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
if (!clone) {
mlir::OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPoint(fn);
- clone = builder.create<cir::FuncOp>(fn.getLoc(), fdInlineName,
- fn.getFunctionType());
+ clone = cir::FuncOp::create(builder, fn.getLoc(), fdInlineName,
+ fn.getFunctionType());
clone.setLinkage(cir::GlobalLinkageKind::InternalLinkage);
clone.setSymVisibility("private");
clone.setInlineKind(cir::InlineKind::AlwaysInline);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index e3b9b6a..5f9dbdc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1461,6 +1461,9 @@ public:
void emitReturnOfRValue(mlir::Location loc, RValue rv, QualType ty);
+ mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee,
+ llvm::ArrayRef<mlir::Value> args = {});
+
/// Emit the computation of the specified expression of scalar type.
mlir::Value emitScalarExpr(const clang::Expr *e);
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index e620310..f7c4d18 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -1809,8 +1809,8 @@ CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
mlir::OpBuilder &builder = cgm.getBuilder();
auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
- return builder.create<cir::VTableAddrPointOp>(
- cgm.getLoc(vtableClass->getSourceRange()), vtablePtrTy,
+ return cir::VTableAddrPointOp::create(
+ builder, cgm.getLoc(vtableClass->getSourceRange()), vtablePtrTy,
mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
cir::AddressPointAttr::get(cgm.getBuilder().getContext(),
addressPoint.VTableIndex,
@@ -1874,6 +1874,15 @@ static cir::FuncOp getBadCastFn(CIRGenFunction &cgf) {
return cgf.cgm.createRuntimeFunction(fnTy, "__cxa_bad_cast");
}
+static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc) {
+ // TODO(cir): set the calling convention to the runtime function.
+ assert(!cir::MissingFeatures::opFuncCallingConv());
+
+ cgf.emitRuntimeCall(loc, getBadCastFn(cgf));
+ cir::UnreachableOp::create(cgf.getBuilder(), loc);
+ cgf.getBuilder().clearInsertionPoint();
+}
+
// TODO(cir): This could be shared with classic codegen.
static CharUnits computeOffsetHint(ASTContext &astContext,
const CXXRecordDecl *src,
@@ -1959,6 +1968,136 @@ static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc,
return Address{ptr, src.getAlignment()};
}
+static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi,
+ CIRGenFunction &cgf, mlir::Location loc,
+ QualType srcRecordTy,
+ QualType destRecordTy,
+ cir::PointerType destCIRTy,
+ bool isRefCast, Address src) {
+ // Find all the inheritance paths from SrcRecordTy to DestRecordTy.
+ const CXXRecordDecl *srcDecl = srcRecordTy->getAsCXXRecordDecl();
+ const CXXRecordDecl *destDecl = destRecordTy->getAsCXXRecordDecl();
+ CXXBasePaths paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+ /*DetectVirtual=*/false);
+ (void)destDecl->isDerivedFrom(srcDecl, paths);
+
+ // Find an offset within `destDecl` where a `srcDecl` instance and its vptr
+ // might appear.
+ std::optional<CharUnits> offset;
+ for (const CXXBasePath &path : paths) {
+ // dynamic_cast only finds public inheritance paths.
+ if (path.Access != AS_public)
+ continue;
+
+ CharUnits pathOffset;
+ for (const CXXBasePathElement &pathElement : path) {
+ // Find the offset along this inheritance step.
+ const CXXRecordDecl *base =
+ pathElement.Base->getType()->getAsCXXRecordDecl();
+ if (pathElement.Base->isVirtual()) {
+ // For a virtual base class, we know that the derived class is exactly
+ // destDecl, so we can use the vbase offset from its layout.
+ const ASTRecordLayout &layout =
+ cgf.getContext().getASTRecordLayout(destDecl);
+ pathOffset = layout.getVBaseClassOffset(base);
+ } else {
+ const ASTRecordLayout &layout =
+ cgf.getContext().getASTRecordLayout(pathElement.Class);
+ pathOffset += layout.getBaseClassOffset(base);
+ }
+ }
+
+ if (!offset) {
+ offset = pathOffset;
+ } else if (offset != pathOffset) {
+ // base appears in at least two different places. Find the most-derived
+ // object and see if it's a DestDecl. Note that the most-derived object
+ // must be at least as aligned as this base class subobject, and must
+ // have a vptr at offset 0.
+ src = emitDynamicCastToVoid(cgf, loc, srcRecordTy, src);
+ srcDecl = destDecl;
+ offset = CharUnits::Zero();
+ break;
+ }
+ }
+
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+
+ if (!offset) {
+ // If there are no public inheritance paths, the cast always fails.
+ mlir::Value nullPtrValue = builder.getNullPtr(destCIRTy, loc);
+ if (isRefCast) {
+ mlir::Region *currentRegion = builder.getBlock()->getParent();
+ emitCallToBadCast(cgf, loc);
+
+ // The call to bad_cast will terminate the block. Create a new block to
+ // hold any follow up code.
+ builder.createBlock(currentRegion, currentRegion->end());
+ }
+
+ return nullPtrValue;
+ }
+
+ // Compare the vptr against the expected vptr for the destination type at
+ // this offset. Note that we do not know what type src points to in the case
+ // where the derived class multiply inherits from the base class so we can't
+ // use getVTablePtr, so we load the vptr directly instead.
+
+ mlir::Value expectedVPtr =
+ abi.getVTableAddressPoint(BaseSubobject(srcDecl, *offset), destDecl);
+
+ // TODO(cir): handle address space here.
+ assert(!cir::MissingFeatures::addressSpace());
+ mlir::Type vptrTy = expectedVPtr.getType();
+ mlir::Type vptrPtrTy = builder.getPointerTo(vptrTy);
+ Address srcVPtrPtr(builder.createBitcast(src.getPointer(), vptrPtrTy),
+ src.getAlignment());
+ mlir::Value srcVPtr = builder.createLoad(loc, srcVPtrPtr);
+
+ // TODO(cir): decorate SrcVPtr with TBAA info.
+ assert(!cir::MissingFeatures::opTBAA());
+
+ mlir::Value success =
+ builder.createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
+
+ auto emitCastResult = [&] {
+ if (offset->isZero())
+ return builder.createBitcast(src.getPointer(), destCIRTy);
+
+ // TODO(cir): handle address space here.
+ assert(!cir::MissingFeatures::addressSpace());
+ mlir::Type u8PtrTy = builder.getUInt8PtrTy();
+
+ mlir::Value strideToApply =
+ builder.getConstInt(loc, builder.getUInt64Ty(), -offset->getQuantity());
+ mlir::Value srcU8Ptr = builder.createBitcast(src.getPointer(), u8PtrTy);
+ mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
+ srcU8Ptr, strideToApply);
+ return builder.createBitcast(resultU8Ptr, destCIRTy);
+ };
+
+ if (isRefCast) {
+ mlir::Value failed = builder.createNot(success);
+ cir::IfOp::create(builder, loc, failed, /*withElseRegion=*/false,
+ [&](mlir::OpBuilder &, mlir::Location) {
+ emitCallToBadCast(cgf, loc);
+ });
+ return emitCastResult();
+ }
+
+ return cir::TernaryOp::create(
+ builder, loc, success,
+ [&](mlir::OpBuilder &, mlir::Location) {
+ auto result = emitCastResult();
+ builder.createYield(loc, result);
+ },
+ [&](mlir::OpBuilder &, mlir::Location) {
+ mlir::Value nullPtrValue = builder.getNullPtr(destCIRTy, loc);
+ builder.createYield(loc, nullPtrValue);
+ })
+ .getResult();
+}
+
static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf,
mlir::Location loc,
QualType srcRecordTy,
@@ -2000,8 +2139,27 @@ mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
// if the dynamic type of the pointer is exactly the destination type.
if (destRecordTy->getAsCXXRecordDecl()->isEffectivelyFinal() &&
cgf.cgm.getCodeGenOpts().OptimizationLevel > 0) {
- cgm.errorNYI(loc, "emitExactDynamicCast");
- return {};
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+ // If this isn't a reference cast, check the pointer to see if it's null.
+ if (!isRefCast) {
+ mlir::Value srcPtrIsNull = builder.createPtrIsNull(src.getPointer());
+ return cir::TernaryOp::create(
+ builder, loc, srcPtrIsNull,
+ [&](mlir::OpBuilder, mlir::Location) {
+ builder.createYield(
+ loc, builder.getNullPtr(destCIRTy, loc).getResult());
+ },
+ [&](mlir::OpBuilder &, mlir::Location) {
+ mlir::Value exactCast = emitExactDynamicCast(
+ *this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
+ isRefCast, src);
+ builder.createYield(loc, exactCast);
+ })
+ .getResult();
+ }
+
+ return emitExactDynamicCast(*this, cgf, loc, srcRecordTy, destRecordTy,
+ destCIRTy, isRefCast, src);
}
cir::DynamicCastInfoAttr castInfo =
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 6b29373..46adfe2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -535,7 +535,7 @@ cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &cgm,
builder.setInsertionPointToStart(cgm.getModule().getBody());
}
- g = builder.create<cir::GlobalOp>(loc, name, t, isConstant);
+ g = cir::GlobalOp::create(builder, loc, name, t, isConstant);
if (!insertPoint)
cgm.lastGlobalOp = g;
@@ -739,8 +739,8 @@ mlir::Value CIRGenModule::getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty,
cir::GlobalOp g = getOrCreateCIRGlobal(d, ty, isForDefinition);
mlir::Type ptrTy = builder.getPointerTo(g.getSymType());
- return builder.create<cir::GetGlobalOp>(getLoc(d->getSourceRange()), ptrTy,
- g.getSymName());
+ return cir::GetGlobalOp::create(builder, getLoc(d->getSourceRange()), ptrTy,
+ g.getSymName());
}
cir::GlobalViewAttr CIRGenModule::getAddrOfGlobalVarAttr(const VarDecl *d) {
@@ -2176,7 +2176,7 @@ CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name,
if (cgf)
builder.setInsertionPoint(cgf->curFn);
- func = builder.create<cir::FuncOp>(loc, name, funcType);
+ func = cir::FuncOp::create(builder, loc, name, funcType);
assert(!cir::MissingFeatures::opFuncAstDeclAttr());
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
index 5ba6bcb..e7bf3bc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp
@@ -27,8 +27,8 @@ mlir::Value createBound(CIRGenFunction &cgf, CIRGen::CIRGenBuilderTy &builder,
// Stride is always 1 in C/C++.
mlir::Value stride = cgf.createOpenACCConstantInt(boundLoc, 64, 1);
- auto bound =
- builder.create<mlir::acc::DataBoundsOp>(boundLoc, lowerBound, upperBound);
+ auto bound = mlir::acc::DataBoundsOp::create(builder, boundLoc, lowerBound,
+ upperBound);
bound.getStartIdxMutable().assign(startIdx);
if (extent)
bound.getExtentMutable().assign(extent);
@@ -48,8 +48,8 @@ mlir::Value CIRGenFunction::emitOpenACCIntExpr(const Expr *intExpr) {
? mlir::IntegerType::SignednessSemantics::Signed
: mlir::IntegerType::SignednessSemantics::Unsigned);
- auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
- exprLoc, targetType, expr);
+ auto conversionOp = mlir::UnrealizedConversionCastOp::create(
+ builder, exprLoc, targetType, expr);
return conversionOp.getResult(0);
}
@@ -59,8 +59,8 @@ mlir::Value CIRGenFunction::createOpenACCConstantInt(mlir::Location loc,
mlir::IntegerType ty =
mlir::IntegerType::get(&getMLIRContext(), width,
mlir::IntegerType::SignednessSemantics::Signless);
- auto constOp = builder.create<mlir::arith::ConstantOp>(
- loc, builder.getIntegerAttr(ty, value));
+ auto constOp = mlir::arith::ConstantOp::create(
+ builder, loc, builder.getIntegerAttr(ty, value));
return constOp;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
index ce4ae7e..5010137 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
@@ -96,8 +96,8 @@ class OpenACCClauseCIREmitter final
mlir::IntegerType targetType = mlir::IntegerType::get(
&cgf.getMLIRContext(), /*width=*/1,
mlir::IntegerType::SignednessSemantics::Signless);
- auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
- exprLoc, targetType, condition);
+ auto conversionOp = mlir::UnrealizedConversionCastOp::create(
+ builder, exprLoc, targetType, condition);
return conversionOp.getResult(0);
}
@@ -107,8 +107,8 @@ class OpenACCClauseCIREmitter final
mlir::IntegerType ty = mlir::IntegerType::get(
&cgf.getMLIRContext(), width,
mlir::IntegerType::SignednessSemantics::Signless);
- auto constOp = builder.create<mlir::arith::ConstantOp>(
- loc, builder.getIntegerAttr(ty, value));
+ auto constOp = mlir::arith::ConstantOp::create(
+ builder, loc, builder.getIntegerAttr(ty, value));
return constOp;
}
@@ -217,8 +217,8 @@ class OpenACCClauseCIREmitter final
cgf.getOpenACCDataOperandInfo(varOperand);
auto beforeOp =
- builder.create<BeforeOpTy>(opInfo.beginLoc, opInfo.varValue, structured,
- implicit, opInfo.name, opInfo.bounds);
+ BeforeOpTy::create(builder, opInfo.beginLoc, opInfo.varValue,
+ structured, implicit, opInfo.name, opInfo.bounds);
operation.getDataClauseOperandsMutable().append(beforeOp.getResult());
AfterOpTy afterOp;
@@ -231,12 +231,12 @@ class OpenACCClauseCIREmitter final
// Detach/Delete ops don't have the variable reference here, so they
// take 1 fewer argument to their build function.
afterOp =
- builder.create<AfterOpTy>(opInfo.beginLoc, beforeOp, structured,
- implicit, opInfo.name, opInfo.bounds);
+ AfterOpTy::create(builder, opInfo.beginLoc, beforeOp, structured,
+ implicit, opInfo.name, opInfo.bounds);
} else {
- afterOp = builder.create<AfterOpTy>(
- opInfo.beginLoc, beforeOp, opInfo.varValue, structured, implicit,
- opInfo.name, opInfo.bounds);
+ afterOp = AfterOpTy::create(builder, opInfo.beginLoc, beforeOp,
+ opInfo.varValue, structured, implicit,
+ opInfo.name, opInfo.bounds);
}
}
@@ -258,8 +258,8 @@ class OpenACCClauseCIREmitter final
CIRGenFunction::OpenACCDataOperandInfo opInfo =
cgf.getOpenACCDataOperandInfo(varOperand);
auto beforeOp =
- builder.create<BeforeOpTy>(opInfo.beginLoc, opInfo.varValue, structured,
- implicit, opInfo.name, opInfo.bounds);
+ BeforeOpTy::create(builder, opInfo.beginLoc, opInfo.varValue,
+ structured, implicit, opInfo.name, opInfo.bounds);
operation.getDataClauseOperandsMutable().append(beforeOp.getResult());
// Set the 'rest' of the info for the operation.
@@ -553,12 +553,15 @@ public:
}
void VisitIfClause(const OpenACCIfClause &clause) {
- if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
- mlir::acc::KernelsOp, mlir::acc::InitOp,
- mlir::acc::ShutdownOp, mlir::acc::SetOp,
- mlir::acc::DataOp, mlir::acc::WaitOp,
- mlir::acc::HostDataOp, mlir::acc::EnterDataOp,
- mlir::acc::ExitDataOp, mlir::acc::UpdateOp>) {
+ if constexpr (isOneOfTypes<
+ OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
+ mlir::acc::KernelsOp, mlir::acc::InitOp,
+ mlir::acc::ShutdownOp, mlir::acc::SetOp,
+ mlir::acc::DataOp, mlir::acc::WaitOp,
+ mlir::acc::HostDataOp, mlir::acc::EnterDataOp,
+ mlir::acc::ExitDataOp, mlir::acc::UpdateOp,
+ mlir::acc::AtomicReadOp, mlir::acc::AtomicWriteOp,
+ mlir::acc::AtomicUpdateOp, mlir::acc::AtomicCaptureOp>) {
operation.getIfCondMutable().append(
createCondition(clause.getConditionExpr()));
} else if constexpr (isCombinedType<OpTy>) {
@@ -1144,6 +1147,10 @@ EXPL_SPEC(mlir::acc::HostDataOp)
EXPL_SPEC(mlir::acc::EnterDataOp)
EXPL_SPEC(mlir::acc::ExitDataOp)
EXPL_SPEC(mlir::acc::UpdateOp)
+EXPL_SPEC(mlir::acc::AtomicReadOp)
+EXPL_SPEC(mlir::acc::AtomicWriteOp)
+EXPL_SPEC(mlir::acc::AtomicCaptureOp)
+EXPL_SPEC(mlir::acc::AtomicUpdateOp)
#undef EXPL_SPEC
template <typename ComputeOp, typename LoopOp>
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index f486c46..1eb7199 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -91,8 +91,9 @@ mlir::LogicalResult CIRGenFunction::emitCompoundStmt(const CompoundStmt &s,
SymTableScopeTy varScope(symbolTable);
mlir::Location scopeLoc = getLoc(s.getSourceRange());
mlir::OpBuilder::InsertPoint scopeInsPt;
- builder.create<cir::ScopeOp>(
- scopeLoc, [&](mlir::OpBuilder &b, mlir::Type &type, mlir::Location loc) {
+ cir::ScopeOp::create(
+ builder, scopeLoc,
+ [&](mlir::OpBuilder &b, mlir::Type &type, mlir::Location loc) {
scopeInsPt = b.saveInsertionPoint();
});
mlir::OpBuilder::InsertionGuard guard(builder);
@@ -423,12 +424,12 @@ mlir::LogicalResult CIRGenFunction::emitIfStmt(const IfStmt &s) {
// LexicalScope ConditionScope(*this, S.getCond()->getSourceRange());
// The if scope contains the full source range for IfStmt.
mlir::Location scopeLoc = getLoc(s.getSourceRange());
- builder.create<cir::ScopeOp>(
- scopeLoc, /*scopeBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- LexicalScope lexScope{*this, scopeLoc, builder.getInsertionBlock()};
- res = ifStmtBuilder();
- });
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ LexicalScope lexScope{*this, scopeLoc,
+ builder.getInsertionBlock()};
+ res = ifStmtBuilder();
+ });
return res;
}
@@ -576,11 +577,11 @@ mlir::LogicalResult CIRGenFunction::emitLabel(const clang::LabelDecl &d) {
mlir::OpBuilder::InsertionGuard guard(builder);
labelBlock = builder.createBlock(builder.getBlock()->getParent());
}
- builder.create<cir::BrOp>(getLoc(d.getSourceRange()), labelBlock);
+ cir::BrOp::create(builder, getLoc(d.getSourceRange()), labelBlock);
}
builder.setInsertionPointToEnd(labelBlock);
- builder.create<cir::LabelOp>(getLoc(d.getSourceRange()), d.getName());
+ cir::LabelOp::create(builder, getLoc(d.getSourceRange()), d.getName());
builder.setInsertionPointToEnd(labelBlock);
// FIXME: emit debug info for labels, incrementProfileCounter
@@ -617,7 +618,7 @@ CIRGenFunction::emitCaseDefaultCascade(const T *stmt, mlir::Type condType,
const Stmt *sub = stmt->getSubStmt();
mlir::OpBuilder::InsertPoint insertPoint;
- builder.create<CaseOp>(loc, value, kind, insertPoint);
+ CaseOp::create(builder, loc, value, kind, insertPoint);
{
mlir::OpBuilder::InsertionGuard guardSwitch(builder);
@@ -789,16 +790,16 @@ CIRGenFunction::emitCXXForRangeStmt(const CXXForRangeStmt &s,
mlir::LogicalResult res = mlir::success();
mlir::Location scopeLoc = getLoc(s.getSourceRange());
- builder.create<cir::ScopeOp>(scopeLoc, /*scopeBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- // Create a cleanup scope for the condition
- // variable cleanups. Logical equivalent from
- // LLVM codegn for LexicalScope
- // ConditionScope(*this, S.getSourceRange())...
- LexicalScope lexScope{
- *this, loc, builder.getInsertionBlock()};
- res = forStmtBuilder();
- });
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ // Create a cleanup scope for the condition
+ // variable cleanups. Logical equivalent from
+ // LLVM codegn for LexicalScope
+ // ConditionScope(*this, S.getSourceRange())...
+ LexicalScope lexScope{*this, loc,
+ builder.getInsertionBlock()};
+ res = forStmtBuilder();
+ });
if (res.failed())
return res;
@@ -841,7 +842,7 @@ mlir::LogicalResult CIRGenFunction::emitForStmt(const ForStmt &s) {
// scalar type.
condVal = evaluateExprAsBool(s.getCond());
} else {
- condVal = b.create<cir::ConstantOp>(loc, builder.getTrueAttr());
+ condVal = cir::ConstantOp::create(b, loc, builder.getTrueAttr());
}
builder.createCondition(condVal);
},
@@ -865,12 +866,12 @@ mlir::LogicalResult CIRGenFunction::emitForStmt(const ForStmt &s) {
auto res = mlir::success();
auto scopeLoc = getLoc(s.getSourceRange());
- builder.create<cir::ScopeOp>(scopeLoc, /*scopeBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- LexicalScope lexScope{
- *this, loc, builder.getInsertionBlock()};
- res = forStmtBuilder();
- });
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ LexicalScope lexScope{*this, loc,
+ builder.getInsertionBlock()};
+ res = forStmtBuilder();
+ });
if (res.failed())
return res;
@@ -916,12 +917,12 @@ mlir::LogicalResult CIRGenFunction::emitDoStmt(const DoStmt &s) {
mlir::LogicalResult res = mlir::success();
mlir::Location scopeLoc = getLoc(s.getSourceRange());
- builder.create<cir::ScopeOp>(scopeLoc, /*scopeBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- LexicalScope lexScope{
- *this, loc, builder.getInsertionBlock()};
- res = doStmtBuilder();
- });
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ LexicalScope lexScope{*this, loc,
+ builder.getInsertionBlock()};
+ res = doStmtBuilder();
+ });
if (res.failed())
return res;
@@ -972,12 +973,12 @@ mlir::LogicalResult CIRGenFunction::emitWhileStmt(const WhileStmt &s) {
mlir::LogicalResult res = mlir::success();
mlir::Location scopeLoc = getLoc(s.getSourceRange());
- builder.create<cir::ScopeOp>(scopeLoc, /*scopeBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- LexicalScope lexScope{
- *this, loc, builder.getInsertionBlock()};
- res = whileStmtBuilder();
- });
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ LexicalScope lexScope{*this, loc,
+ builder.getInsertionBlock()};
+ res = whileStmtBuilder();
+ });
if (res.failed())
return res;
@@ -1048,8 +1049,8 @@ mlir::LogicalResult CIRGenFunction::emitSwitchStmt(const clang::SwitchStmt &s) {
assert(!cir::MissingFeatures::insertBuiltinUnpredictable());
mlir::LogicalResult res = mlir::success();
- swop = builder.create<SwitchOp>(
- getLoc(s.getBeginLoc()), condV,
+ swop = SwitchOp::create(
+ builder, getLoc(s.getBeginLoc()), condV,
/*switchBuilder=*/
[&](mlir::OpBuilder &b, mlir::Location loc, mlir::OperationState &os) {
curLexScope->setAsSwitch();
@@ -1067,12 +1068,12 @@ mlir::LogicalResult CIRGenFunction::emitSwitchStmt(const clang::SwitchStmt &s) {
// The switch scope contains the full source range for SwitchStmt.
mlir::Location scopeLoc = getLoc(s.getSourceRange());
mlir::LogicalResult res = mlir::success();
- builder.create<cir::ScopeOp>(scopeLoc, /*scopeBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- LexicalScope lexScope{
- *this, loc, builder.getInsertionBlock()};
- res = switchStmtBuilder();
- });
+ cir::ScopeOp::create(builder, scopeLoc, /*scopeBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ LexicalScope lexScope{*this, loc,
+ builder.getInsertionBlock()};
+ res = switchStmtBuilder();
+ });
llvm::SmallVector<CaseOp> cases;
swop.collectCases(cases);
@@ -1096,7 +1097,7 @@ void CIRGenFunction::emitReturnOfRValue(mlir::Location loc, RValue rv,
}
mlir::Block *retBlock = curLexScope->getOrCreateRetBlock(*this, loc);
assert(!cir::MissingFeatures::emitBranchThroughCleanup());
- builder.create<cir::BrOp>(loc, retBlock);
+ cir::BrOp::create(builder, loc, retBlock);
if (ehStack.stable_begin() != currentCleanupStackDepth)
cgm.errorNYI(loc, "return of r-value with cleanup stack");
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
index e89393c..77e6f83 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACC.cpp
@@ -30,7 +30,7 @@ mlir::LogicalResult CIRGenFunction::emitOpenACCOpAssociatedStmt(
llvm::SmallVector<mlir::Type> retTy;
llvm::SmallVector<mlir::Value> operands;
- auto op = builder.create<Op>(start, retTy, operands);
+ auto op = Op::create(builder, start, retTy, operands);
emitOpenACCClauses(op, dirKind, dirLoc, clauses);
@@ -42,7 +42,7 @@ mlir::LogicalResult CIRGenFunction::emitOpenACCOpAssociatedStmt(
LexicalScope ls{*this, start, builder.getInsertionBlock()};
res = emitStmt(associatedStmt, /*useCurrentScope=*/true);
- builder.create<TermOp>(end);
+ TermOp::create(builder, end);
}
return res;
}
@@ -73,7 +73,7 @@ mlir::LogicalResult CIRGenFunction::emitOpenACCOpCombinedConstruct(
llvm::SmallVector<mlir::Type> retTy;
llvm::SmallVector<mlir::Value> operands;
- auto computeOp = builder.create<Op>(start, retTy, operands);
+ auto computeOp = Op::create(builder, start, retTy, operands);
computeOp.setCombinedAttr(builder.getUnitAttr());
mlir::acc::LoopOp loopOp;
@@ -85,7 +85,7 @@ mlir::LogicalResult CIRGenFunction::emitOpenACCOpCombinedConstruct(
builder.setInsertionPointToEnd(&block);
LexicalScope ls{*this, start, builder.getInsertionBlock()};
- auto loopOp = builder.create<LoopOp>(start, retTy, operands);
+ auto loopOp = LoopOp::create(builder, start, retTy, operands);
loopOp.setCombinedAttr(mlir::acc::CombinedConstructsTypeAttr::get(
builder.getContext(), CombinedType<Op>::value));
@@ -99,14 +99,14 @@ mlir::LogicalResult CIRGenFunction::emitOpenACCOpCombinedConstruct(
res = emitStmt(loopStmt, /*useCurrentScope=*/true);
- builder.create<mlir::acc::YieldOp>(end);
+ mlir::acc::YieldOp::create(builder, end);
}
emitOpenACCClauses(computeOp, loopOp, dirKind, dirLoc, clauses);
updateLoopOpParallelism(loopOp, /*isOrphan=*/false, dirKind);
- builder.create<TermOp>(end);
+ TermOp::create(builder, end);
}
return res;
@@ -118,7 +118,7 @@ Op CIRGenFunction::emitOpenACCOp(
llvm::ArrayRef<const OpenACCClause *> clauses) {
llvm::SmallVector<mlir::Type> retTy;
llvm::SmallVector<mlir::Value> operands;
- auto op = builder.create<Op>(start, retTy, operands);
+ auto op = Op::create(builder, start, retTy, operands);
emitOpenACCClauses(op, dirKind, dirLoc, clauses);
return op;
@@ -197,8 +197,8 @@ CIRGenFunction::emitOpenACCWaitConstruct(const OpenACCWaitConstruct &s) {
? mlir::IntegerType::SignednessSemantics::Signed
: mlir::IntegerType::SignednessSemantics::Unsigned);
- auto conversionOp = builder.create<mlir::UnrealizedConversionCastOp>(
- exprLoc, targetType, expr);
+ auto conversionOp = mlir::UnrealizedConversionCastOp::create(
+ builder, exprLoc, targetType, expr);
return conversionOp.getResult(0);
};
@@ -294,9 +294,9 @@ CIRGenFunction::emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s) {
CIRGenFunction::OpenACCDataOperandInfo opInfo =
getOpenACCDataOperandInfo(var);
- auto cacheOp = builder.create<CacheOp>(
- opInfo.beginLoc, opInfo.varValue,
- /*structured=*/false, /*implicit=*/false, opInfo.name, opInfo.bounds);
+ auto cacheOp = CacheOp::create(builder, opInfo.beginLoc, opInfo.varValue,
+ /*structured=*/false, /*implicit=*/false,
+ opInfo.name, opInfo.bounds);
loopOp.getCacheOperandsMutable().append(cacheOp.getResult());
}
@@ -306,6 +306,29 @@ CIRGenFunction::emitOpenACCCacheConstruct(const OpenACCCacheConstruct &s) {
mlir::LogicalResult
CIRGenFunction::emitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &s) {
- cgm.errorNYI(s.getSourceRange(), "OpenACC Atomic Construct");
- return mlir::failure();
+ // For now, we are only support 'read', so diagnose. We can switch on the kind
+ // later once we start implementing the other 3 forms.
+ if (s.getAtomicKind() != OpenACCAtomicKind::Read) {
+ cgm.errorNYI(s.getSourceRange(), "OpenACC Atomic Construct");
+ return mlir::failure();
+ }
+
+ // While Atomic is an 'associated statement' construct, it 'steals' the
+ // expression it is associated with rather than emitting it inside of it. So
+ // it has custom emit logic.
+ mlir::Location start = getLoc(s.getSourceRange().getBegin());
+ OpenACCAtomicConstruct::StmtInfo inf = s.getAssociatedStmtInfo();
+ // Atomic 'read' only permits 'v = x', where v and x are both scalar L values.
+ // The getAssociatedStmtInfo strips off implicit casts, which includes
+ // implicit conversions and L-to-R-Value conversions, so we can just emit it
+ // as an L value. The Flang implementation has no problem with different
+ // types, so it appears that the dialect can handle the conversions.
+ mlir::Value v = emitLValue(inf.V).getPointer();
+ mlir::Value x = emitLValue(inf.X).getPointer();
+ mlir::Type resTy = convertType(inf.V->getType());
+ auto op = mlir::acc::AtomicReadOp::create(builder, start, x, v, resTy,
+ /*ifCond=*/{});
+ emitOpenACCClauses(op, s.getDirectiveKind(), s.getDirectiveLoc(),
+ s.clauses());
+ return mlir::success();
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp
index f3911ae..c5b89bd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmtOpenACCLoop.cpp
@@ -58,7 +58,7 @@ CIRGenFunction::emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s) {
mlir::Location end = getLoc(s.getSourceRange().getEnd());
llvm::SmallVector<mlir::Type> retTy;
llvm::SmallVector<mlir::Value> operands;
- auto op = builder.create<LoopOp>(start, retTy, operands);
+ auto op = LoopOp::create(builder, start, retTy, operands);
// TODO(OpenACC): In the future we are going to need to come up with a
// transformation here that can teach the acc.loop how to figure out the
@@ -133,7 +133,7 @@ CIRGenFunction::emitOpenACCLoopConstruct(const OpenACCLoopConstruct &s) {
ActiveOpenACCLoopRAII activeLoop{*this, &op};
stmtRes = emitStmt(s.getLoop(), /*useCurrentScope=*/true);
- builder.create<mlir::acc::YieldOp>(end);
+ mlir::acc::YieldOp::create(builder, end);
}
return stmtRes;