@@ -271,37 +271,41 @@ getUnderlyingObjectSet(Value pointerValue) {
271
271
static void createNewAliasScopesFromNoAliasParameter (
272
272
Operation *call, iterator_range<Region::iterator> inlinedBlocks) {
273
273
274
- // First collect all noalias parameters. These have been specially marked by
275
- // the `handleArgument` implementation by using the `ssa.copy` intrinsic and
276
- // attaching a `noalias` attribute to it.
277
- // These are only meant to be temporary and should therefore be deleted after
278
- // we're done using them here.
274
+ // First, collect all ssa copy operations, which correspond to function
275
+ // parameters, and additionally store the noalias parameters. All parameters
276
+ // have been marked by the `handleArgument` implementation by using the
277
+ // `ssa.copy` intrinsic. Additionally, noalias parameters have an attached
278
+ // `noalias` attribute to the intrinsics. These intrinsics are only meant to
279
+ // be temporary and should therefore be deleted after we're done using them
280
+ // here.
281
+ SetVector<LLVM::SSACopyOp> ssaCopies;
279
282
SetVector<LLVM::SSACopyOp> noAliasParams;
280
283
for (Value argument : cast<LLVM::CallOp>(call).getArgOperands ()) {
281
284
for (Operation *user : argument.getUsers ()) {
282
285
auto ssaCopy = llvm::dyn_cast<LLVM::SSACopyOp>(user);
283
286
if (!ssaCopy)
284
287
continue ;
288
+ ssaCopies.insert (ssaCopy);
289
+
285
290
if (!ssaCopy->hasAttr (LLVM::LLVMDialect::getNoAliasAttrName ()))
286
291
continue ;
287
-
288
292
noAliasParams.insert (ssaCopy);
289
293
}
290
294
}
291
295
292
- // If there were none, we have nothing to do here.
293
- if (noAliasParams.empty ())
294
- return ;
295
-
296
296
// Scope exit block to make it impossible to forget to get rid of the
297
297
// intrinsics.
298
298
auto exit = llvm::make_scope_exit ([&] {
299
- for (LLVM::SSACopyOp ssaCopyOp : noAliasParams ) {
299
+ for (LLVM::SSACopyOp ssaCopyOp : ssaCopies ) {
300
300
ssaCopyOp.replaceAllUsesWith (ssaCopyOp.getOperand ());
301
301
ssaCopyOp->erase ();
302
302
}
303
303
});
304
304
305
+ // If there were no noalias parameters, we have nothing to do here.
306
+ if (noAliasParams.empty ())
307
+ return ;
308
+
305
309
// Create a new domain for this specific inlining and a new scope for every
306
310
// noalias parameter.
307
311
auto functionDomain = LLVM::AliasScopeDomainAttr::get (
@@ -335,7 +339,7 @@ static void createNewAliasScopesFromNoAliasParameter(
335
339
bool aliasesOtherKnownObject = false ;
336
340
// Go through the based on pointers and check that they are either:
337
341
// * Constants that can be ignored (undef, poison, null pointer).
338
- // * Based on a noalias parameter.
342
+ // * Based on a pointer parameter.
339
343
// * Other pointers that we know can't alias with our noalias parameter.
340
344
//
341
345
// Any other value might be a pointer based on any noalias parameter that
@@ -346,11 +350,13 @@ static void createNewAliasScopesFromNoAliasParameter(
346
350
if (matchPattern (object, m_Constant ()))
347
351
return false ;
348
352
349
- if (noAliasParams.contains (object.getDefiningOp <LLVM::SSACopyOp>()))
353
+ if (auto ssaCopy = object.getDefiningOp <LLVM::SSACopyOp>()) {
354
+ // If that value is based on a noalias parameter, it is guaranteed
355
+ // to not alias with any other object.
356
+ aliasesOtherKnownObject |= !noAliasParams.contains (ssaCopy);
350
357
return false ;
358
+ }
351
359
352
- // TODO: This should include other arguments from the inlined
353
- // callable.
354
360
if (isa_and_nonnull<LLVM::AllocaOp, LLVM::AddressOfOp>(
355
361
object.getDefiningOp ())) {
356
362
aliasesOtherKnownObject = true ;
@@ -773,29 +779,25 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
773
779
return handleByValArgument (builder, callable, argument, elementType,
774
780
requestedAlignment);
775
781
}
776
- if (argumentAttrs.contains (LLVM::LLVMDialect::getNoAliasAttrName ())) {
777
- if (argument.use_empty ())
778
- return argument;
779
-
780
- // This code is essentially a workaround for deficiencies in the
781
- // inliner interface: We need to transform operations *after* inlined
782
- // based on the argument attributes of the parameters *before* inlining.
783
- // This method runs prior to actual inlining and thus cannot transform the
784
- // post-inlining code, while `processInlinedCallBlocks` does not have
785
- // access to pre-inlining function arguments. Additionally, it is required
786
- // to distinguish which parameter an SSA value originally came from.
787
- // As a workaround until this is changed: Create an ssa.copy intrinsic
788
- // with the noalias attribute that can easily be found, and is extremely
789
- // unlikely to exist in the code prior to inlining, using this to
790
- // communicate between this method and `processInlinedCallBlocks`.
791
- // TODO: Fix this by refactoring the inliner interface.
792
- auto copyOp = builder.create <LLVM::SSACopyOp>(call->getLoc (), argument);
782
+
783
+ // This code is essentially a workaround for deficiencies in the inliner
784
+ // interface: We need to transform operations *after* inlined based on the
785
+ // argument attributes of the parameters *before* inlining. This method runs
786
+ // prior to actual inlining and thus cannot transform the post-inlining
787
+ // code, while `processInlinedCallBlocks` does not have access to
788
+ // pre-inlining function arguments. Additionally, it is required to
789
+ // distinguish which parameter an SSA value originally came from. As a
790
+ // workaround until this is changed: Create an ssa.copy intrinsic with the
791
+ // noalias attribute (when it was present before) that can easily be found,
792
+ // and is extremely unlikely to exist in the code prior to inlining, using
793
+ // this to communicate between this method and `processInlinedCallBlocks`.
794
+ // TODO: Fix this by refactoring the inliner interface.
795
+ auto copyOp = builder.create <LLVM::SSACopyOp>(call->getLoc (), argument);
796
+ if (argumentAttrs.contains (LLVM::LLVMDialect::getNoAliasAttrName ()))
793
797
copyOp->setDiscardableAttr (
794
798
builder.getStringAttr (LLVM::LLVMDialect::getNoAliasAttrName ()),
795
799
builder.getUnitAttr ());
796
- return copyOp;
797
- }
798
- return argument;
800
+ return copyOp;
799
801
}
800
802
801
803
void processInlinedCallBlocks (
0 commit comments