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/IR/CIRMemorySlot.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
// This file implements MemorySlot-related interfaces for CIR dialect
10
// operations.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/CIR/Dialect/IR/CIRDialect.h"
15
16
using namespace mlir;
17
18
/// Conditions the deletion of the operation to the removal of all its uses.
19
static bool forwardToUsers(Operation *op,
20
SmallVectorImpl<OpOperand *> &newBlockingUses) {
21
for (Value result : op->getResults())
22
for (OpOperand &use : result.getUses())
23
newBlockingUses.push_back(&use);
24
return true;
25
}
26
27
//===----------------------------------------------------------------------===//
28
// Interfaces for AllocaOp
29
//===----------------------------------------------------------------------===//
30
31
llvm::SmallVector<MemorySlot> cir::AllocaOp::getPromotableSlots() {
32
return {MemorySlot{getResult(), getAllocaType()}};
33
}
34
35
Value cir::AllocaOp::getDefaultValue(const MemorySlot &slot,
36
OpBuilder &builder) {
37
return builder.create<cir::ConstantOp>(getLoc(),
38
cir::UndefAttr::get(slot.elemType));
39
}
40
41
void cir::AllocaOp::handleBlockArgument(const MemorySlot &slot,
42
BlockArgument argument,
43
OpBuilder &builder) {}
44
45
std::optional<PromotableAllocationOpInterface>
46
cir::AllocaOp::handlePromotionComplete(const MemorySlot &slot,
47
Value defaultValue, OpBuilder &builder) {
48
if (defaultValue && defaultValue.use_empty())
49
defaultValue.getDefiningOp()->erase();
50
this->erase();
51
return std::nullopt;
52
}
53
54
//===----------------------------------------------------------------------===//
55
// Interfaces for LoadOp
56
//===----------------------------------------------------------------------===//
57
58
bool cir::LoadOp::loadsFrom(const MemorySlot &slot) {
59
return getAddr() == slot.ptr;
60
}
61
62
bool cir::LoadOp::storesTo(const MemorySlot &slot) { return false; }
63
64
Value cir::LoadOp::getStored(const MemorySlot &slot, OpBuilder &builder,
65
Value reachingDef, const DataLayout &dataLayout) {
66
llvm_unreachable("getStored should not be called on LoadOp");
67
}
68
69
bool cir::LoadOp::canUsesBeRemoved(
70
const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
71
SmallVectorImpl<OpOperand *> &newBlockingUses,
72
const DataLayout &dataLayout) {
73
if (blockingUses.size() != 1)
74
return false;
75
Value blockingUse = (*blockingUses.begin())->get();
76
return blockingUse == slot.ptr && getAddr() == slot.ptr &&
77
getType() == slot.elemType;
78
}
79
80
DeletionKind cir::LoadOp::removeBlockingUses(
81
const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
82
OpBuilder &builder, Value reachingDefinition,
83
const DataLayout &dataLayout) {
84
getResult().replaceAllUsesWith(reachingDefinition);
85
return DeletionKind::Delete;
86
}
87
88
//===----------------------------------------------------------------------===//
89
// Interfaces for StoreOp
90
//===----------------------------------------------------------------------===//
91
92
bool cir::StoreOp::loadsFrom(const MemorySlot &slot) { return false; }
93
94
bool cir::StoreOp::storesTo(const MemorySlot &slot) {
95
return getAddr() == slot.ptr;
96
}
97
98
Value cir::StoreOp::getStored(const MemorySlot &slot, OpBuilder &builder,
99
Value reachingDef, const DataLayout &dataLayout) {
100
return getValue();
101
}
102
103
bool cir::StoreOp::canUsesBeRemoved(
104
const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
105
SmallVectorImpl<OpOperand *> &newBlockingUses,
106
const DataLayout &dataLayout) {
107
if (blockingUses.size() != 1)
108
return false;
109
Value blockingUse = (*blockingUses.begin())->get();
110
return blockingUse == slot.ptr && getAddr() == slot.ptr &&
111
getValue() != slot.ptr && slot.elemType == getValue().getType();
112
}
113
114
DeletionKind cir::StoreOp::removeBlockingUses(
115
const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
116
OpBuilder &builder, Value reachingDefinition,
117
const DataLayout &dataLayout) {
118
return DeletionKind::Delete;
119
}
120
121
//===----------------------------------------------------------------------===//
122
// Interfaces for CastOp
123
//===----------------------------------------------------------------------===//
124
125
bool cir::CastOp::canUsesBeRemoved(
126
const SmallPtrSetImpl<OpOperand *> &blockingUses,
127
SmallVectorImpl<OpOperand *> &newBlockingUses,
128
const DataLayout &dataLayout) {
129
if (getKind() == cir::CastKind::bitcast)
130
return forwardToUsers(*this, newBlockingUses);
131
return false;
132
}
133
134
DeletionKind cir::CastOp::removeBlockingUses(
135
const SmallPtrSetImpl<OpOperand *> &blockingUses, OpBuilder &builder) {
136
return DeletionKind::Delete;
137
}
138
139