Enzyme main
Loading...
Searching...
No Matches
FuncAutoDiffOpInterfaceImpl.cpp
Go to the documentation of this file.
1//===- FuncAutoDiffOpInterfaceImpl.cpp - Interface external model --------===//
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 contains the external model implementation of the automatic
10// differentiation op interfaces for the upstream MLIR arithmetic dialect.
11//
12//===----------------------------------------------------------------------===//
13
18#include "mlir/Dialect/Func/IR/FuncOps.h"
19#include "mlir/IR/DialectRegistry.h"
20#include "mlir/Support/LogicalResult.h"
21
22#include "Dialect/Ops.h"
23#include "mlir/IR/TypeSupport.h"
24
25using namespace mlir;
26using namespace mlir::enzyme;
27
28namespace {
29#include "Implementations/FuncDerivatives.inc"
30} // namespace
31
33 : public AutoDiffFunctionInterface::ExternalModel<
34 AutoDiffFuncFuncFunctionInterface, func::FuncOp> {
35public:
36 void transformResultTypes(Operation *self,
37 SmallVectorImpl<Type> &types) const {}
38
39 // A func.func carries no linkage of its own, but one raised from an
40 // llvm.func still holds the primal's comdat as a plain attribute, and the
41 // clone inherits it. The derivative is not part of the primal's
42 // deduplication group (see the llvm.func model above for why that group is
43 // wrong for it), and a func.func cannot express a comdat anyway -- what
44 // remains is a dangling nested symbol reference that breaks symbol-use
45 // walks such as gpu-kernel-outlining's. Drop it.
46 void detachFromPrimalDefinition(Operation *self) const {
47 self->removeAttr("comdat");
48 }
49
50 Operation *createCall(Operation *self, OpBuilder &builder, Location loc,
51 ValueRange args) const {
52 return func::CallOp::create(builder, loc, cast<func::FuncOp>(self), args);
53 }
54
55 Operation *createReturn(Operation *self, OpBuilder &builder, Location loc,
56 ValueRange args) const {
57 return func::ReturnOp::create(builder, loc, args);
58 }
59};
60
62 DialectRegistry &registry) {
63 registry.addExtension(+[](MLIRContext *context, func::FuncDialect *) {
64 registerInterfaces(context);
65 func::FuncOp::attachInterface<AutoDiffFuncFuncFunctionInterface>(*context);
66 });
67}
Operation * createCall(Operation *self, OpBuilder &builder, Location loc, ValueRange args) const
Operation * createReturn(Operation *self, OpBuilder &builder, Location loc, ValueRange args) const
void detachFromPrimalDefinition(Operation *self) const
void transformResultTypes(Operation *self, SmallVectorImpl< Type > &types) const
void registerFuncDialectAutoDiffInterface(DialectRegistry &registry)