42bool isCaptured(Value v, Operation *potentialUser,
bool *seenuse) {
43 SmallVector<Value> todo = {v};
45 Value v = todo.pop_back_val();
46 for (
auto u : v.getUsers()) {
47 if (seenuse && u == potentialUser)
49 if (isa<memref::LoadOp, LLVM::LoadOp, affine::AffineLoadOp>(u))
51 if (
auto s = dyn_cast<memref::StoreOp>(u)) {
52 if (s.getValue() == v)
56 if (
auto s = dyn_cast<affine::AffineStoreOp>(u)) {
57 if (s.getValue() == v)
61 if (
auto s = dyn_cast<LLVM::StoreOp>(u)) {
62 if (s.getValue() == v)
66 if (
auto view = dyn_cast<ViewLikeOpInterface>(u)) {
67 if (view.getViewSource() == v) {
68 todo.push_back(view.getViewDest());
72 if (
auto sub = dyn_cast<func::ReturnOp>(u)) {
75 if (
auto sub = dyn_cast<LLVM::MemsetOp>(u)) {
78 if (
auto sub = dyn_cast<LLVM::MemcpyOp>(u)) {
81 if (
auto sub = dyn_cast<LLVM::MemmoveOp>(u)) {
84 if (
auto sub = dyn_cast<memref::DeallocOp>(u)) {
87 if (
auto cop = dyn_cast<LLVM::CallOp>(u)) {
88 if (
auto callee = cop.getCallee()) {
93 if (
auto cop = dyn_cast<func::CallOp>(u)) {
153 if (
auto glob = v1.getDefiningOp<memref::GetGlobalOp>()) {
154 if (
auto Aglob = v2.getDefiningOp<memref::GetGlobalOp>()) {
155 return glob.getName() == Aglob.getName();
159 if (
auto glob = v1.getDefiningOp<LLVM::AddressOfOp>()) {
160 if (
auto Aglob = v2.getDefiningOp<LLVM::AddressOfOp>()) {
161 return glob.getGlobalName() == Aglob.getGlobalName();
169 isGlobal[0] = v1.getDefiningOp<memref::GetGlobalOp>() ||
170 v1.getDefiningOp<LLVM::AddressOfOp>();
174 isGlobal[1] = v2.getDefiningOp<memref::GetGlobalOp>() ||
175 v2.getDefiningOp<LLVM::AddressOfOp>();
178 if ((isAlloca[0] || isGlobal[0]) && (isAlloca[1] || isGlobal[1]))
181 BlockArgument barg1 = dyn_cast<BlockArgument>(v1);
182 BlockArgument barg2 = dyn_cast<BlockArgument>(v2);
184 FunctionOpInterface f1 =
185 barg1 ? dyn_cast<FunctionOpInterface>(barg1.getOwner()->getParentOp())
187 FunctionOpInterface f2 =
188 barg2 ? dyn_cast<FunctionOpInterface>(barg2.getOwner()->getParentOp())
192 f1 ? !!f1.getArgAttr(barg1.getArgNumber(),
193 LLVM::LLVMDialect::getNoAliasAttrName())
196 f2 ? !!f2.getArgAttr(barg2.getArgNumber(),
197 LLVM::LLVMDialect::getNoAliasAttrName())
210 if ((isAlloca[0] && isArg[1]) || (isAlloca[1] && isArg[0]))
249 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
251 SmallVector<MemoryEffects::EffectInstance, 1> effects;
252 effectInterface.getEffects(effects);
253 if (!llvm::all_of(effects, [](
const MemoryEffects::EffectInstance &it) {
254 return isa<MemoryEffects::Read>(it.getEffect());
260 bool isRecursiveContainer =
261 op->hasTrait<OpTrait::HasRecursiveMemoryEffects>();
262 if (isRecursiveContainer) {
263 for (Region ®ion : op->getRegions()) {
264 for (
auto &block : region) {
265 for (
auto &nestedOp : block)
276 bool hasRecursiveEffects = op->hasTrait<OpTrait::HasRecursiveMemoryEffects>();
277 if (hasRecursiveEffects) {
278 for (Region ®ion : op->getRegions()) {
279 for (
auto &block : region) {
280 for (
auto &nestedOp : block)
290 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
293 SmallVector<MemoryEffects::EffectInstance, 1> effects;
294 effectInterface.getEffects(effects);
295 if (llvm::any_of(effects, [](
const MemoryEffects::EffectInstance &it) {
296 return isa<MemoryEffects::Read>(it.getEffect()) ||
297 isa<MemoryEffects::Write>(it.getEffect());
307 SmallVector<MemoryEffects::EffectInstance> &effects) {
308 SmallVector<Operation *> effectingOps(1, rootOp);
309 bool couldCollectEffects =
true;
311 while (!effectingOps.empty()) {
312 Operation *op = effectingOps.pop_back_val();
313 bool isRecursiveContainer =
314 op->hasTrait<OpTrait::HasRecursiveMemoryEffects>();
316 if (isRecursiveContainer) {
317 for (Region ®ion : op->getRegions()) {
318 for (Block &block : region) {
319 for (Operation &nestedOp : block) {
320 effectingOps.push_back(&nestedOp);
326 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
327 SmallVector<MemoryEffects::EffectInstance> localEffects;
328 effectInterface.getEffects(localEffects);
329 llvm::append_range(effects, localEffects);
330 }
else if (!isRecursiveContainer) {
335 if (
auto cop = dyn_cast<LLVM::CallOp>(op)) {
336 if (
auto callee = cop.getCallee()) {
337 if (*callee ==
"scanf" || *callee ==
"__isoc99_scanf") {
339 effects.emplace_back(
340 MemoryEffects::Effect::get<MemoryEffects::Read>());
343 for (
auto &arg : cop.getArgOperandsMutable()) {
345 effects.emplace_back(MemoryEffects::Read::get(), &arg);
347 effects.emplace_back(MemoryEffects::Write::get(), &arg,
348 SideEffects::DefaultResource::get());
352 if (*callee ==
"fscanf" || *callee ==
"__isoc99_fscanf") {
354 effects.emplace_back(
355 MemoryEffects::Effect::get<MemoryEffects::Read>());
357 for (
auto &&[idx, arg] :
358 llvm::enumerate(cop.getArgOperandsMutable())) {
360 effects.emplace_back(MemoryEffects::Read::get(), &arg,
361 SideEffects::DefaultResource::get());
362 effects.emplace_back(MemoryEffects::Write::get(), &arg,
363 SideEffects::DefaultResource::get());
364 }
else if (idx == 1) {
365 effects.emplace_back(MemoryEffects::Read::get(), &arg,
366 SideEffects::DefaultResource::get());
368 effects.emplace_back(MemoryEffects::Write::get(), &arg,
369 SideEffects::DefaultResource::get());
372 if (*callee ==
"printf") {
374 effects.emplace_back(
375 MemoryEffects::Effect::get<MemoryEffects::Write>());
376 for (
auto &arg : cop.getArgOperandsMutable()) {
377 effects.emplace_back(MemoryEffects::Read::get(), &arg,
378 SideEffects::DefaultResource::get());
381 if (*callee ==
"free") {
382 for (
auto &arg : cop.getArgOperandsMutable()) {
383 effects.emplace_back(MemoryEffects::Free::get(), &arg,
384 SideEffects::DefaultResource::get());
387 if (*callee ==
"strlen") {
388 for (
auto &arg : cop.getArgOperandsMutable()) {
389 effects.emplace_back(MemoryEffects::Read::get(), &arg,
390 SideEffects::DefaultResource::get());
401 effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Read>());
402 effects.emplace_back(
403 MemoryEffects::Effect::get<MemoryEffects::Write>());
404 effects.emplace_back(
405 MemoryEffects::Effect::get<MemoryEffects::Allocate>());
406 effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Free>());
407 couldCollectEffects =
false;
414 return couldCollectEffects;
432 MemoryEffects::Effect *effect,
433 SideEffects::Resource *resource) {
435 if (
auto valOR = dyn_cast<OpResult>(val))
436 return MemoryEffects::EffectInstance(effect, valOR, resource);
437 else if (
auto valBA = dyn_cast<BlockArgument>(val)) {
438 return MemoryEffects::EffectInstance(effect, valBA, resource);
440 llvm_unreachable(
"Provided Value is neither an argument nor a result of an "
441 "op. This is not allowed by SSA");