Files
gps/tools/local/circt/include/mlir/ABI/ABIRewriteContext.h
T
2026-07-12 11:01:51 +03:00

160 lines
5.2 KiB
C++

//===- ABIRewriteContext.h - Dialect-specific ABI rewriting -----*- C++ -*-===//
//
// 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 defines ABIRewriteContext, the abstract interface for dialect-
// specific ABI lowering rewrites. Each MLIR dialect that wants ABI lowering
// (CIR, FIR, etc.) provides a concrete subclass.
//
// ABIRewriteContext consumes ABI classification results and drives the
// creation of lowered function signatures, argument coercions, and call
// site rewrites using dialect-specific operations.
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_ABI_ABIREWRITECONTEXT_H
#define MLIR_ABI_ABIREWRITECONTEXT_H
#include "mlir/IR/Builders.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/Types.h"
#include "mlir/IR/Value.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "llvm/Support/Alignment.h"
namespace mlir {
namespace abi {
/// Classification of how a single argument or return value should be
/// passed at the ABI level.
///
/// This is a dialect-agnostic representation. It mirrors the kinds
/// found in the LLVM ABI library and in CIR's ABIArgInfo, but does
/// not depend on either.
enum class ArgKind : uint8_t {
/// Pass directly in registers, possibly coerced to a different type.
Direct,
/// Like Direct, but with a sign/zero extension attribute.
Extend,
/// Pass indirectly via a pointer (sret for returns, byval for args).
Indirect,
/// Ignore (void return, empty struct).
Ignore,
/// Expand an aggregate into its constituent scalar fields.
Expand,
};
/// Describes how a single argument or return value is passed after ABI
/// lowering.
struct ArgClassification {
ArgKind kind = ArgKind::Direct;
/// The ABI-coerced type, if different from the original. Null means
/// use the original type.
Type coercedType = nullptr;
/// For Indirect: alignment of the pointed-to object.
llvm::Align indirectAlign = llvm::Align(1);
/// For Extend: whether to sign-extend (true) or zero-extend (false).
bool signExtend = false;
/// For Direct: whether a struct coercion can be flattened into
/// individual register-width arguments.
bool canFlatten = true;
/// For Indirect: whether the callee gets ownership (byval).
bool byVal = false;
static ArgClassification getDirect(Type coerced = nullptr) {
ArgClassification c;
c.kind = ArgKind::Direct;
c.coercedType = coerced;
return c;
}
static ArgClassification getIgnore() {
ArgClassification c;
c.kind = ArgKind::Ignore;
return c;
}
static ArgClassification getIndirect(llvm::Align align, bool byVal = true) {
ArgClassification c;
c.kind = ArgKind::Indirect;
c.indirectAlign = align;
c.byVal = byVal;
return c;
}
static ArgClassification getExtend(Type coerced, bool signExt) {
ArgClassification c;
c.kind = ArgKind::Extend;
c.coercedType = coerced;
c.signExtend = signExt;
return c;
}
};
/// Holds the full ABI classification for a function: return type and
/// all arguments.
struct FunctionClassification {
ArgClassification returnInfo;
SmallVector<ArgClassification> argInfos;
};
/// ABIRewriteContext is the abstract interface that each dialect
/// implements to perform ABI-specific rewrites on its operations.
///
/// The pass orchestrator calls these methods after ABI classification
/// to rewrite function definitions and call sites.
class ABIRewriteContext {
public:
virtual ~ABIRewriteContext() = default;
/// Rewrite a function definition to use ABI-lowered types.
///
/// This creates a new function with the lowered signature, rewrites
/// the function body to adapt between the ABI types and the
/// original high-level types, and replaces the original function.
///
/// \param funcOp The function to rewrite (via FunctionOpInterface).
/// \param fc The ABI classification for this function.
/// \param builder The OpBuilder to use for modifications.
/// \returns success() if the function was rewritten.
virtual LogicalResult
rewriteFunctionDefinition(FunctionOpInterface funcOp,
const FunctionClassification &fc,
OpBuilder &builder) = 0;
/// Rewrite a call operation to match the callee's ABI-lowered
/// signature.
///
/// This coerces arguments, handles indirect returns (sret), and
/// adapts the call result back to the original high-level type.
///
/// \param callOp The call operation to rewrite.
/// \param fc The ABI classification for the callee.
/// \param builder The OpBuilder to use for modifications.
/// \returns success() if the call was rewritten.
virtual LogicalResult rewriteCallSite(Operation *callOp,
const FunctionClassification &fc,
OpBuilder &builder) = 0;
/// Return the dialect namespace this context handles (e.g. "cir").
virtual StringRef getDialectNamespace() const = 0;
};
} // namespace abi
} // namespace mlir
#endif // MLIR_ABI_ABIREWRITECONTEXT_H