Introduce another level of metadata to distinguish non-aliasing accesses
Introduce another level of alias metadata to distinguish the individual
non-aliasing accesses that have inter iteration alias-free base pointers
marked with "Inter iteration alias-free" mark nodes. It can be used to,
for example, distinguish different stores (loads) produced by unrolling of
the innermost loops and, subsequently, sink (hoist) them by LICM.
Reviewed-by: Tobias Grosser <tobias@grosser.es>
Differential Revision: https://reviews.llvm.org/D30606
llvm-svn: 298510
diff --git a/polly/lib/CodeGen/IRBuilder.cpp b/polly/lib/CodeGen/IRBuilder.cpp
index 9b3602d..1077515 100644
--- a/polly/lib/CodeGen/IRBuilder.cpp
+++ b/polly/lib/CodeGen/IRBuilder.cpp
@@ -115,6 +115,49 @@
B->setMetadata("llvm.loop", Id);
}
+/// Get the pointer operand
+///
+/// @param Inst The instruction to be analyzed.
+/// @return the pointer operand in case @p Inst is a memory access
+/// instruction and nullptr otherwise.
+static llvm::Value *getMemAccInstPointerOperand(Instruction *Inst) {
+ auto MemInst = MemAccInst::dyn_cast(Inst);
+ if (!MemInst)
+ return nullptr;
+
+ return MemInst.getPointerOperand();
+}
+
+void ScopAnnotator::annotateSecondLevel(llvm::Instruction *Inst,
+ llvm::Value *BasePtr) {
+ auto *Ptr = getMemAccInstPointerOperand(Inst);
+ if (!Ptr)
+ return;
+ auto SecondLevelAliasScope = SecondLevelAliasScopeMap.lookup(Ptr);
+ auto SecondLevelOtherAliasScopeList =
+ SecondLevelOtherAliasScopeListMap.lookup(Ptr);
+ if (!SecondLevelAliasScope) {
+ auto AliasScope = AliasScopeMap.lookup(BasePtr);
+ if (!AliasScope)
+ return;
+ LLVMContext &Ctx = SE->getContext();
+ SecondLevelAliasScope = getID(
+ Ctx, AliasScope, MDString::get(Ctx, "second level alias metadata"));
+ SecondLevelAliasScopeMap[Ptr] = SecondLevelAliasScope;
+ Metadata *Args = {SecondLevelAliasScope};
+ auto SecondLevelBasePtrAliasScopeList =
+ SecondLevelAliasScopeMap.lookup(BasePtr);
+ SecondLevelAliasScopeMap[BasePtr] = MDNode::concatenate(
+ SecondLevelBasePtrAliasScopeList, MDNode::get(Ctx, Args));
+ auto OtherAliasScopeList = OtherAliasScopeListMap.lookup(BasePtr);
+ SecondLevelOtherAliasScopeList = MDNode::concatenate(
+ OtherAliasScopeList, SecondLevelBasePtrAliasScopeList);
+ SecondLevelOtherAliasScopeListMap[Ptr] = SecondLevelOtherAliasScopeList;
+ }
+ Inst->setMetadata("alias.scope", SecondLevelAliasScope);
+ Inst->setMetadata("noalias", SecondLevelOtherAliasScopeList);
+}
+
void ScopAnnotator::annotate(Instruction *Inst) {
if (!Inst->mayReadOrWriteMemory())
return;
@@ -126,11 +169,7 @@
if (!AliasScopeDomain)
return;
- auto MemInst = MemAccInst::dyn_cast(Inst);
- if (!MemInst)
- return;
-
- auto *Ptr = MemInst.getPointerOperand();
+ auto *Ptr = getMemAccInstPointerOperand(Inst);
if (!Ptr)
return;
@@ -162,6 +201,18 @@
"BasePtr either expected in AliasScopeMap and OtherAlias...Map");
auto *OtherAliasScopeList = OtherAliasScopeListMap[BasePtr];
+ if (InterIterationAliasFreeBasePtrs.count(BasePtr)) {
+ annotateSecondLevel(Inst, BasePtr);
+ return;
+ }
+
Inst->setMetadata("alias.scope", AliasScope);
Inst->setMetadata("noalias", OtherAliasScopeList);
}
+
+void ScopAnnotator::addInterIterationAliasFreeBasePtr(llvm::Value *BasePtr) {
+ if (!BasePtr)
+ return;
+
+ InterIterationAliasFreeBasePtrs.insert(BasePtr);
+}