mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Two changes: Make getDependency remove QueryInst for a dirty record's
ReverseLocalDeps when we update it. This fixes a regression test failure from my last commit. Second, for each non-local cached information structure, keep a bit that indicates whether it is dirty or not. This saves us a scan over the whole thing in the common case when it isn't dirty. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60274 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -129,11 +129,14 @@ namespace llvm { | |||||||
|  |  | ||||||
|     typedef DenseMap<BasicBlock*, DepResultTy> NonLocalDepInfo; |     typedef DenseMap<BasicBlock*, DepResultTy> NonLocalDepInfo; | ||||||
|      |      | ||||||
|  |     /// PerInstNLInfo - This is the instruction we keep for each cached access | ||||||
|  |     /// that we have for an instruction.  The pointer is an owning pointer and | ||||||
|  |     /// the bool indicates whether we have any dirty bits in the set. | ||||||
|  |     typedef PointerIntPair<NonLocalDepInfo*, 1, bool> PerInstNLInfo; | ||||||
|      |      | ||||||
|     // A map from instructions to their non-local dependencies. |     // A map from instructions to their non-local dependencies. | ||||||
|     typedef DenseMap<Instruction*, |     typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType; | ||||||
|                      // This is an owning pointer. |        | ||||||
|                      NonLocalDepInfo*> NonLocalDepMapType; |  | ||||||
|     NonLocalDepMapType NonLocalDeps; |     NonLocalDepMapType NonLocalDeps; | ||||||
|      |      | ||||||
|     // A reverse mapping from dependencies to the dependees.  This is |     // A reverse mapping from dependencies to the dependees.  This is | ||||||
| @@ -158,7 +161,7 @@ namespace llvm { | |||||||
|       LocalDeps.clear(); |       LocalDeps.clear(); | ||||||
|       for (NonLocalDepMapType::iterator I = NonLocalDeps.begin(), |       for (NonLocalDepMapType::iterator I = NonLocalDeps.begin(), | ||||||
|            E = NonLocalDeps.end(); I != E; ++I) |            E = NonLocalDeps.end(); I != E; ++I) | ||||||
|         delete I->second; |         delete I->second.getPointer(); | ||||||
|       NonLocalDeps.clear(); |       NonLocalDeps.clear(); | ||||||
|       ReverseLocalDeps.clear(); |       ReverseLocalDeps.clear(); | ||||||
|       ReverseNonLocalDeps.clear(); |       ReverseNonLocalDeps.clear(); | ||||||
|   | |||||||
| @@ -199,9 +199,15 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { | |||||||
|      |      | ||||||
|   // Otherwise, if we have a dirty entry, we know we can start the scan at that |   // Otherwise, if we have a dirty entry, we know we can start the scan at that | ||||||
|   // instruction, which may save us some work. |   // instruction, which may save us some work. | ||||||
|   if (Instruction *Inst = LocalCache.getPointer()) |   if (Instruction *Inst = LocalCache.getPointer()) { | ||||||
|     ScanPos = Inst; |     ScanPos = Inst; | ||||||
|     |     | ||||||
|  |     SmallPtrSet<Instruction*, 4> &InstMap = ReverseLocalDeps[Inst]; | ||||||
|  |     InstMap.erase(QueryInst); | ||||||
|  |     if (InstMap.empty()) | ||||||
|  |       ReverseLocalDeps.erase(Inst); | ||||||
|  |   } | ||||||
|  |    | ||||||
|   // Do the scan. |   // Do the scan. | ||||||
|   LocalCache = getDependencyFromInternal(QueryInst, ScanPos, |   LocalCache = getDependencyFromInternal(QueryInst, ScanPos, | ||||||
|                                          QueryInst->getParent()); |                                          QueryInst->getParent()); | ||||||
| @@ -227,10 +233,10 @@ getNonLocalDependency(Instruction *QueryInst, | |||||||
|                                                       MemDepResult> > &Result) { |                                                       MemDepResult> > &Result) { | ||||||
|   assert(getDependency(QueryInst).isNonLocal() && |   assert(getDependency(QueryInst).isNonLocal() && | ||||||
|      "getNonLocalDependency should only be used on insts with non-local deps!"); |      "getNonLocalDependency should only be used on insts with non-local deps!"); | ||||||
|   NonLocalDepInfo *&CacheP = NonLocalDeps[QueryInst]; |   PerInstNLInfo &CacheP = NonLocalDeps[QueryInst]; | ||||||
|   if (CacheP == 0) CacheP = new NonLocalDepInfo(); |   if (CacheP.getPointer() == 0) CacheP.setPointer(new NonLocalDepInfo()); | ||||||
|    |    | ||||||
|   NonLocalDepInfo &Cache = *CacheP; |   NonLocalDepInfo &Cache = *CacheP.getPointer(); | ||||||
|  |  | ||||||
|   /// DirtyBlocks - This is the set of blocks that need to be recomputed.  In |   /// DirtyBlocks - This is the set of blocks that need to be recomputed.  In | ||||||
|   /// the cached case, this can happen due to instructions being deleted etc. In |   /// the cached case, this can happen due to instructions being deleted etc. In | ||||||
| @@ -240,9 +246,9 @@ getNonLocalDependency(Instruction *QueryInst, | |||||||
|    |    | ||||||
|   if (!Cache.empty()) { |   if (!Cache.empty()) { | ||||||
|     // If we already have a partially computed set of results, scan them to |     // If we already have a partially computed set of results, scan them to | ||||||
|     // determine what is dirty, seeding our initial DirtyBlocks worklist. |     // determine what is dirty, seeding our initial DirtyBlocks worklist.  The | ||||||
|     // FIXME: In the "don't need to be updated" case, this is expensive, why not |     // Int bit of CacheP tells us if we have anything dirty. | ||||||
|     // have a per-"cache" flag saying it is undirty? |     if (CacheP.getInt()) | ||||||
|       for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); |       for (NonLocalDepInfo::iterator I = Cache.begin(), E = Cache.end(); | ||||||
|          I != E; ++I) |          I != E; ++I) | ||||||
|         if (I->second.getInt() == Dirty) |         if (I->second.getInt() == Dirty) | ||||||
| @@ -315,7 +321,7 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { | |||||||
|   // for any cached queries. |   // for any cached queries. | ||||||
|   NonLocalDepMapType::iterator NLDI = NonLocalDeps.find(RemInst); |   NonLocalDepMapType::iterator NLDI = NonLocalDeps.find(RemInst); | ||||||
|   if (NLDI != NonLocalDeps.end()) { |   if (NLDI != NonLocalDeps.end()) { | ||||||
|     NonLocalDepInfo &BlockMap = *NLDI->second; |     NonLocalDepInfo &BlockMap = *NLDI->second.getPointer(); | ||||||
|     for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); |     for (NonLocalDepInfo::iterator DI = BlockMap.begin(), DE = BlockMap.end(); | ||||||
|          DI != DE; ++DI) |          DI != DE; ++DI) | ||||||
|       if (Instruction *Inst = DI->second.getPointer()) |       if (Instruction *Inst = DI->second.getPointer()) | ||||||
| @@ -388,11 +394,13 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { | |||||||
|          I != E; ++I) { |          I != E; ++I) { | ||||||
|       assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); |       assert(*I != RemInst && "Already removed NonLocalDep info for RemInst"); | ||||||
|        |        | ||||||
|       NonLocalDepInfo &INLD = *NonLocalDeps[*I]; |       PerInstNLInfo &INLD = NonLocalDeps[*I]; | ||||||
|       assert(&INLD != 0 && "Reverse mapping out of date?"); |       assert(INLD.getPointer() != 0 && "Reverse mapping out of date?"); | ||||||
|  |       // The information is now dirty! | ||||||
|  |       INLD.setInt(true); | ||||||
|        |        | ||||||
|       for (NonLocalDepInfo::iterator DI = INLD.begin(), DE = INLD.end(); |       for (NonLocalDepInfo::iterator DI = INLD.getPointer()->begin(),  | ||||||
|            DI != DE; ++DI) { |            DE = INLD.getPointer()->end(); DI != DE; ++DI) { | ||||||
|         if (DI->second.getPointer() != RemInst) continue; |         if (DI->second.getPointer() != RemInst) continue; | ||||||
|          |          | ||||||
|         // Convert to a dirty entry for the subsequent instruction. |         // Convert to a dirty entry for the subsequent instruction. | ||||||
| @@ -435,9 +443,9 @@ void MemoryDependenceAnalysis::verifyRemoved(Instruction *D) const { | |||||||
|   for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), |   for (NonLocalDepMapType::const_iterator I = NonLocalDeps.begin(), | ||||||
|        E = NonLocalDeps.end(); I != E; ++I) { |        E = NonLocalDeps.end(); I != E; ++I) { | ||||||
|     assert(I->first != D && "Inst occurs in data structures"); |     assert(I->first != D && "Inst occurs in data structures"); | ||||||
|     NonLocalDepInfo &INLD = *I->second; |     const PerInstNLInfo &INLD = I->second; | ||||||
|     for (NonLocalDepInfo::iterator II = INLD.begin(), EE = INLD.end(); |     for (NonLocalDepInfo::iterator II = INLD.getPointer()->begin(), | ||||||
|          II  != EE; ++II) |          EE = INLD.getPointer()->end(); II  != EE; ++II) | ||||||
|       assert(II->second.getPointer() != D && "Inst occurs in data structures"); |       assert(II->second.getPointer() != D && "Inst occurs in data structures"); | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user