38static bool isCaptured(Value v, Operation *potentialUser =
nullptr,
39 bool *seenuse =
nullptr) {
40 SmallVector<Value> todo = {v};
42 Value v = todo.pop_back_val();
43 for (
auto u : v.getUsers()) {
44 if (seenuse && u == potentialUser)
46 if (isa<memref::LoadOp, LLVM::LoadOp, affine::AffineLoadOp>(u))
48 if (
auto s = dyn_cast<memref::StoreOp>(u)) {
49 if (s.getValue() == v)
53 if (
auto s = dyn_cast<affine::AffineStoreOp>(u)) {
54 if (s.getValue() == v)
58 if (
auto s = dyn_cast<LLVM::StoreOp>(u)) {
59 if (s.getValue() == v)
63 if (
auto sub = dyn_cast<LLVM::GEPOp>(u)) {
66 if (
auto sub = dyn_cast<LLVM::BitcastOp>(u)) {
69 if (
auto sub = dyn_cast<LLVM::AddrSpaceCastOp>(u)) {
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::CastOp>(u)) {
87 if (
auto sub = dyn_cast<memref::DeallocOp>(u)) {
90 if (
auto cop = dyn_cast<LLVM::CallOp>(u)) {
91 if (
auto callee = cop.getCallee()) {
96 if (
auto cop = dyn_cast<func::CallOp>(u)) {
144 if (
auto glob = v1.getDefiningOp<memref::GetGlobalOp>()) {
145 if (
auto Aglob = v2.getDefiningOp<memref::GetGlobalOp>()) {
146 return glob.getName() == Aglob.getName();
150 if (
auto glob = v1.getDefiningOp<LLVM::AddressOfOp>()) {
151 if (
auto Aglob = v2.getDefiningOp<LLVM::AddressOfOp>()) {
152 return glob.getGlobalName() == Aglob.getGlobalName();
160 isGlobal[0] = v1.getDefiningOp<memref::GetGlobalOp>() ||
161 v1.getDefiningOp<LLVM::AddressOfOp>();
165 isGlobal[1] = v2.getDefiningOp<memref::GetGlobalOp>() ||
166 v2.getDefiningOp<LLVM::AddressOfOp>();
169 if ((isAlloca[0] || isGlobal[0]) && (isAlloca[1] || isGlobal[1]))
172 BlockArgument barg1 = dyn_cast<BlockArgument>(v1);
173 BlockArgument barg2 = dyn_cast<BlockArgument>(v2);
175 FunctionOpInterface f1 =
176 barg1 ? dyn_cast<FunctionOpInterface>(barg1.getOwner()->getParentOp())
178 FunctionOpInterface f2 =
179 barg2 ? dyn_cast<FunctionOpInterface>(barg2.getOwner()->getParentOp())
183 f1 ? !!f1.getArgAttr(barg1.getArgNumber(),
184 LLVM::LLVMDialect::getNoAliasAttrName())
187 f2 ? !!f2.getArgAttr(barg2.getArgNumber(),
188 LLVM::LLVMDialect::getNoAliasAttrName())
201 if ((isAlloca[0] && isArg[1]) || (isAlloca[1] && isArg[0]))
240 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
242 SmallVector<MemoryEffects::EffectInstance, 1> effects;
243 effectInterface.getEffects(effects);
244 if (!llvm::all_of(effects, [op](
const MemoryEffects::EffectInstance &it) {
245 return isa<MemoryEffects::Read>(it.getEffect());
251 bool isRecursiveContainer =
252 op->hasTrait<OpTrait::HasRecursiveMemoryEffects>();
253 if (isRecursiveContainer) {
254 for (Region ®ion : op->getRegions()) {
255 for (
auto &block : region) {
256 for (
auto &nestedOp : block)
267 bool hasRecursiveEffects = op->hasTrait<OpTrait::HasRecursiveMemoryEffects>();
268 if (hasRecursiveEffects) {
269 for (Region ®ion : op->getRegions()) {
270 for (
auto &block : region) {
271 for (
auto &nestedOp : block)
281 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
284 SmallVector<MemoryEffects::EffectInstance, 1> effects;
285 effectInterface.getEffects(effects);
286 if (llvm::any_of(effects, [](
const MemoryEffects::EffectInstance &it) {
287 return isa<MemoryEffects::Read>(it.getEffect()) ||
288 isa<MemoryEffects::Write>(it.getEffect());
298 SmallVector<MemoryEffects::EffectInstance> &effects) {
299 SmallVector<Operation *> effectingOps(1, rootOp);
300 bool couldCollectEffects =
true;
302 while (!effectingOps.empty()) {
303 Operation *op = effectingOps.pop_back_val();
304 bool isRecursiveContainer =
305 op->hasTrait<OpTrait::HasRecursiveMemoryEffects>();
307 if (isRecursiveContainer) {
308 for (Region ®ion : op->getRegions()) {
309 for (Block &block : region) {
310 for (Operation &nestedOp : block) {
311 effectingOps.push_back(&nestedOp);
317 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
318 SmallVector<MemoryEffects::EffectInstance> localEffects;
319 effectInterface.getEffects(localEffects);
320 llvm::append_range(effects, localEffects);
321 }
else if (!isRecursiveContainer) {
326 if (
auto cop = dyn_cast<LLVM::CallOp>(op)) {
327 if (
auto callee = cop.getCallee()) {
328 if (*callee ==
"scanf" || *callee ==
"__isoc99_scanf") {
330 effects.emplace_back(
331 MemoryEffects::Effect::get<MemoryEffects::Read>());
334 for (
auto &arg : cop.getArgOperandsMutable()) {
336 effects.emplace_back(MemoryEffects::Read::get(), &arg);
338 effects.emplace_back(MemoryEffects::Write::get(), &arg,
339 SideEffects::DefaultResource::get());
343 if (*callee ==
"fscanf" || *callee ==
"__isoc99_fscanf") {
345 effects.emplace_back(
346 MemoryEffects::Effect::get<MemoryEffects::Read>());
348 for (
auto &&[idx, arg] :
349 llvm::enumerate(cop.getArgOperandsMutable())) {
351 effects.emplace_back(MemoryEffects::Read::get(), &arg,
352 SideEffects::DefaultResource::get());
353 effects.emplace_back(MemoryEffects::Write::get(), &arg,
354 SideEffects::DefaultResource::get());
355 }
else if (idx == 1) {
356 effects.emplace_back(MemoryEffects::Read::get(), &arg,
357 SideEffects::DefaultResource::get());
359 effects.emplace_back(MemoryEffects::Write::get(), &arg,
360 SideEffects::DefaultResource::get());
363 if (*callee ==
"printf") {
365 effects.emplace_back(
366 MemoryEffects::Effect::get<MemoryEffects::Write>());
367 for (
auto &arg : cop.getArgOperandsMutable()) {
368 effects.emplace_back(MemoryEffects::Read::get(), &arg,
369 SideEffects::DefaultResource::get());
372 if (*callee ==
"free") {
373 for (
auto &arg : cop.getArgOperandsMutable()) {
374 effects.emplace_back(MemoryEffects::Free::get(), &arg,
375 SideEffects::DefaultResource::get());
378 if (*callee ==
"strlen") {
379 for (
auto &arg : cop.getArgOperandsMutable()) {
380 effects.emplace_back(MemoryEffects::Read::get(), &arg,
381 SideEffects::DefaultResource::get());
392 effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Read>());
393 effects.emplace_back(
394 MemoryEffects::Effect::get<MemoryEffects::Write>());
395 effects.emplace_back(
396 MemoryEffects::Effect::get<MemoryEffects::Allocate>());
397 effects.emplace_back(MemoryEffects::Effect::get<MemoryEffects::Free>());
398 couldCollectEffects =
false;
405 return couldCollectEffects;
423 MemoryEffects::Effect *effect,
424 SideEffects::Resource *resource) {
426 if (
auto valOR = dyn_cast<OpResult>(val))
427 return MemoryEffects::EffectInstance(effect, valOR, resource);
428 else if (
auto valBA = dyn_cast<BlockArgument>(val)) {
429 return MemoryEffects::EffectInstance(effect, valBA, resource);
431 llvm_unreachable(
"Provided Value is neither an argument nor a result of an "
432 "op. This is not allowed by SSA");