[PATCH] Scoped NoAlias Metadata

hfinkel at anl.gov hfinkel at anl.gov
Fri Nov 15 15:08:39 PST 2013


Hi atrick, sunfish, chandlerc,

This patch adds support for scoped noalias metadata. The primary motivations for this feature are:

 1. To preserve noalias function attribute information when inlining

 2. To provide the ability to model block-scope C99 restrict pointers

The second point requires frontend enhancement, and only the first capability is added here. In practice, this patch adds the ability to generally specify noalias memory-access sets, and I'm sure that other frontends will find this useful too. These things are important for vectorization, LICM, instruction scheduling, etc.

First, this is a large patchset; however, it is mostly a formulaic generalization of the current TBAA support. The new alias.scope and noalias metadata act very much like TBAA metadata: references to the associated MDNodes need to be included in AA's Location object, handled by the AA infrastructure, and preserved like TBAA in existing passes. This patch introduces a new structure, AAMDNodes, to hold MDNode pointers to all three of the possible AA MDNodes associated with a memory access (tbaa, alias.scope and noalias), and changes almost all code that deals with MDNode* for TBAA to use the AAMDNodes structure instead. As part of this, I tried to also rename the relevant variables (TBAAInfo -> AAInfo, TBAATag -> AATags, etc.) and update any relevant comments.

As for the metadata itself, alias-analysis scopes are defined similar to TBAA nodes:

!scope0 = metadata !{ metadata !"scope of foo()" }
!scope1 = metadata !{ metadata !"scope 1", metadata !scope0 }
!scope2 = metadata !{ metadata !"scope 2", metadata !scope0 }
!scope3 = metadata !{ metadata !"scope 2.1", metadata !scope2 }
!scope4 = metadata !{ metadata !"scope 2.2", metadata !scope2 }

Loads and stores can be tagged with an alias-analysis scope, and also, with a noalias tag for a specific scope:

... = load %ptr1, !alias.scope !{ !scope1 }
... = load %ptr2, !alias.scope !{ !scope1, !scope2 }, !noalias !{ !scope1 }

When evaluating an aliasing query, if one of the instructions is associated with an alias.scope id that is identical to the noalias scope associated with the other instruction, or is a descendant (in the scope hierarchy) of the noalias scope associated with the other instruction, then the two memory accesses are assumed not to alias.

Note that is the first element of the scope metadata is a string, then it can be combined accross functions and translation units. The string can be replaced by a self-reference to create globally unqiue scope identifiers.

[Note: This overview is slightly stylized, since the metadata nodes really need to just be numbers (!0 instead of !scope0), and the scope lists are also global unnamed metadata.]

When a function is inlined, the noalias metadata is added to the function: A new unique scope is created for each noalias function parameter. noalias indicates that pointer values based on the argument do not alias pointer values which are not based on it. So we add a new "scope" for each noalias function argument. Accesses using pointers based on that argument become part of that alias scope, accesses using pointers not based on that argument are tagged as noalias with that scope.

Also, existing metadata in the inlined callee may be "cloned" for use by the inlined code. This is necessary because the aliasing scopes are unique to each call site (because of possible control dependencies on the aliasing properties). For example, consider a function: foo(noalias a, noalias b) { *a = *b; } that gets inlined into bar() { ... if (...) foo(a1, b1); ... if (...) foo(a2, b2); } -- now just because we know that a1 does not alias with b1 at the first call site, and a2 does not alias with b2 at the second call site, we cannot let inlining these functons have the metadata imply that a1 does not alias with b2.

The significant code additions are in lib/Analysis/ScopedNoAliasAA.cpp and lib/Transforms/Utils/InlineFunction.cpp (and a few things in lib/IR/Metadata.cpp); the overall amount of new code is actually pretty minimal.

Please review.

Thanks again!

P.S. I know that the LangRef documentation changes are not here yet; if we're okay with the design, then I'll write some (based on the text above).

http://llvm-reviews.chandlerc.com/D2194

Files:
  include/llvm-c/Transforms/Scalar.h
  include/llvm/Analysis/AliasAnalysis.h
  include/llvm/Analysis/AliasSetTracker.h
  include/llvm/Analysis/Loads.h
  include/llvm/Analysis/MemoryDependenceAnalysis.h
  include/llvm/Analysis/Passes.h
  include/llvm/CodeGen/MachineFunction.h
  include/llvm/CodeGen/MachineMemOperand.h
  include/llvm/CodeGen/SelectionDAG.h
  include/llvm/CodeGen/SelectionDAGNodes.h
  include/llvm/IR/IRBuilder.h
  include/llvm/IR/Instruction.h
  include/llvm/IR/LLVMContext.h
  include/llvm/IR/MDBuilder.h
  include/llvm/IR/Metadata.h
  include/llvm/InitializePasses.h
  include/llvm/LinkAllPasses.h
  lib/Analysis/AliasAnalysis.cpp
  lib/Analysis/AliasAnalysisEvaluator.cpp
  lib/Analysis/AliasSetTracker.cpp
  lib/Analysis/Analysis.cpp
  lib/Analysis/BasicAliasAnalysis.cpp
  lib/Analysis/CMakeLists.txt
  lib/Analysis/Loads.cpp
  lib/Analysis/MemoryDependenceAnalysis.cpp
  lib/Analysis/ScalarEvolutionAliasAnalysis.cpp
  lib/Analysis/ScopedNoAliasAA.cpp
  lib/Analysis/TypeBasedAliasAnalysis.cpp
  lib/CodeGen/MachineFunction.cpp
  lib/CodeGen/MachineInstr.cpp
  lib/CodeGen/Passes.cpp
  lib/CodeGen/ScheduleDAGInstrs.cpp
  lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
  lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
  lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
  lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
  lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
  lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
  lib/CodeGen/SelectionDAG/SelectionDAG.cpp
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  lib/IR/IRBuilder.cpp
  lib/IR/LLVMContext.cpp
  lib/IR/Metadata.cpp
  lib/Target/ARM/ARMISelLowering.cpp
  lib/Target/Mips/MipsSEISelLowering.cpp
  lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
  lib/Target/X86/X86ISelLowering.cpp
  lib/Transforms/IPO/ArgumentPromotion.cpp
  lib/Transforms/IPO/FunctionAttrs.cpp
  lib/Transforms/IPO/PassManagerBuilder.cpp
  lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
  lib/Transforms/Scalar/GVN.cpp
  lib/Transforms/Scalar/JumpThreading.cpp
  lib/Transforms/Scalar/LICM.cpp
  lib/Transforms/Scalar/SROA.cpp
  lib/Transforms/Scalar/Scalar.cpp
  lib/Transforms/Scalar/ScalarReplAggregates.cpp
  lib/Transforms/Utils/InlineFunction.cpp
  lib/Transforms/Vectorize/BBVectorize.cpp
  test/Analysis/ScopedNoAliasAA/basic-hierarchy.ll
  test/Analysis/ScopedNoAliasAA/basic.ll
  test/Analysis/ScopedNoAliasAA/basic2.ll
  test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
  test/Analysis/TypeBasedAliasAnalysis/tbaa-path.ll
  test/Transforms/GVN/noalias.ll
  test/Transforms/Inline/noalias.ll
  test/Transforms/Inline/noalias2.ll
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2194.1.patch
Type: text/x-patch
Size: 196054 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131115/ff039ac8/attachment.bin>


More information about the llvm-commits mailing list