mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Add trivial support for the invariance intrinsics to memdep. This logic is
purely local for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85378 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -171,13 +171,42 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall, | |||||||
| /// location depends.  If isLoad is true, this routine ignore may-aliases with | /// location depends.  If isLoad is true, this routine ignore may-aliases with | ||||||
| /// read-only operations. | /// read-only operations. | ||||||
| MemDepResult MemoryDependenceAnalysis:: | MemDepResult MemoryDependenceAnalysis:: | ||||||
| getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, | getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,  | ||||||
|                          BasicBlock::iterator ScanIt, BasicBlock *BB) { |                          BasicBlock::iterator ScanIt, BasicBlock *BB) { | ||||||
|  |  | ||||||
|  |   Value* invariantTag = 0; | ||||||
|  |  | ||||||
|   // Walk backwards through the basic block, looking for dependencies. |   // Walk backwards through the basic block, looking for dependencies. | ||||||
|   while (ScanIt != BB->begin()) { |   while (ScanIt != BB->begin()) { | ||||||
|     Instruction *Inst = --ScanIt; |     Instruction *Inst = --ScanIt; | ||||||
|  |  | ||||||
|  |     // If we're in an invariant region, no dependencies can be found before | ||||||
|  |     // we pass an invariant-begin marker. | ||||||
|  |     if (invariantTag == Inst) { | ||||||
|  |       invariantTag = 0; | ||||||
|  |       continue; | ||||||
|  |      | ||||||
|  |     // If we pass an invariant-end marker, then we've just entered an invariant | ||||||
|  |     // region and can start ignoring dependencies. | ||||||
|  |     } else if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(Inst)) { | ||||||
|  |       if (II->getIntrinsicID() == Intrinsic::invariant_end) { | ||||||
|  |         uint64_t invariantSize = ~0ULL; | ||||||
|  |         if (ConstantInt* CI = dyn_cast<ConstantInt>(II->getOperand(2))) | ||||||
|  |           invariantSize = CI->getZExtValue(); | ||||||
|  |          | ||||||
|  |         AliasAnalysis::AliasResult R = | ||||||
|  |           AA->alias(II->getOperand(3), invariantSize, MemPtr, MemSize); | ||||||
|  |         if (R == AliasAnalysis::MustAlias) { | ||||||
|  |           invariantTag = II->getOperand(1); | ||||||
|  |           continue; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // If we're querying on a load and we're in an invariant region, we're done | ||||||
|  |     // at this point. Nothing a load depends on can live in an invariant region. | ||||||
|  |     if (isLoad && invariantTag) continue; | ||||||
|  |  | ||||||
|     // Debug intrinsics don't cause dependences. |     // Debug intrinsics don't cause dependences. | ||||||
|     if (isa<DbgInfoIntrinsic>(Inst)) continue; |     if (isa<DbgInfoIntrinsic>(Inst)) continue; | ||||||
|  |  | ||||||
| @@ -201,6 +230,11 @@ getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad, | |||||||
|       return MemDepResult::getDef(Inst); |       return MemDepResult::getDef(Inst); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     // If we're querying on a store and we're in an invariant region, we're done | ||||||
|  |     // at this point. The only things that stores depend on that could exist in | ||||||
|  |     // an invariant region are loads, which we've already checked. | ||||||
|  |     if (invariantTag) continue; | ||||||
|  |      | ||||||
|     if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { |     if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { | ||||||
|       // If alias analysis can tell that this store is guaranteed to not modify |       // If alias analysis can tell that this store is guaranteed to not modify | ||||||
|       // the query pointer, ignore it.  Use getModRefInfo to handle cases where |       // the query pointer, ignore it.  Use getModRefInfo to handle cases where | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								test/Transforms/GVN/invariant-simple.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								test/Transforms/GVN/invariant-simple.ll
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | ; RUN: opt < %s -gvn -S | FileCheck %s | ||||||
|  |  | ||||||
|  | target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" | ||||||
|  | target triple = "i386-apple-darwin7" | ||||||
|  |  | ||||||
|  | define i8 @test(i8* %P) nounwind { | ||||||
|  | ; CHECK: @test | ||||||
|  | ; CHECK-NOT: load | ||||||
|  | ; CHECK: ret i8 | ||||||
|  | entry: | ||||||
|  |   store i8 1, i8* %P | ||||||
|  |   %0 = call {}* @llvm.invariant.start(i64 32, i8* %P) | ||||||
|  |   %1 = tail call i32 @foo(i8* %P) | ||||||
|  |   call void @llvm.invariant.end({}* %0, i64 32, i8* %P) | ||||||
|  |   %2 = load i8* %P | ||||||
|  |   ret i8 %2 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | declare i32 @foo(i8*) nounwind  | ||||||
|  | declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly | ||||||
|  | declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) | ||||||
		Reference in New Issue
	
	Block a user