Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/Dialect/Transforms/HoistAllocas.cpp
213845 views
1
//===----------------------------------------------------------------------===//
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
#include "PassDetail.h"
10
#include "mlir/Dialect/Func/IR/FuncOps.h"
11
#include "mlir/IR/PatternMatch.h"
12
#include "mlir/Support/LogicalResult.h"
13
#include "mlir/Transforms/DialectConversion.h"
14
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
15
#include "clang/CIR/Dialect/IR/CIRDialect.h"
16
#include "clang/CIR/Dialect/Passes.h"
17
#include "clang/CIR/MissingFeatures.h"
18
#include "llvm/Support/TimeProfiler.h"
19
20
using namespace mlir;
21
using namespace cir;
22
23
namespace {
24
25
struct HoistAllocasPass : public HoistAllocasBase<HoistAllocasPass> {
26
27
HoistAllocasPass() = default;
28
void runOnOperation() override;
29
};
30
31
static void process(mlir::ModuleOp mod, cir::FuncOp func) {
32
if (func.getRegion().empty())
33
return;
34
35
// Hoist all static allocas to the entry block.
36
mlir::Block &entryBlock = func.getRegion().front();
37
mlir::Operation *insertPoint = &*entryBlock.begin();
38
39
// Post-order is the default, but the code below requires it, so
40
// let's not depend on the default staying that way.
41
func.getBody().walk<mlir::WalkOrder::PostOrder>([&](cir::AllocaOp alloca) {
42
if (alloca->getBlock() == &entryBlock)
43
return;
44
// Don't hoist allocas with dynamic alloca size.
45
assert(!cir::MissingFeatures::opAllocaDynAllocSize());
46
47
// Hoist allocas into the entry block.
48
49
// Preserving the `const` attribute on hoisted allocas can cause LLVM to
50
// incorrectly introduce invariant group metadata in some circumstances.
51
// The incubator performs some analysis to determine whether the attribute
52
// can be preserved, but it only runs this analysis when optimizations are
53
// enabled. Until we start tracking the optimization level, we can just
54
// always remove the `const` attribute.
55
assert(!cir::MissingFeatures::optInfoAttr());
56
if (alloca.getConstant())
57
alloca.setConstant(false);
58
59
alloca->moveBefore(insertPoint);
60
});
61
}
62
63
void HoistAllocasPass::runOnOperation() {
64
llvm::TimeTraceScope scope("Hoist Allocas");
65
llvm::SmallVector<Operation *, 16> ops;
66
67
Operation *op = getOperation();
68
auto mod = mlir::dyn_cast<mlir::ModuleOp>(op);
69
if (!mod)
70
mod = op->getParentOfType<mlir::ModuleOp>();
71
72
// If we ever introduce nested cir.function ops, we'll need to make this
73
// walk in post-order and recurse into nested functions.
74
getOperation()->walk<mlir::WalkOrder::PreOrder>([&](cir::FuncOp op) {
75
process(mod, op);
76
return mlir::WalkResult::skip();
77
});
78
}
79
80
} // namespace
81
82
std::unique_ptr<Pass> mlir::createHoistAllocasPass() {
83
return std::make_unique<HoistAllocasPass>();
84
}
85
86