Skip to content

Commit 42cb0d2

Browse files
author
Leon Clark
committed
[AMDGPU] Propagate alias information in AMDGPULowerKernelArguments.
This patch reimplements https://reviews.llvm.org/D108363 and https://reviews.llvm.org/D108361 to emit !noalias and !alias.scope metadata for noalias kernel arguments.
1 parent 66580f7 commit 42cb0d2

File tree

12 files changed

+2460
-1286
lines changed

12 files changed

+2460
-1286
lines changed

llvm/include/llvm/Transforms/Utils/Cloning.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,17 @@ LLVM_ABI void updateProfileCallee(
363363
Function *Callee, int64_t EntryDelta,
364364
const ValueMap<const Value *, WeakTrackingVH> *VMap = nullptr);
365365

366+
/// Adds `!noalias` and `!alias.scope` metadata for `CB`'s called function's
367+
/// `noalias` argument based memory accesses.
368+
void addAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
369+
const DataLayout &DL, AAResults *CalleeAAR,
370+
ClonedCodeInfo &InlinedFunctionInfo,
371+
bool UseNoAliasIntrinsic);
372+
373+
/// Adds `!noalias` and `!alias.scope` metadata for `F`'s `noalias` argument
374+
/// based memory accesses.
375+
void addAliasScopeMetadata(Function &F);
376+
366377
/// Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified
367378
/// basic blocks and extract their scope. These are candidates for duplication
368379
/// when cloning.

llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/IR/IntrinsicsAMDGPU.h"
2121
#include "llvm/IR/MDBuilder.h"
2222
#include "llvm/Target/TargetMachine.h"
23+
#include "llvm/Transforms/Utils/Cloning.h"
2324

2425
#define DEBUG_TYPE "amdgpu-lower-kernel-arguments"
2526

@@ -86,6 +87,9 @@ static bool lowerKernelArguments(Function &F, const TargetMachine &TM) {
8687
Attribute::getWithDereferenceableBytes(Ctx, TotalKernArgSize));
8788

8889
uint64_t ExplicitArgOffset = 0;
90+
91+
addAliasScopeMetadata(F);
92+
8993
for (Argument &Arg : F.args()) {
9094
const bool IsByRef = Arg.hasByRefAttr();
9195
Type *ArgTy = IsByRef ? Arg.getParamByRefType() : Arg.getType();
@@ -124,11 +128,6 @@ static bool lowerKernelArguments(Function &F, const TargetMachine &TM) {
124128
PT->getAddressSpace() == AMDGPUAS::REGION_ADDRESS) &&
125129
!ST.hasUsableDSOffset())
126130
continue;
127-
128-
// FIXME: We can replace this with equivalent alias.scope/noalias
129-
// metadata, but this appears to be a lot of work.
130-
if (Arg.hasNoAliasAttr())
131-
continue;
132131
}
133132

134133
auto *VT = dyn_cast<FixedVectorType>(ArgTy);
@@ -215,8 +214,6 @@ static bool lowerKernelArguments(Function &F, const TargetMachine &TM) {
215214
}
216215
}
217216

218-
// TODO: Convert noalias arg to !noalias
219-
220217
if (DoShiftOpt) {
221218
Value *ExtractBits = OffsetDiff == 0 ?
222219
Load : Builder.CreateLShr(Load, OffsetDiff * 8);

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "llvm/IR/GlobalVariable.h"
5252
#include "llvm/IR/IRBuilder.h"
5353
#include "llvm/IR/InlineAsm.h"
54+
#include "llvm/IR/InstIterator.h"
5455
#include "llvm/IR/InstrTypes.h"
5556
#include "llvm/IR/Instruction.h"
5657
#include "llvm/IR/Instructions.h"
@@ -1114,17 +1115,30 @@ void ScopedAliasMetadataDeepCloner::remap(Function::iterator FStart,
11141115
/// then add new alias scopes for each noalias argument, tag the mapped noalias
11151116
/// parameters with noalias metadata specifying the new scope, and tag all
11161117
/// non-derived loads, stores and memory intrinsics with the new alias scopes.
1117-
static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
1118-
const DataLayout &DL, AAResults *CalleeAAR,
1119-
ClonedCodeInfo &InlinedFunctionInfo) {
1120-
if (!EnableNoAliasConversion)
1121-
return;
1122-
1123-
const Function *CalledFunc = CB.getCalledFunction();
1118+
static void addAliasScopeMetadataImpl(CallBase *CB, Function *F,
1119+
ValueToValueMapTy *VMap,
1120+
const DataLayout &DL,
1121+
AAResults *CalleeAAR,
1122+
ClonedCodeInfo *InlinedFunctionInfo,
1123+
bool UseNoAliasIntrinsic) {
1124+
assert(CB || F);
1125+
const Function *CalledFunc = CB ? CB->getCalledFunction() : F;
11241126
SmallVector<const Argument *, 4> NoAliasArgs;
11251127

1128+
std::function<bool(const Argument *, Attribute::AttrKind)> paramHasAttr;
1129+
if (CB) {
1130+
paramHasAttr = [&](const Argument *Arg, Attribute::AttrKind Attr) -> bool {
1131+
return CB->paramHasAttr(Arg->getArgNo(), Attr);
1132+
};
1133+
1134+
} else {
1135+
paramHasAttr = [&](const Argument *Arg, Attribute::AttrKind Attr) -> bool {
1136+
return Arg->hasAttribute(Attr);
1137+
};
1138+
}
1139+
11261140
for (const Argument &Arg : CalledFunc->args())
1127-
if (CB.paramHasAttr(Arg.getArgNo(), Attribute::NoAlias) && !Arg.use_empty())
1141+
if (paramHasAttr(&Arg, Attribute::NoAlias) && !Arg.use_empty())
11281142
NoAliasArgs.push_back(&Arg);
11291143

11301144
if (NoAliasArgs.empty())
@@ -1166,29 +1180,20 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
11661180
NewScopes.insert(std::make_pair(A, NewScope));
11671181

11681182
if (UseNoAliasIntrinsic) {
1183+
assert(CB);
11691184
// Introduce a llvm.experimental.noalias.scope.decl for the noalias
11701185
// argument.
11711186
MDNode *AScopeList = MDNode::get(CalledFunc->getContext(), NewScope);
11721187
auto *NoAliasDecl =
1173-
IRBuilder<>(&CB).CreateNoAliasScopeDeclaration(AScopeList);
1188+
IRBuilder<>(CB).CreateNoAliasScopeDeclaration(AScopeList);
11741189
// Ignore the result for now. The result will be used when the
11751190
// llvm.noalias intrinsic is introduced.
11761191
(void)NoAliasDecl;
11771192
}
11781193
}
11791194

1180-
// Iterate over all new instructions in the map; for all memory-access
1181-
// instructions, add the alias scope metadata.
1182-
for (ValueToValueMapTy::iterator VMI = VMap.begin(), VMIE = VMap.end();
1183-
VMI != VMIE; ++VMI) {
1184-
if (const Instruction *I = dyn_cast<Instruction>(VMI->first)) {
1185-
if (!VMI->second)
1186-
continue;
1187-
1188-
Instruction *NI = dyn_cast<Instruction>(VMI->second);
1189-
if (!NI || InlinedFunctionInfo.isSimplified(I, NI))
1190-
continue;
1191-
1195+
{
1196+
auto addAliasMD = [&](const Instruction *I, Instruction *NI) -> void {
11921197
bool IsArgMemOnlyCall = false, IsFuncCall = false;
11931198
SmallVector<const Value *, 2> PtrArgs;
11941199

@@ -1207,15 +1212,15 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
12071212
// know that about the inlined clone of this call site, and we don't
12081213
// need to add metadata.
12091214
if (Call->doesNotAccessMemory())
1210-
continue;
1215+
return;
12111216

12121217
IsFuncCall = true;
12131218
if (CalleeAAR) {
12141219
MemoryEffects ME = CalleeAAR->getMemoryEffects(Call);
12151220

12161221
// We'll retain this knowledge without additional metadata.
12171222
if (ME.onlyAccessesInaccessibleMem())
1218-
continue;
1223+
return;
12191224

12201225
if (ME.onlyAccessesArgPointees())
12211226
IsArgMemOnlyCall = true;
@@ -1237,7 +1242,7 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
12371242
// However, if this is a call, this we might just alias with none of the
12381243
// noalias arguments.
12391244
if (PtrArgs.empty() && !IsFuncCall)
1240-
continue;
1245+
return;
12411246

12421247
// It is possible that there is only one underlying object, but you
12431248
// need to go through several PHIs to see it, and thus could be
@@ -1270,7 +1275,7 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
12701275
// completely describe the aliasing properties using alias.scope
12711276
// metadata (and, thus, won't add any).
12721277
if (const Argument *A = dyn_cast<Argument>(V)) {
1273-
if (!CB.paramHasAttr(A->getArgNo(), Attribute::NoAlias))
1278+
if (!paramHasAttr(A, Attribute::NoAlias))
12741279
UsesAliasingPtr = true;
12751280
} else {
12761281
UsesAliasingPtr = true;
@@ -1292,7 +1297,7 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
12921297
// Nothing we can do if the used underlying object cannot be reliably
12931298
// determined.
12941299
if (UsesUnknownObject)
1295-
continue;
1300+
return;
12961301

12971302
// A function call can always get captured noalias pointers (via other
12981303
// parameters, globals, etc.).
@@ -1353,10 +1358,49 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
13531358
LLVMContext::MD_alias_scope,
13541359
MDNode::concatenate(NI->getMetadata(LLVMContext::MD_alias_scope),
13551360
MDNode::get(CalledFunc->getContext(), Scopes)));
1361+
};
1362+
1363+
if (VMap) {
1364+
assert(InlinedFunctionInfo);
1365+
1366+
for (ValueToValueMapTy::iterator VMI = VMap->begin(), VMIE = VMap->end();
1367+
VMI != VMIE; ++VMI) {
1368+
const Instruction *I = dyn_cast<Instruction>(VMI->first);
1369+
if (!I || !VMI->second)
1370+
continue;
1371+
1372+
Instruction *NI = dyn_cast<Instruction>(VMI->second);
1373+
if (!NI || InlinedFunctionInfo->isSimplified(I, NI))
1374+
continue;
1375+
1376+
addAliasMD(I, NI);
1377+
}
1378+
1379+
} else {
1380+
for (auto It = inst_begin(F), End = inst_end(F); It != End; ++It) {
1381+
Instruction *I = &(*It);
1382+
addAliasMD(I, I);
1383+
}
13561384
}
13571385
}
13581386
}
13591387

1388+
void llvm::addAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap,
1389+
const DataLayout &DL, AAResults *CalleeAAR,
1390+
ClonedCodeInfo &InlinedFunctionInfo,
1391+
bool UseNoAliasIntrinsic) {
1392+
addAliasScopeMetadataImpl(&CB, /* F */ nullptr, &VMap, DL, CalleeAAR,
1393+
&InlinedFunctionInfo, UseNoAliasIntrinsic);
1394+
}
1395+
1396+
void llvm::addAliasScopeMetadata(Function &F) {
1397+
addAliasScopeMetadataImpl(/* CB */ nullptr, &F, /* VMap */ nullptr,
1398+
F.getParent()->getDataLayout(),
1399+
/* CalleeAAR */ nullptr,
1400+
/* InlinedFunctionInfo */ nullptr,
1401+
/* UseNoAliasIntrinsic */ false);
1402+
}
1403+
13601404
static bool MayContainThrowingOrExitingCallAfterCB(CallBase *Begin,
13611405
ReturnInst *End) {
13621406

@@ -2797,7 +2841,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
27972841
SAMetadataCloner.remap(FirstNewBlock, Caller->end());
27982842

27992843
// Add noalias metadata if necessary.
2800-
AddAliasScopeMetadata(CB, VMap, DL, CalleeAAR, InlinedFunctionInfo);
2844+
if (EnableNoAliasConversion)
2845+
addAliasScopeMetadata(CB, VMap, DL, CalleeAAR, InlinedFunctionInfo,
2846+
UseNoAliasIntrinsic);
28012847

28022848
// Clone return attributes on the callsite into the calls within the inlined
28032849
// function which feed into its return value.

0 commit comments

Comments
 (0)