Sirui Mu b9f3710c0e
[CIR] Add TargetLowering pass (#179245)
This patch adds a new TargetLowering pass to the CIR pipeline. The new
pass is run immediately before CXXABILowering. This new pass does not
perform any heavy transformations yet -- for now it only converts sync
scopes attached to load and store operations according to the target
info, which was done in the LLVM lowering pass.

Related to #175968 .
2026-02-05 21:40:50 +08:00

69 lines
2.2 KiB
C++

//===- TargetLowering.cpp -------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the cir-target-lowering pass.
//
//===----------------------------------------------------------------------===//
#include "TargetLowering/LowerModule.h"
#include "mlir/Support/LLVM.h"
#include "clang/CIR/Dialect/Passes.h"
#include "llvm/ADT/TypeSwitch.h"
using namespace mlir;
using namespace cir;
namespace mlir {
#define GEN_PASS_DEF_TARGETLOWERING
#include "clang/CIR/Dialect/Passes.h.inc"
} // namespace mlir
namespace {
struct TargetLoweringPass
: public impl::TargetLoweringBase<TargetLoweringPass> {
TargetLoweringPass() = default;
void runOnOperation() override;
};
} // namespace
static void convertSyncScopeIfPresent(mlir::Operation *op,
cir::LowerModule &lowerModule) {
auto syncScopeAttr =
mlir::cast_if_present<cir::SyncScopeKindAttr>(op->getAttr("sync_scope"));
if (syncScopeAttr) {
cir::SyncScopeKind convertedSyncScope =
lowerModule.getTargetLoweringInfo().convertSyncScope(
syncScopeAttr.getValue());
op->setAttr("sync_scope", cir::SyncScopeKindAttr::get(op->getContext(),
convertedSyncScope));
}
}
void TargetLoweringPass::runOnOperation() {
auto mod = mlir::cast<mlir::ModuleOp>(getOperation());
std::unique_ptr<cir::LowerModule> lowerModule = cir::createLowerModule(mod);
// If lower module is not available, skip the target lowering pass.
if (!lowerModule) {
mod.emitWarning("Cannot create a CIR lower module, skipping the ")
<< getName() << " pass";
return;
}
mod->walk([&](mlir::Operation *op) {
if (mlir::isa<cir::LoadOp, cir::StoreOp>(op))
convertSyncScopeIfPresent(op, *lowerModule);
});
}
std::unique_ptr<Pass> mlir::createTargetLoweringPass() {
return std::make_unique<TargetLoweringPass>();
}