llvm.org GIT mirror llvm / 985dac6
Memory Dependence Analysis (not mem-dep test) take advantage of "invariant.load" metadata. The "invariant.load" metadata indicates the memory unit being accessed is immutable. A load annotated with this metadata can be moved across any store. As I am not sure if it is legal to move such loads across barrier/fence, this change dose not allow such transformation. rdar://11311484 Thank Arnold for code review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176562 91177308-0d34-0410-b5e6-96231b3b80d8 Shuxin Yang 7 years ago
5 changed file(s) with 55 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
390390 /// getPointerDependencyFrom - Return the instruction on which a memory
391391 /// location depends. If isLoad is true, this routine ignores may-aliases
392392 /// with read-only operations. If isLoad is false, this routine ignores
393 /// may-aliases with reads from read-only locations.
393 /// may-aliases with reads from read-only locations. If possible, pass
394 /// the query instruction as well; this function may take advantage of
395 /// the metadata annotated to the query instruction to refine the result.
394396 ///
395397 /// Note that this is an uncached query, and thus may be inefficient.
396398 ///
397399 MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
398400 bool isLoad,
399401 BasicBlock::iterator ScanIt,
400 BasicBlock *BB);
402 BasicBlock *BB,
403 Instruction *QueryInst = 0);
401404
402405
403406 /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
4545 MD_prof = 2, // "prof"
4646 MD_fpmath = 3, // "fpmath"
4747 MD_range = 4, // "range"
48 MD_tbaa_struct = 5 // "tbaa.struct"
48 MD_tbaa_struct = 5, // "tbaa.struct"
49 MD_invariant_load = 6 // "invariant.load"
4950 };
5051
5152 /// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
350350 /// getPointerDependencyFrom - Return the instruction on which a memory
351351 /// location depends. If isLoad is true, this routine ignores may-aliases with
352352 /// read-only operations. If isLoad is false, this routine ignores may-aliases
353 /// with reads from read-only locations.
353 /// with reads from read-only locations. If possible, pass the query
354 /// instruction as well; this function may take advantage of the metadata
355 /// annotated to the query instruction to refine the result.
354356 MemDepResult MemoryDependenceAnalysis::
355357 getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad,
356 BasicBlock::iterator ScanIt, BasicBlock *BB) {
358 BasicBlock::iterator ScanIt, BasicBlock *BB,
359 Instruction *QueryInst) {
357360
358361 const Value *MemLocBase = 0;
359362 int64_t MemLocOffset = 0;
360
361363 unsigned Limit = BlockScanLimit;
364 bool isInvariantLoad = false;
365 if (isLoad && QueryInst) {
366 LoadInst *LI = dyn_cast(QueryInst);
367 if (LI && LI->getMetadata(LLVMContext::MD_invariant_load) != 0)
368 isInvariantLoad = true;
369 }
362370
363371 // Walk backwards through the basic block, looking for dependencies.
364372 while (ScanIt != BB->begin()) {
473481 continue;
474482 if (R == AliasAnalysis::MustAlias)
475483 return MemDepResult::getDef(Inst);
484 if (isInvariantLoad)
485 continue;
476486 return MemDepResult::getClobber(Inst);
477487 }
478488
570580 isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start;
571581
572582 LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos,
573 QueryParent);
583 QueryParent, QueryInst);
574584 } else if (isa(QueryInst) || isa(QueryInst)) {
575585 CallSite QueryCS(QueryInst);
576586 bool isReadOnly = AA->onlyReadsMemory(QueryCS);
5757 unsigned TBAAStructID = getMDKindID("tbaa.struct");
5858 assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
5959 (void)TBAAStructID;
60
61 // Create the 'invariant.load' metadata kind.
62 unsigned InvariantLdId = getMDKindID("invariant.load");
63 assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
64 (void)InvariantLdId;
6065 }
6166 LLVMContext::~LLVMContext() { delete pImpl; }
6267
0 ; RUN: opt < %s -basicaa -gvn -S | FileCheck %s
1
2 ; The input *.ll is obtained by manually annotating "invariant.load" to the
3 ; two loads. With "invariant.load" metadata, the second load is redundant.
4 ;
5 ; int foo(int *p, char *q) {
6 ; *q = (char)*p;
7 ; return *p + 1;
8 ; }
9
10 define i32 @foo(i32* nocapture %p, i8* nocapture %q) {
11 entry:
12 %0 = load i32* %p, align 4, !tbaa !0, !invariant.load !3
13 %conv = trunc i32 %0 to i8
14 store i8 %conv, i8* %q, align 1, !tbaa !1
15 %1 = load i32* %p, align 4, !tbaa !0, !invariant.load !3
16 %add = add nsw i32 %1, 1
17 ret i32 %add
18
19 ; CHECK: foo
20 ; CHECK: %0 = load i32* %p
21 ; CHECK: store i8 %conv, i8* %q,
22 ; CHECK: %add = add nsw i32 %0, 1
23 }
24
25 !0 = metadata !{metadata !"int", metadata !1}
26 !1 = metadata !{metadata !"omnipotent char", metadata !2}
27 !2 = metadata !{metadata !"Simple C/C++ TBAA"}
28 !3 = metadata !{}