MLIR 23.0.0git
ABIRewriteContext.h
Go to the documentation of this file.
1//===- ABIRewriteContext.h - Dialect-specific ABI rewriting -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines ABIRewriteContext, the abstract interface for dialect-
10// specific ABI lowering rewrites. Each MLIR dialect that wants ABI lowering
11// (CIR, FIR, etc.) provides a concrete subclass.
12//
13// ABIRewriteContext consumes ABI classification results and drives the
14// creation of lowered function signatures, argument coercions, and call
15// site rewrites using dialect-specific operations.
16//
17//===----------------------------------------------------------------------===//
18
19#ifndef MLIR_ABI_ABIREWRITECONTEXT_H
20#define MLIR_ABI_ABIREWRITECONTEXT_H
21
22#include "mlir/IR/Builders.h"
23#include "mlir/IR/Operation.h"
24#include "mlir/IR/Types.h"
25#include "mlir/IR/Value.h"
27#include "llvm/Support/Alignment.h"
28
29namespace mlir {
30namespace abi {
31
32/// Classification of how a single argument or return value should be
33/// passed at the ABI level.
34///
35/// This is a dialect-agnostic representation. It mirrors the kinds
36/// found in the LLVM ABI library and in CIR's ABIArgInfo, but does
37/// not depend on either.
38enum class ArgKind : uint8_t {
39 /// Pass directly in registers, possibly coerced to a different type.
41
42 /// Like Direct, but with a sign/zero extension attribute.
44
45 /// Pass indirectly via a pointer (sret for returns, byval for args).
47
48 /// Ignore (void return, empty struct).
50
51 /// Expand an aggregate into its constituent scalar fields.
53};
54
55/// Describes how a single argument or return value is passed after ABI
56/// lowering.
59
60 /// The ABI-coerced type, if different from the original. Null means
61 /// use the original type.
62 Type coercedType = nullptr;
63
64 /// For Indirect: alignment of the pointed-to object.
65 llvm::Align indirectAlign = llvm::Align(1);
66
67 /// For Extend: whether to sign-extend (true) or zero-extend (false).
68 bool signExtend = false;
69
70 /// For Direct: whether a struct coercion can be flattened into
71 /// individual register-width arguments.
72 bool canFlatten = true;
73
74 /// For Indirect: whether the callee gets ownership (byval).
75 bool byVal = false;
76
77 static ArgClassification getDirect(Type coerced = nullptr) {
80 c.coercedType = coerced;
81 return c;
82 }
83
87 return c;
88 }
89
90 static ArgClassification getIndirect(llvm::Align align, bool byVal = true) {
93 c.indirectAlign = align;
94 c.byVal = byVal;
95 return c;
96 }
97
98 static ArgClassification getExtend(Type coerced, bool signExt) {
101 c.coercedType = coerced;
102 c.signExtend = signExt;
103 return c;
104 }
105};
106
107/// Holds the full ABI classification for a function: return type and
108/// all arguments.
113
114/// ABIRewriteContext is the abstract interface that each dialect
115/// implements to perform ABI-specific rewrites on its operations.
116///
117/// The pass orchestrator calls these methods after ABI classification
118/// to rewrite function definitions and call sites.
120public:
121 virtual ~ABIRewriteContext() = default;
122
123 /// Rewrite a function definition to use ABI-lowered types.
124 ///
125 /// This creates a new function with the lowered signature, rewrites
126 /// the function body to adapt between the ABI types and the
127 /// original high-level types, and replaces the original function.
128 ///
129 /// \param funcOp The function to rewrite (via FunctionOpInterface).
130 /// \param fc The ABI classification for this function.
131 /// \param rewriter The pattern rewriter to use for modifications.
132 /// \returns success() if the function was rewritten.
133 virtual LogicalResult
134 rewriteFunctionDefinition(FunctionOpInterface funcOp,
135 const FunctionClassification &fc,
136 OpBuilder &rewriter) = 0;
137
138 /// Rewrite a call operation to match the callee's ABI-lowered
139 /// signature.
140 ///
141 /// This coerces arguments, handles indirect returns (sret), and
142 /// adapts the call result back to the original high-level type.
143 ///
144 /// \param callOp The call operation to rewrite.
145 /// \param fc The ABI classification for the callee.
146 /// \param rewriter The pattern rewriter to use for modifications.
147 /// \returns success() if the call was rewritten.
148 virtual LogicalResult rewriteCallSite(Operation *callOp,
149 const FunctionClassification &fc,
150 OpBuilder &rewriter) = 0;
151
152 /// Return the dialect namespace this context handles (e.g. "cir").
153 virtual StringRef getDialectNamespace() const = 0;
154};
155
156} // namespace abi
157} // namespace mlir
158
159#endif // MLIR_ABI_ABIREWRITECONTEXT_H
This class helps build Operations.
Definition Builders.h:209
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
ABIRewriteContext is the abstract interface that each dialect implements to perform ABI-specific rewr...
virtual LogicalResult rewriteFunctionDefinition(FunctionOpInterface funcOp, const FunctionClassification &fc, OpBuilder &rewriter)=0
Rewrite a function definition to use ABI-lowered types.
virtual StringRef getDialectNamespace() const =0
Return the dialect namespace this context handles (e.g. "cir").
virtual ~ABIRewriteContext()=default
virtual LogicalResult rewriteCallSite(Operation *callOp, const FunctionClassification &fc, OpBuilder &rewriter)=0
Rewrite a call operation to match the callee's ABI-lowered signature.
ArgKind
Classification of how a single argument or return value should be passed at the ABI level.
@ Indirect
Pass indirectly via a pointer (sret for returns, byval for args).
@ Extend
Like Direct, but with a sign/zero extension attribute.
@ Expand
Expand an aggregate into its constituent scalar fields.
@ Ignore
Ignore (void return, empty struct).
@ Direct
Pass directly in registers, possibly coerced to a different type.
Include the generated interface declarations.
Describes how a single argument or return value is passed after ABI lowering.
static ArgClassification getIgnore()
static ArgClassification getDirect(Type coerced=nullptr)
bool canFlatten
For Direct: whether a struct coercion can be flattened into individual register-width arguments.
bool signExtend
For Extend: whether to sign-extend (true) or zero-extend (false).
static ArgClassification getIndirect(llvm::Align align, bool byVal=true)
Type coercedType
The ABI-coerced type, if different from the original.
bool byVal
For Indirect: whether the callee gets ownership (byval).
llvm::Align indirectAlign
For Indirect: alignment of the pointed-to object.
static ArgClassification getExtend(Type coerced, bool signExt)
Holds the full ABI classification for a function: return type and all arguments.
SmallVector< ArgClassification > argInfos