aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/Dialect
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/Dialect')
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRDialect.cpp64
-rw-r--r--clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp37
2 files changed, 74 insertions, 27 deletions
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 5f88590..7af3dc1 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -15,6 +15,7 @@
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "mlir/IR/DialectImplementation.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/FunctionImplementation.h"
#include "mlir/Support/LLVM.h"
@@ -1720,6 +1721,43 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
hasAlias = true;
}
+ auto parseGlobalDtorCtor =
+ [&](StringRef keyword,
+ llvm::function_ref<void(std::optional<int> prio)> createAttr)
+ -> mlir::LogicalResult {
+ if (mlir::succeeded(parser.parseOptionalKeyword(keyword))) {
+ std::optional<int> priority;
+ if (mlir::succeeded(parser.parseOptionalLParen())) {
+ auto parsedPriority = mlir::FieldParser<int>::parse(parser);
+ if (mlir::failed(parsedPriority))
+ return parser.emitError(parser.getCurrentLocation(),
+ "failed to parse 'priority', of type 'int'");
+ priority = parsedPriority.value_or(int());
+ // Parse literal ')'
+ if (parser.parseRParen())
+ return failure();
+ }
+ createAttr(priority);
+ }
+ return success();
+ };
+
+ if (parseGlobalDtorCtor("global_ctor", [&](std::optional<int> priority) {
+ mlir::IntegerAttr globalCtorPriorityAttr =
+ builder.getI32IntegerAttr(priority.value_or(65535));
+ state.addAttribute(getGlobalCtorPriorityAttrName(state.name),
+ globalCtorPriorityAttr);
+ }).failed())
+ return failure();
+
+ if (parseGlobalDtorCtor("global_dtor", [&](std::optional<int> priority) {
+ mlir::IntegerAttr globalDtorPriorityAttr =
+ builder.getI32IntegerAttr(priority.value_or(65535));
+ state.addAttribute(getGlobalDtorPriorityAttrName(state.name),
+ globalDtorPriorityAttr);
+ }).failed())
+ return failure();
+
// Parse the optional function body.
auto *body = state.addRegion();
OptionalParseResult parseResult = parser.parseOptionalRegion(
@@ -1801,6 +1839,18 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
p << ")";
}
+ if (auto globalCtorPriority = getGlobalCtorPriority()) {
+ p << " global_ctor";
+ if (globalCtorPriority.value() != 65535)
+ p << "(" << globalCtorPriority.value() << ")";
+ }
+
+ if (auto globalDtorPriority = getGlobalDtorPriority()) {
+ p << " global_dtor";
+ if (globalDtorPriority.value() != 65535)
+ p << "(" << globalDtorPriority.value() << ")";
+ }
+
// Print the body if this is not an external function.
Region &body = getOperation()->getRegion(0);
if (!body.empty()) {
@@ -2851,20 +2901,6 @@ mlir::LogicalResult cir::ThrowOp::verify() {
}
//===----------------------------------------------------------------------===//
-// AtomicCmpXchg
-//===----------------------------------------------------------------------===//
-
-LogicalResult cir::AtomicCmpXchg::verify() {
- mlir::Type pointeeType = getPtr().getType().getPointee();
-
- if (pointeeType != getExpected().getType() ||
- pointeeType != getDesired().getType())
- return emitOpError("ptr, expected and desired types must match");
-
- return success();
-}
-
-//===----------------------------------------------------------------------===//
// TypeInfoAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index dbff0b9..d99c362 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -105,6 +105,8 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
/// List of ctors and their priorities to be called before main()
llvm::SmallVector<std::pair<std::string, uint32_t>, 4> globalCtorList;
+ /// List of dtors and their priorities to be called when unloading module.
+ llvm::SmallVector<std::pair<std::string, uint32_t>, 4> globalDtorList;
void setASTContext(clang::ASTContext *c) {
astCtx = c;
@@ -823,10 +825,13 @@ void LoweringPreparePass::buildGlobalCtorDtorList() {
mlir::ArrayAttr::get(&getContext(), globalCtors));
}
- // We will eventual need to populate a global_dtor list, but that's not
- // needed for globals with destructors. It will only be needed for functions
- // that are marked as global destructors with an attribute.
- assert(!cir::MissingFeatures::opGlobalDtorList());
+ if (!globalDtorList.empty()) {
+ llvm::SmallVector<mlir::Attribute> globalDtors =
+ prepareCtorDtorAttrList<cir::GlobalDtorAttr>(&getContext(),
+ globalDtorList);
+ mlirModule->setAttr(cir::CIRDialect::getGlobalDtorsAttrName(),
+ mlir::ArrayAttr::get(&getContext(), globalDtors));
+ }
}
void LoweringPreparePass::buildCXXGlobalInitFunc() {
@@ -975,22 +980,28 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) {
}
void LoweringPreparePass::runOnOp(mlir::Operation *op) {
- if (auto arrayCtor = dyn_cast<ArrayCtor>(op))
+ if (auto arrayCtor = dyn_cast<cir::ArrayCtor>(op)) {
lowerArrayCtor(arrayCtor);
- else if (auto arrayDtor = dyn_cast<cir::ArrayDtor>(op))
+ } else if (auto arrayDtor = dyn_cast<cir::ArrayDtor>(op)) {
lowerArrayDtor(arrayDtor);
- else if (auto cast = mlir::dyn_cast<cir::CastOp>(op))
+ } else if (auto cast = mlir::dyn_cast<cir::CastOp>(op)) {
lowerCastOp(cast);
- else if (auto complexDiv = mlir::dyn_cast<cir::ComplexDivOp>(op))
+ } else if (auto complexDiv = mlir::dyn_cast<cir::ComplexDivOp>(op)) {
lowerComplexDivOp(complexDiv);
- else if (auto complexMul = mlir::dyn_cast<cir::ComplexMulOp>(op))
+ } else if (auto complexMul = mlir::dyn_cast<cir::ComplexMulOp>(op)) {
lowerComplexMulOp(complexMul);
- else if (auto glob = mlir::dyn_cast<cir::GlobalOp>(op))
+ } else if (auto glob = mlir::dyn_cast<cir::GlobalOp>(op)) {
lowerGlobalOp(glob);
- else if (auto dynamicCast = mlir::dyn_cast<cir::DynamicCastOp>(op))
+ } else if (auto dynamicCast = mlir::dyn_cast<cir::DynamicCastOp>(op)) {
lowerDynamicCastOp(dynamicCast);
- else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op))
+ } else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op)) {
lowerUnaryOp(unary);
+ } else if (auto fnOp = dyn_cast<cir::FuncOp>(op)) {
+ if (auto globalCtor = fnOp.getGlobalCtorPriority())
+ globalCtorList.emplace_back(fnOp.getName(), globalCtor.value());
+ else if (auto globalDtor = fnOp.getGlobalDtorPriority())
+ globalDtorList.emplace_back(fnOp.getName(), globalDtor.value());
+ }
}
void LoweringPreparePass::runOnOperation() {
@@ -1003,7 +1014,7 @@ void LoweringPreparePass::runOnOperation() {
op->walk([&](mlir::Operation *op) {
if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp,
cir::ComplexMulOp, cir::ComplexDivOp, cir::DynamicCastOp,
- cir::GlobalOp, cir::UnaryOp>(op))
+ cir::FuncOp, cir::GlobalOp, cir::UnaryOp>(op))
opsToTransform.push_back(op);
});