Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
//===- DialectConversion.cpp - MLIR dialect conversion generic pass -------===//
|
|
|
|
|
//
|
|
|
|
|
// Copyright 2019 The MLIR Authors.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
#include "mlir/Transforms/DialectConversion.h"
|
|
|
|
|
#include "mlir/IR/BlockAndValueMapping.h"
|
|
|
|
|
#include "mlir/IR/Builders.h"
|
|
|
|
|
#include "mlir/IR/Function.h"
|
|
|
|
|
#include "mlir/IR/Module.h"
|
|
|
|
|
#include "mlir/Transforms/Utils.h"
|
|
|
|
|
|
|
|
|
|
using namespace mlir;
|
2019-05-19 17:56:32 -07:00
|
|
|
using namespace mlir::impl;
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 20:54:13 -07:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// ProducerGenerator
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
2019-05-17 22:21:13 -07:00
|
|
|
namespace {
|
2019-05-19 17:56:32 -07:00
|
|
|
/// This class provides a simple interface for generating fake producers during
|
|
|
|
|
/// the conversion process. These fake producers are used when replacing the
|
|
|
|
|
/// results of an operation with values of a new, legal, type. The producer
|
|
|
|
|
/// provides a definition for the remaining uses of the old value while they
|
|
|
|
|
/// await conversion.
|
|
|
|
|
struct ProducerGenerator {
|
|
|
|
|
ProducerGenerator(MLIRContext *ctx)
|
|
|
|
|
: producerOpName(kProducerName, ctx), loc(UnknownLoc::get(ctx)) {}
|
|
|
|
|
|
|
|
|
|
/// Cleanup any generated conversion values. Returns failure if there are any
|
|
|
|
|
/// dangling references to a producer operation, success otherwise.
|
|
|
|
|
LogicalResult cleanupGeneratedOps() {
|
|
|
|
|
for (auto *op : producerOps) {
|
|
|
|
|
if (!op->use_empty()) {
|
|
|
|
|
auto diag = op->getContext()->emitError(loc)
|
|
|
|
|
<< "Converter did not convert all uses of replaced value "
|
|
|
|
|
"with illegal type";
|
|
|
|
|
for (auto *user : op->getResult(0)->getUsers())
|
|
|
|
|
diag.attachNote(user->getLoc())
|
|
|
|
|
<< "user was not converted : " << *user;
|
|
|
|
|
return diag;
|
|
|
|
|
}
|
|
|
|
|
op->destroy();
|
|
|
|
|
}
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Generate a producer value for 'oldValue'. These new producers replace all
|
|
|
|
|
/// of the current uses of the original value, and record a mapping between
|
|
|
|
|
/// for replacement with the 'newValue'.
|
|
|
|
|
void generateAndReplace(Value *oldValue, Value *newValue,
|
|
|
|
|
BlockAndValueMapping &mapping) {
|
|
|
|
|
if (oldValue->use_empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Otherwise, generate a new producer operation for the given value type.
|
|
|
|
|
auto *producer = Operation::create(
|
|
|
|
|
loc, producerOpName, llvm::None, oldValue->getType(), llvm::None,
|
|
|
|
|
llvm::None, 0, false, oldValue->getContext());
|
|
|
|
|
|
|
|
|
|
// Replace the uses of the old value and record the mapping.
|
|
|
|
|
oldValue->replaceAllUsesWith(producer->getResult(0));
|
|
|
|
|
mapping.map(producer->getResult(0), newValue);
|
|
|
|
|
producerOps.push_back(producer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// This is an operation name for a fake operation that is inserted during the
|
|
|
|
|
/// conversion process. Operations of this type are guaranteed to never escape
|
|
|
|
|
/// the converter.
|
|
|
|
|
static constexpr StringLiteral kProducerName = "__mlir_conversion.producer";
|
|
|
|
|
OperationName producerOpName;
|
|
|
|
|
|
|
|
|
|
/// This is a collection of producer values that were generated during the
|
|
|
|
|
/// conversion process.
|
|
|
|
|
std::vector<Operation *> producerOps;
|
|
|
|
|
|
|
|
|
|
/// An instance of the unknown location that is used when generating
|
|
|
|
|
/// producers.
|
|
|
|
|
UnknownLoc loc;
|
|
|
|
|
};
|
|
|
|
|
|
2019-05-19 23:09:29 -07:00
|
|
|
constexpr StringLiteral ProducerGenerator::kProducerName;
|
|
|
|
|
|
2019-05-19 20:54:13 -07:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// DialectConversionRewriter
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
/// This class implements a pattern rewriter for DialectConversionPattern
|
|
|
|
|
/// patterns. It automatically performs remapping of replaced operation values.
|
2019-05-17 22:21:13 -07:00
|
|
|
struct DialectConversionRewriter final : public PatternRewriter {
|
2019-05-19 17:56:32 -07:00
|
|
|
DialectConversionRewriter(Function *fn)
|
|
|
|
|
: PatternRewriter(fn), tempGenerator(fn->getContext()) {}
|
2019-05-17 22:21:13 -07:00
|
|
|
~DialectConversionRewriter() = default;
|
|
|
|
|
|
|
|
|
|
// Implement the hook for replacing an operation with new values.
|
|
|
|
|
void replaceOp(Operation *op, ArrayRef<Value *> newValues,
|
|
|
|
|
ArrayRef<Value *> valuesToRemoveIfDead) override {
|
|
|
|
|
assert(newValues.size() == op->getNumResults());
|
2019-05-19 17:56:32 -07:00
|
|
|
for (unsigned i = 0, e = newValues.size(); i < e; ++i) {
|
|
|
|
|
Value *result = op->getResult(i);
|
|
|
|
|
if (result->getType() != newValues[i]->getType())
|
|
|
|
|
tempGenerator.generateAndReplace(result, newValues[i], mapping);
|
|
|
|
|
else
|
|
|
|
|
result->replaceAllUsesWith(newValues[i]);
|
|
|
|
|
}
|
|
|
|
|
op->erase();
|
2019-05-17 22:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement the hook for creating operations, and make sure that newly
|
|
|
|
|
// created ops are added to the worklist for processing.
|
|
|
|
|
Operation *createOperation(const OperationState &state) override {
|
|
|
|
|
return FuncBuilder::createOperation(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lookupValues(Operation::operand_range operands,
|
|
|
|
|
SmallVectorImpl<Value *> &remapped) {
|
|
|
|
|
remapped.reserve(llvm::size(operands));
|
2019-05-19 17:56:32 -07:00
|
|
|
for (Value *operand : operands)
|
|
|
|
|
remapped.push_back(mapping.lookupOrDefault(operand));
|
2019-05-17 22:21:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mapping between values(blocks) in the original function and in the new
|
|
|
|
|
// function.
|
|
|
|
|
BlockAndValueMapping mapping;
|
2019-05-19 17:56:32 -07:00
|
|
|
|
|
|
|
|
/// Utility used to create temporary producers operations.
|
|
|
|
|
ProducerGenerator tempGenerator;
|
2019-05-17 22:21:13 -07:00
|
|
|
};
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
2019-05-19 20:54:13 -07:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// DialectConversionPattern
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2019-05-17 22:21:13 -07:00
|
|
|
/// Rewrite the IR rooted at the specified operation with the result of
|
|
|
|
|
/// this pattern, generating any new operations with the specified
|
|
|
|
|
/// builder. If an unexpected error is encountered (an internal
|
|
|
|
|
/// compiler error), it is emitted through the normal MLIR diagnostic
|
|
|
|
|
/// hooks and the IR is left in a valid state.
|
2019-05-19 20:54:13 -07:00
|
|
|
void DialectConversionPattern::rewrite(Operation *op,
|
|
|
|
|
PatternRewriter &rewriter) const {
|
2019-05-17 22:21:13 -07:00
|
|
|
SmallVector<Value *, 4> operands;
|
|
|
|
|
auto &dialectRewriter = static_cast<DialectConversionRewriter &>(rewriter);
|
|
|
|
|
dialectRewriter.lookupValues(op->getOperands(), operands);
|
|
|
|
|
|
|
|
|
|
// If this operation has no successors, invoke the rewrite directly.
|
|
|
|
|
if (op->getNumSuccessors() == 0)
|
|
|
|
|
return rewrite(op, operands, rewriter);
|
|
|
|
|
|
|
|
|
|
// Otherwise, we need to remap the successors.
|
|
|
|
|
SmallVector<Block *, 2> destinations;
|
|
|
|
|
destinations.reserve(op->getNumSuccessors());
|
|
|
|
|
|
|
|
|
|
SmallVector<ArrayRef<Value *>, 2> operandsPerDestination;
|
|
|
|
|
unsigned firstSuccessorOperand = op->getSuccessorOperandIndex(0);
|
|
|
|
|
for (unsigned i = 0, seen = 0, e = op->getNumSuccessors(); i < e; ++i) {
|
2019-05-19 17:56:32 -07:00
|
|
|
destinations.push_back(op->getSuccessor(i));
|
2019-05-17 22:21:13 -07:00
|
|
|
|
|
|
|
|
// Lookup the successors operands.
|
|
|
|
|
unsigned n = op->getNumSuccessorOperands(i);
|
|
|
|
|
operandsPerDestination.push_back(
|
|
|
|
|
llvm::makeArrayRef(operands.data() + firstSuccessorOperand + seen, n));
|
|
|
|
|
seen += n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Rewrite the operation.
|
|
|
|
|
rewrite(op,
|
|
|
|
|
llvm::makeArrayRef(operands.data(),
|
|
|
|
|
operands.data() + firstSuccessorOperand),
|
|
|
|
|
destinations, operandsPerDestination, rewriter);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 20:54:13 -07:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// FunctionConverter
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
namespace {
|
2019-05-19 17:56:32 -07:00
|
|
|
// Implementation detail class of the DialectConversion utility. Performs
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
// function-by-function conversions by creating new functions, filling them in
|
|
|
|
|
// with converted blocks, updating the function attributes, and replacing the
|
|
|
|
|
// old functions with the new ones in the module.
|
2019-05-19 17:56:32 -07:00
|
|
|
class FunctionConverter {
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
public:
|
2019-05-19 17:56:32 -07:00
|
|
|
// Constructs a FunctionConverter.
|
|
|
|
|
explicit FunctionConverter(MLIRContext *ctx, DialectConversion *conversion,
|
|
|
|
|
RewritePatternMatcher &matcher)
|
|
|
|
|
: dialectConversion(conversion), matcher(matcher) {}
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Converts the given function to the dialect using hooks defined in
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
// `dialectConversion`. Returns the converted function or `nullptr` on error.
|
2019-05-19 17:56:32 -07:00
|
|
|
Function *convertFunction(Function *f);
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-03-28 15:58:53 -07:00
|
|
|
// Converts the given region starting from the entry block and following the
|
2019-05-19 17:56:32 -07:00
|
|
|
// block successors. Returns failure on error, success otherwise.
|
2019-03-28 15:58:53 -07:00
|
|
|
template <typename RegionParent>
|
2019-05-19 17:56:32 -07:00
|
|
|
LogicalResult convertRegion(DialectConversionRewriter &rewriter,
|
|
|
|
|
Region ®ion, RegionParent *parent);
|
2019-03-28 15:58:53 -07:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Converts a block by traversing its operations sequentially, attempting to
|
|
|
|
|
// match a pattern. If there is no match, recurses the operations regions if
|
|
|
|
|
// it has any.
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
//
|
|
|
|
|
// After converting operations, traverses the successor blocks unless they
|
|
|
|
|
// have been visited already as indicated in `visitedBlocks`.
|
2019-05-19 17:56:32 -07:00
|
|
|
LogicalResult convertBlock(DialectConversionRewriter &rewriter, Block *block,
|
|
|
|
|
DenseSet<Block *> &visitedBlocks);
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Converts the type of the given block argument. Returns success if the
|
|
|
|
|
// argument type could be successfully converted, failure otherwise.
|
|
|
|
|
LogicalResult convertArgument(DialectConversionRewriter &rewriter,
|
|
|
|
|
BlockArgument *arg, Location loc);
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Pointer to a specific dialect conversion info.
|
|
|
|
|
DialectConversion *dialectConversion;
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
/// The matcher to use when converting operations.
|
2019-05-17 22:21:13 -07:00
|
|
|
RewritePatternMatcher &matcher;
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
};
|
2019-05-19 20:54:13 -07:00
|
|
|
} // end anonymous namespace
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-03-08 16:04:42 -08:00
|
|
|
LogicalResult
|
2019-05-19 17:56:32 -07:00
|
|
|
FunctionConverter::convertArgument(DialectConversionRewriter &rewriter,
|
|
|
|
|
BlockArgument *arg, Location loc) {
|
|
|
|
|
auto convertedType = dialectConversion->convertType(arg->getType());
|
|
|
|
|
if (!convertedType)
|
|
|
|
|
return arg->getContext()->emitError(loc)
|
|
|
|
|
<< "could not convert block argument of type : " << arg->getType();
|
|
|
|
|
|
|
|
|
|
// Generate a replacement value, with the new type, for this argument.
|
|
|
|
|
if (convertedType != arg->getType()) {
|
|
|
|
|
rewriter.tempGenerator.generateAndReplace(arg, arg, rewriter.mapping);
|
|
|
|
|
arg->setType(convertedType);
|
|
|
|
|
}
|
|
|
|
|
return success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LogicalResult
|
|
|
|
|
FunctionConverter::convertBlock(DialectConversionRewriter &rewriter,
|
|
|
|
|
Block *block,
|
|
|
|
|
DenseSet<Block *> &visitedBlocks) {
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
// First, add the current block to the list of visited blocks.
|
|
|
|
|
visitedBlocks.insert(block);
|
2019-05-19 17:56:32 -07:00
|
|
|
|
|
|
|
|
// Preserve the successors before rewriting the operations.
|
|
|
|
|
SmallVector<Block *, 4> successors(block->getSuccessors());
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
|
|
|
|
// Iterate over ops and convert them.
|
2019-05-19 17:56:32 -07:00
|
|
|
for (Operation &op : llvm::make_early_inc_range(*block)) {
|
|
|
|
|
rewriter.setInsertionPoint(&op);
|
2019-05-17 22:21:13 -07:00
|
|
|
if (matcher.matchAndRewrite(&op, rewriter))
|
|
|
|
|
continue;
|
|
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// If a rewrite wasn't matched, update any mapped operands in place.
|
|
|
|
|
for (auto &operand : op.getOpOperands())
|
|
|
|
|
if (auto *newOperand = rewriter.mapping.lookupOrNull(operand.get()))
|
|
|
|
|
operand.set(newOperand);
|
|
|
|
|
|
|
|
|
|
// Traverse any held regions.
|
|
|
|
|
for (auto ®ion : op.getRegions())
|
|
|
|
|
if (!region.empty() && failed(convertRegion(rewriter, region, &op)))
|
|
|
|
|
return failure();
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
}
|
|
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Recurse to children that haven't been visited.
|
|
|
|
|
for (Block *succ : successors) {
|
|
|
|
|
if (visitedBlocks.count(succ))
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
continue;
|
2019-05-19 17:56:32 -07:00
|
|
|
if (failed(convertBlock(rewriter, succ, visitedBlocks)))
|
2019-03-10 15:32:54 -07:00
|
|
|
return failure();
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
}
|
2019-03-10 15:32:54 -07:00
|
|
|
return success();
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
}
|
|
|
|
|
|
2019-03-28 15:58:53 -07:00
|
|
|
template <typename RegionParent>
|
2019-05-19 17:56:32 -07:00
|
|
|
LogicalResult
|
|
|
|
|
FunctionConverter::convertRegion(DialectConversionRewriter &rewriter,
|
|
|
|
|
Region ®ion, RegionParent *parent) {
|
|
|
|
|
assert(!region.empty() && "expected non-empty region");
|
|
|
|
|
|
|
|
|
|
// Create the arguments of each of the blocks in the region.
|
|
|
|
|
for (Block &block : region)
|
|
|
|
|
for (auto *arg : block.getArguments())
|
|
|
|
|
if (failed(convertArgument(rewriter, arg, parent->getLoc())))
|
|
|
|
|
return failure();
|
2019-03-28 15:58:53 -07:00
|
|
|
|
|
|
|
|
// Start a DFS-order traversal of the CFG to make sure defs are converted
|
|
|
|
|
// before uses in dominated blocks.
|
|
|
|
|
llvm::DenseSet<Block *> visitedBlocks;
|
2019-05-19 17:56:32 -07:00
|
|
|
if (failed(convertBlock(rewriter, ®ion.front(), visitedBlocks)))
|
|
|
|
|
return failure();
|
2019-03-28 15:58:53 -07:00
|
|
|
|
|
|
|
|
// If some blocks are not reachable through successor chains, they should have
|
|
|
|
|
// been removed by the DCE before this.
|
2019-05-19 17:56:32 -07:00
|
|
|
if (visitedBlocks.size() != std::distance(region.begin(), region.end()))
|
|
|
|
|
return parent->emitError("unreachable blocks were not converted");
|
|
|
|
|
return success();
|
2019-03-28 15:58:53 -07:00
|
|
|
}
|
|
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
Function *FunctionConverter::convertFunction(Function *f) {
|
|
|
|
|
// Convert the function type using the dialect converter.
|
2019-03-19 01:19:01 -07:00
|
|
|
SmallVector<NamedAttributeList, 4> newFunctionArgAttrs;
|
|
|
|
|
Type newFunctionType = dialectConversion->convertFunctionSignatureType(
|
|
|
|
|
f->getType(), f->getAllArgAttrs(), newFunctionArgAttrs);
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
if (!newFunctionType)
|
2019-05-19 17:56:32 -07:00
|
|
|
return f->emitError("could not convert function type"), nullptr;
|
|
|
|
|
|
|
|
|
|
// Create a new function using the mapped function type and arg attributes.
|
|
|
|
|
auto *newFunc = new Function(f->getLoc(), f->getName().strref(),
|
|
|
|
|
newFunctionType.cast<FunctionType>(),
|
|
|
|
|
f->getAttrs(), newFunctionArgAttrs);
|
|
|
|
|
f->getModule()->getFunctions().push_back(newFunc);
|
|
|
|
|
|
|
|
|
|
// If this is not an external function, we need to convert the body.
|
|
|
|
|
if (!f->isExternal()) {
|
|
|
|
|
DialectConversionRewriter rewriter(f);
|
|
|
|
|
f->getBody().cloneInto(&newFunc->getBody(), rewriter.mapping,
|
|
|
|
|
f->getContext());
|
|
|
|
|
rewriter.mapping.clear();
|
|
|
|
|
if (failed(convertRegion(rewriter, newFunc->getBody(), &*newFunc))) {
|
|
|
|
|
f->getModule()->getFunctions().pop_back();
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Cleanup any temp producer operations that were generated by the rewriter.
|
|
|
|
|
if (failed(rewriter.tempGenerator.cleanupGeneratedOps())) {
|
|
|
|
|
f->getModule()->getFunctions().pop_back();
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return newFunc;
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
}
|
|
|
|
|
|
2019-05-19 20:54:13 -07:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// DialectConversion
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2019-05-17 22:21:13 -07:00
|
|
|
// Create a function type with arguments and results converted, and argument
|
|
|
|
|
// attributes passed through.
|
|
|
|
|
FunctionType DialectConversion::convertFunctionSignatureType(
|
|
|
|
|
FunctionType type, ArrayRef<NamedAttributeList> argAttrs,
|
|
|
|
|
SmallVectorImpl<NamedAttributeList> &convertedArgAttrs) {
|
|
|
|
|
SmallVector<Type, 8> arguments;
|
|
|
|
|
SmallVector<Type, 4> results;
|
|
|
|
|
|
|
|
|
|
arguments.reserve(type.getNumInputs());
|
|
|
|
|
for (auto t : type.getInputs())
|
|
|
|
|
arguments.push_back(convertType(t));
|
|
|
|
|
|
|
|
|
|
results.reserve(type.getNumResults());
|
|
|
|
|
for (auto t : type.getResults())
|
|
|
|
|
results.push_back(convertType(t));
|
|
|
|
|
|
|
|
|
|
// Note this will cause an extra allocation only if we need
|
|
|
|
|
// to grow the caller-provided resulting attribute vector.
|
|
|
|
|
convertedArgAttrs.reserve(arguments.size());
|
|
|
|
|
for (auto attr : argAttrs)
|
|
|
|
|
convertedArgAttrs.push_back(attr);
|
|
|
|
|
|
|
|
|
|
return FunctionType::get(arguments, results, type.getContext());
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
}
|
|
|
|
|
|
2019-05-17 22:21:13 -07:00
|
|
|
// Converts the module as follows.
|
|
|
|
|
// 1. Call `convertFunction` on each function of the module and collect the
|
|
|
|
|
// mapping between old and new functions.
|
|
|
|
|
// 2. Remap all function attributes in the new functions to point to the new
|
|
|
|
|
// functions instead of the old ones.
|
|
|
|
|
// 3. Replace old functions with the new in the module.
|
|
|
|
|
LogicalResult DialectConversion::convert(Module *module) {
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
if (!module)
|
2019-03-10 15:32:54 -07:00
|
|
|
return failure();
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-17 22:21:13 -07:00
|
|
|
// Grab the conversion patterns from the converter and create the pattern
|
|
|
|
|
// matcher.
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
MLIRContext *context = module->getContext();
|
2019-05-17 22:21:13 -07:00
|
|
|
OwningRewritePatternList patterns;
|
|
|
|
|
initConverters(patterns, context);
|
|
|
|
|
RewritePatternMatcher matcher(std::move(patterns));
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
|
|
|
|
SmallVector<Function *, 0> originalFuncs, convertedFuncs;
|
|
|
|
|
DenseMap<Attribute, FunctionAttr> functionAttrRemapping;
|
|
|
|
|
originalFuncs.reserve(module->getFunctions().size());
|
|
|
|
|
for (auto &func : *module)
|
|
|
|
|
originalFuncs.push_back(&func);
|
2019-05-19 17:56:32 -07:00
|
|
|
convertedFuncs.reserve(originalFuncs.size());
|
|
|
|
|
|
|
|
|
|
// Convert each function.
|
|
|
|
|
FunctionConverter converter(context, this, matcher);
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
for (auto *func : originalFuncs) {
|
2019-05-19 17:56:32 -07:00
|
|
|
Function *converted = converter.convertFunction(func);
|
|
|
|
|
if (!converted) {
|
|
|
|
|
// Make sure to erase any previously converted functions.
|
|
|
|
|
while (!convertedFuncs.empty())
|
|
|
|
|
convertedFuncs.pop_back_val()->erase();
|
2019-03-10 15:32:54 -07:00
|
|
|
return failure();
|
2019-05-19 17:56:32 -07:00
|
|
|
}
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
convertedFuncs.push_back(converted);
|
2019-05-06 12:40:43 -07:00
|
|
|
auto origFuncAttr = FunctionAttr::get(func);
|
|
|
|
|
auto convertedFuncAttr = FunctionAttr::get(converted);
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
functionAttrRemapping.insert({origFuncAttr, convertedFuncAttr});
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Remap function attributes in the converted functions. Original functions
|
|
|
|
|
// will disappear anyway so there is no need to remap attributes in them.
|
2019-05-17 22:21:13 -07:00
|
|
|
for (const auto &funcPair : functionAttrRemapping)
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
remapFunctionAttrs(*funcPair.getSecond().getValue(), functionAttrRemapping);
|
|
|
|
|
|
2019-05-19 17:56:32 -07:00
|
|
|
// Remove the original functions from the module and update the names of the
|
|
|
|
|
// converted functions.
|
|
|
|
|
for (unsigned i = 0, e = originalFuncs.size(); i != e; ++i) {
|
|
|
|
|
convertedFuncs[i]->takeName(*originalFuncs[i]);
|
|
|
|
|
originalFuncs[i]->erase();
|
|
|
|
|
}
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
|
2019-03-10 15:32:54 -07:00
|
|
|
return success();
|
Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.
It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.
The latter two things required, given the existing API, to create new functions
in the same module. Eventually, this should converge with the rest of
PatternRewriter. However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.
This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function. Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks. The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks. The patterns are defined as
separate classes that can be table-generated in the future.
The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion. It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen. The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows. Future
patches will add missing support before switching the translator in a single
patch.
PiperOrigin-RevId: 230951202
2019-01-25 12:46:53 -08:00
|
|
|
}
|