forked from OSchip/llvm-project
[Inliner] Consistently apply callsite noalias metadata
Previously, !noalias and !alias.scope metadata on the call site was applied as part of CloneAliasScopeMetadata(), which short-circuits if the callee does not use any noalias metadata itself. However, these two things have no relation to each other. Consistently apply !noalias and !alias.scope metadata by integrating this into an existing function that handled !llvm.access.group and !llvm.mem.parallel_loop_access metadata. The handling for all of these metadata kinds essentially the same.
This commit is contained in:
parent
61b1446a9e
commit
27f647d117
|
@ -771,14 +771,16 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock,
|
|||
UnwindDest->removePredecessor(InvokeBB);
|
||||
}
|
||||
|
||||
/// When inlining a call site that has !llvm.mem.parallel_loop_access or
|
||||
/// llvm.access.group metadata, that metadata should be propagated to all
|
||||
/// memory-accessing cloned instructions.
|
||||
static void PropagateParallelLoopAccessMetadata(CallBase &CB,
|
||||
ValueToValueMapTy &VMap) {
|
||||
MDNode *M = CB.getMetadata(LLVMContext::MD_mem_parallel_loop_access);
|
||||
MDNode *CallAccessGroup = CB.getMetadata(LLVMContext::MD_access_group);
|
||||
if (!M && !CallAccessGroup)
|
||||
/// When inlining a call site that has !llvm.mem.parallel_loop_access,
|
||||
/// !llvm.access.group, !alias.scope or !noalias metadata, that metadata should
|
||||
/// be propagated to all memory-accessing cloned instructions.
|
||||
static void PropagateCallSiteMetadata(CallBase &CB, ValueToValueMapTy &VMap) {
|
||||
MDNode *MemParallelLoopAccess =
|
||||
CB.getMetadata(LLVMContext::MD_mem_parallel_loop_access);
|
||||
MDNode *AccessGroup = CB.getMetadata(LLVMContext::MD_access_group);
|
||||
MDNode *AliasScope = CB.getMetadata(LLVMContext::MD_alias_scope);
|
||||
MDNode *NoAlias = CB.getMetadata(LLVMContext::MD_noalias);
|
||||
if (!MemParallelLoopAccess && !AccessGroup && !AliasScope && !NoAlias)
|
||||
return;
|
||||
|
||||
for (ValueToValueMapTy::iterator VMI = VMap.begin(), VMIE = VMap.end();
|
||||
|
@ -790,21 +792,30 @@ static void PropagateParallelLoopAccessMetadata(CallBase &CB,
|
|||
if (!NI)
|
||||
continue;
|
||||
|
||||
if (M) {
|
||||
if (MDNode *PM =
|
||||
NI->getMetadata(LLVMContext::MD_mem_parallel_loop_access)) {
|
||||
M = MDNode::concatenate(PM, M);
|
||||
NI->setMetadata(LLVMContext::MD_mem_parallel_loop_access, M);
|
||||
} else if (NI->mayReadOrWriteMemory()) {
|
||||
NI->setMetadata(LLVMContext::MD_mem_parallel_loop_access, M);
|
||||
}
|
||||
// This metadata is only relevant for instructions that access memory.
|
||||
if (!NI->mayReadOrWriteMemory())
|
||||
continue;
|
||||
|
||||
if (MemParallelLoopAccess) {
|
||||
// TODO: This probably should not overwrite MemParalleLoopAccess.
|
||||
MemParallelLoopAccess = MDNode::concatenate(
|
||||
NI->getMetadata(LLVMContext::MD_mem_parallel_loop_access),
|
||||
MemParallelLoopAccess);
|
||||
NI->setMetadata(LLVMContext::MD_mem_parallel_loop_access,
|
||||
MemParallelLoopAccess);
|
||||
}
|
||||
|
||||
if (NI->mayReadOrWriteMemory()) {
|
||||
MDNode *UnitedAccGroups = uniteAccessGroups(
|
||||
NI->getMetadata(LLVMContext::MD_access_group), CallAccessGroup);
|
||||
NI->setMetadata(LLVMContext::MD_access_group, UnitedAccGroups);
|
||||
}
|
||||
if (AccessGroup)
|
||||
NI->setMetadata(LLVMContext::MD_access_group, uniteAccessGroups(
|
||||
NI->getMetadata(LLVMContext::MD_access_group), AccessGroup));
|
||||
|
||||
if (AliasScope)
|
||||
NI->setMetadata(LLVMContext::MD_alias_scope, MDNode::concatenate(
|
||||
NI->getMetadata(LLVMContext::MD_alias_scope), AliasScope));
|
||||
|
||||
if (NoAlias)
|
||||
NI->setMetadata(LLVMContext::MD_noalias, MDNode::concatenate(
|
||||
NI->getMetadata(LLVMContext::MD_noalias), NoAlias));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -886,31 +897,11 @@ static void CloneAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap) {
|
|||
if (!NI)
|
||||
continue;
|
||||
|
||||
if (MDNode *M = NI->getMetadata(LLVMContext::MD_alias_scope)) {
|
||||
MDNode *NewMD = MDMap[M];
|
||||
// If the call site also had alias scope metadata (a list of scopes to
|
||||
// which instructions inside it might belong), propagate those scopes to
|
||||
// the inlined instructions.
|
||||
if (MDNode *CSM = CB.getMetadata(LLVMContext::MD_alias_scope))
|
||||
NewMD = MDNode::concatenate(NewMD, CSM);
|
||||
NI->setMetadata(LLVMContext::MD_alias_scope, NewMD);
|
||||
} else if (NI->mayReadOrWriteMemory()) {
|
||||
if (MDNode *M = CB.getMetadata(LLVMContext::MD_alias_scope))
|
||||
NI->setMetadata(LLVMContext::MD_alias_scope, M);
|
||||
}
|
||||
if (MDNode *M = NI->getMetadata(LLVMContext::MD_alias_scope))
|
||||
NI->setMetadata(LLVMContext::MD_alias_scope, MDMap[M]);
|
||||
|
||||
if (MDNode *M = NI->getMetadata(LLVMContext::MD_noalias)) {
|
||||
MDNode *NewMD = MDMap[M];
|
||||
// If the call site also had noalias metadata (a list of scopes with
|
||||
// which instructions inside it don't alias), propagate those scopes to
|
||||
// the inlined instructions.
|
||||
if (MDNode *CSM = CB.getMetadata(LLVMContext::MD_noalias))
|
||||
NewMD = MDNode::concatenate(NewMD, CSM);
|
||||
NI->setMetadata(LLVMContext::MD_noalias, NewMD);
|
||||
} else if (NI->mayReadOrWriteMemory()) {
|
||||
if (MDNode *M = CB.getMetadata(LLVMContext::MD_noalias))
|
||||
NI->setMetadata(LLVMContext::MD_noalias, M);
|
||||
}
|
||||
if (MDNode *M = NI->getMetadata(LLVMContext::MD_noalias))
|
||||
NI->setMetadata(LLVMContext::MD_noalias, MDMap[M]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1911,8 +1902,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
|
|||
// function which feed into its return value.
|
||||
AddReturnAttributes(CB, VMap);
|
||||
|
||||
// Propagate llvm.mem.parallel_loop_access if necessary.
|
||||
PropagateParallelLoopAccessMetadata(CB, VMap);
|
||||
// Propagate metadata on the callsite if necessary.
|
||||
PropagateCallSiteMetadata(CB, VMap);
|
||||
|
||||
// Register any cloned assumptions.
|
||||
if (IFI.GetAssumptionCache)
|
||||
|
|
|
@ -50,22 +50,22 @@ define void @caller(float* nocapture %a, float* nocapture %b, float* nocapture r
|
|||
; CHECK-NEXT: [[TMP3:%.*]] = load float, float* [[A]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: [[ARRAYIDX_I9:%.*]] = getelementptr inbounds float, float* [[B]], i64 7
|
||||
; CHECK-NEXT: store float [[TMP3]], float* [[ARRAYIDX_I9]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load float, float* [[C]], align 4
|
||||
; CHECK-NEXT: [[TMP4:%.*]] = load float, float* [[C]], align 4, !noalias !16
|
||||
; CHECK-NEXT: [[ARRAYIDX_I_I4:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
|
||||
; CHECK-NEXT: store float [[TMP4]], float* [[ARRAYIDX_I_I4]], align 4
|
||||
; CHECK-NEXT: store float [[TMP4]], float* [[ARRAYIDX_I_I4]], align 4, !noalias !16
|
||||
; CHECK-NEXT: [[ARRAYIDX1_I_I5:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
|
||||
; CHECK-NEXT: store float [[TMP4]], float* [[ARRAYIDX1_I_I5]], align 4
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = load float, float* [[C]], align 4
|
||||
; CHECK-NEXT: store float [[TMP4]], float* [[ARRAYIDX1_I_I5]], align 4, !noalias !16
|
||||
; CHECK-NEXT: [[TMP5:%.*]] = load float, float* [[C]], align 4, !noalias !16
|
||||
; CHECK-NEXT: [[ARRAYIDX_I6:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
|
||||
; CHECK-NEXT: store float [[TMP5]], float* [[ARRAYIDX_I6]], align 4
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = load float, float* [[A]], align 4
|
||||
; CHECK-NEXT: store float [[TMP5]], float* [[ARRAYIDX_I6]], align 4, !noalias !16
|
||||
; CHECK-NEXT: [[TMP6:%.*]] = load float, float* [[A]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: [[ARRAYIDX_I_I1:%.*]] = getelementptr inbounds float, float* [[B]], i64 5
|
||||
; CHECK-NEXT: store float [[TMP6]], float* [[ARRAYIDX_I_I1]], align 4
|
||||
; CHECK-NEXT: store float [[TMP6]], float* [[ARRAYIDX_I_I1]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: [[ARRAYIDX1_I_I2:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
|
||||
; CHECK-NEXT: store float [[TMP6]], float* [[ARRAYIDX1_I_I2]], align 4
|
||||
; CHECK-NEXT: [[TMP7:%.*]] = load float, float* [[A]], align 4
|
||||
; CHECK-NEXT: store float [[TMP6]], float* [[ARRAYIDX1_I_I2]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: [[TMP7:%.*]] = load float, float* [[A]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: [[ARRAYIDX_I3:%.*]] = getelementptr inbounds float, float* [[B]], i64 7
|
||||
; CHECK-NEXT: store float [[TMP7]], float* [[ARRAYIDX_I3]], align 4
|
||||
; CHECK-NEXT: store float [[TMP7]], float* [[ARRAYIDX_I3]], align 4, !alias.scope !16
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
entry:
|
||||
|
|
Loading…
Reference in New Issue