clang 24.0.0git
CIRABIRewriteContext.h
Go to the documentation of this file.
1//===- CIRABIRewriteContext.h - CIR ABI rewrite context ---------*- 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// Defines CIRABIRewriteContext, the CIR dialect's implementation of the
10// generic mlir::abi::ABIRewriteContext. Given a FunctionClassification it
11// rewrites a cir.func signature, the function body, and call sites to match
12// the ABI-lowered shape.
13//
14// This file handles Direct (pass-through and coerce-in-registers), Extend,
15// Ignore, Indirect (sret return, byval and non-byval arguments), and Expand
16// (struct flattening into scalar fields).
17//
18//===----------------------------------------------------------------------===//
19
20#ifndef CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_CIRABIREWRITECONTEXT_H
21#define CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_CIRABIREWRITECONTEXT_H
22
23#include "mlir/ABI/ABIRewriteContext.h"
24#include "mlir/IR/BuiltinOps.h"
25#include "mlir/Interfaces/DataLayoutInterfaces.h"
27#include "llvm/ADT/SmallVector.h"
28#include <cassert>
29#include <utility>
30
31namespace cir {
32
33/// CIR-specific implementation of mlir::abi::ABIRewriteContext.
34///
35/// The driver pass (CallConvLoweringPass) computes a FunctionClassification
36/// for each cir.func / cir.call and dispatches to this class to perform the
37/// actual IR rewriting using cir dialect operations.
38///
39/// Holds a reference to the module's DataLayout for coercion alignment
40/// queries. The DataLayout must outlive the rewrite context.
42public:
43 CIRABIRewriteContext(mlir::ModuleOp module, const mlir::DataLayout &dl)
44 : module(module), dl(dl) {}
45
47 assert(pendingParamSlots.empty() &&
48 "finalizeParameterSlots must run before the rewrite context dies");
49 }
50
51 mlir::LogicalResult
52 rewriteFunctionDefinition(mlir::FunctionOpInterface funcOp,
53 const mlir::abi::FunctionClassification &fc,
54 mlir::OpBuilder &builder) override;
55
56 mlir::LogicalResult
57 rewriteCallSite(mlir::Operation *callOp,
58 const mlir::abi::FunctionClassification &fc,
59 mlir::OpBuilder &builder) override;
60
61 /// Expand a `cir.va_arg` into the x86-64 SysV register-save-area /
62 /// overflow-area sequence.
63 mlir::LogicalResult rewriteVAArg(mlir::Operation *vaArgOp,
64 const mlir::abi::ArgClassification &ac,
65 mlir::OpBuilder &builder) override;
66
67 /// Retype \p addrOp, which holds the address of \p funcOp, to the signature
68 /// funcOp was rewritten to, and cast it back so existing uses keep the type
69 /// they were built for. A no-op when the ABI left funcOp's type alone.
70 /// Call after funcOp has been rewritten. Not an override, since taking a
71 /// function's address has no counterpart in the generic contract.
72 void rewriteFunctionAddress(cir::GetGlobalOp addrOp, cir::FuncOp funcOp,
73 mlir::OpBuilder &builder);
74
75 /// Restate each non-byval indirect parameter's CIRGen slot alignment as the
76 /// alignment the ABI promises for that parameter. CIRGen picked the slot's
77 /// alignment for a local copy of the record, but the slot is about to stand
78 /// in for the parameter, and a call forwarding it may only promise what the
79 /// incoming pointer does. Call for every function before any call site is
80 /// rewritten, since a call is rewritten with its callee rather than with its
81 /// enclosing function and so may be reached first. Not an override, since
82 /// this has no counterpart in the generic contract.
83 void
84 normalizeParameterSlotAlignments(cir::FuncOp funcOp,
85 const mlir::abi::FunctionClassification &fc);
86
87 /// Replace each non-byval indirect parameter's CIRGen slot with the
88 /// incoming pointer, so the body operates on the caller's storage in place.
89 /// Call once, after every function and call site has been rewritten: a call
90 /// forwarding such a parameter reads the slot to recognise it. Not an
91 /// override, since deferring this has no counterpart in the generic
92 /// contract.
94
95 mlir::StringRef getDialectNamespace() const override { return "cir"; }
96
97private:
98 mlir::ModuleOp module;
99 const mlir::DataLayout &dl;
100
101 /// CIRGen param-slot allocas that non-byval indirect parameters will
102 /// replace, paired with the incoming pointer that replaces them. The
103 /// rewrite retypes the block argument but leaves the slot standing, because
104 /// a call site recognises a forwardable parameter by the slot its operand
105 /// was loaded from. finalizeParameterSlots does the replacement once every
106 /// call site has been rewritten.
108 pendingParamSlots;
109};
110
111} // namespace cir
112
113#endif // CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_CIRABIREWRITECONTEXT_H
void rewriteFunctionAddress(cir::GetGlobalOp addrOp, cir::FuncOp funcOp, mlir::OpBuilder &builder)
Retype addrOp, which holds the address of funcOp, to the signature funcOp was rewritten to,...
mlir::LogicalResult rewriteFunctionDefinition(mlir::FunctionOpInterface funcOp, const mlir::abi::FunctionClassification &fc, mlir::OpBuilder &builder) override
void normalizeParameterSlotAlignments(cir::FuncOp funcOp, const mlir::abi::FunctionClassification &fc)
Restate each non-byval indirect parameter's CIRGen slot alignment as the alignment the ABI promises f...
void finalizeParameterSlots()
Replace each non-byval indirect parameter's CIRGen slot with the incoming pointer,...
mlir::StringRef getDialectNamespace() const override
CIRABIRewriteContext(mlir::ModuleOp module, const mlir::DataLayout &dl)
mlir::LogicalResult rewriteVAArg(mlir::Operation *vaArgOp, const mlir::abi::ArgClassification &ac, mlir::OpBuilder &builder) override
Expand a cir.va_arg into the x86-64 SysV register-save-area / overflow-area sequence.
mlir::LogicalResult rewriteCallSite(mlir::Operation *callOp, const mlir::abi::FunctionClassification &fc, mlir::OpBuilder &builder) override