mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Improve LSR's dead-phi detection to handle use-def cycles
with more than two nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52617 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -1810,31 +1810,28 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) { | |||||||
|     DeleteTriviallyDeadInstructions(DeadInsts); |     DeleteTriviallyDeadInstructions(DeadInsts); | ||||||
|  |  | ||||||
|     BasicBlock::iterator I = L->getHeader()->begin(); |     BasicBlock::iterator I = L->getHeader()->begin(); | ||||||
|     PHINode *PN; |     while (PHINode *PN = dyn_cast<PHINode>(I++)) { | ||||||
|     while ((PN = dyn_cast<PHINode>(I))) { |       // At this point, we know that we have killed one or more IV users. | ||||||
|       ++I;  // Preincrement iterator to avoid invalidating it when deleting PN. |       // It is worth checking to see if the cann indvar is also | ||||||
|  |       // dead, so that we can remove it as well. | ||||||
|       // At this point, we know that we have killed one or more GEP |       // | ||||||
|       // instructions.  It is worth checking to see if the cann indvar is also |       // We can remove a PHI if it is on a cycle in the def-use graph | ||||||
|       // dead, so that we can remove it as well.  The requirements for the cann |       // where each node in the cycle has degree one, i.e. only one use, | ||||||
|       // indvar to be considered dead are: |       // and is an instruction with no side effects. | ||||||
|       // 1. the cann indvar has one use |       // | ||||||
|       // 2. the use is an add instruction |  | ||||||
|       // 3. the add has one use |  | ||||||
|       // 4. the add is used by the cann indvar |  | ||||||
|       // If all four cases above are true, then we can remove both the add and |  | ||||||
|       // the cann indvar. |  | ||||||
|       // FIXME: this needs to eliminate an induction variable even if it's being |       // FIXME: this needs to eliminate an induction variable even if it's being | ||||||
|       // compared against some value to decide loop termination. |       // compared against some value to decide loop termination. | ||||||
|       if (PN->hasOneUse()) { |       if (PN->hasOneUse()) { | ||||||
|         Instruction *BO = dyn_cast<Instruction>(*PN->use_begin()); |         for (Instruction *J = dyn_cast<Instruction>(*PN->use_begin()); | ||||||
|         if (BO && (isa<BinaryOperator>(BO) || isa<CmpInst>(BO))) { |              J && J->hasOneUse() && !J->mayWriteToMemory(); | ||||||
|           if (BO->hasOneUse() && PN == *(BO->use_begin())) { |              J = dyn_cast<Instruction>(*J->use_begin())) { | ||||||
|             DeadInsts.insert(BO); |           // If we find the original PHI, we've discovered a cycle. | ||||||
|             // Break the cycle, then delete the PHI. |           if (J == PN) { | ||||||
|  |             // Break the cycle and mark the PHI for deletion. | ||||||
|             SE->deleteValueFromRecords(PN); |             SE->deleteValueFromRecords(PN); | ||||||
|             PN->replaceAllUsesWith(UndefValue::get(PN->getType())); |             PN->replaceAllUsesWith(UndefValue::get(PN->getType())); | ||||||
|             PN->eraseFromParent(); |             DeadInsts.insert(PN); | ||||||
|  |             break; | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								test/Transforms/LoopStrengthReduce/dead-phi.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								test/Transforms/LoopStrengthReduce/dead-phi.ll
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | ; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | grep phi | count 1 | ||||||
|  |  | ||||||
|  | define void @foo(i32 %n) { | ||||||
|  | entry: | ||||||
|  |   br label %loop | ||||||
|  |  | ||||||
|  | loop: | ||||||
|  |   %i = phi i32 [ 0, %entry ], [ %i.next, %loop ] | ||||||
|  |  | ||||||
|  |   ; These three instructions form an isolated cycle and can be deleted. | ||||||
|  |   %j = phi i32 [ 0, %entry ], [ %j.y, %loop ] | ||||||
|  |   %j.x = add i32 %j, 1 | ||||||
|  |   %j.y = mul i32 %j.x, 2 | ||||||
|  |  | ||||||
|  |   %i.next = add i32 %i, 1 | ||||||
|  |   %c = icmp ne i32 %i.next, %n | ||||||
|  |   br i1 %c, label %loop, label %exit | ||||||
|  |  | ||||||
|  | exit: | ||||||
|  |   ret void | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user