mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Revert r222039 because of bot failure.
http://lab.llvm.org:8080/green/job/clang-Rlto_master/298/ Hopefully, bot will be green. If not, we will re-submit the commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222287 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -20,7 +20,6 @@ | |||||||
| #include "llvm/ADT/DepthFirstIterator.h" | #include "llvm/ADT/DepthFirstIterator.h" | ||||||
| #include "llvm/ADT/Hashing.h" | #include "llvm/ADT/Hashing.h" | ||||||
| #include "llvm/ADT/MapVector.h" | #include "llvm/ADT/MapVector.h" | ||||||
| #include "llvm/ADT/PostOrderIterator.h" |  | ||||||
| #include "llvm/ADT/SetVector.h" | #include "llvm/ADT/SetVector.h" | ||||||
| #include "llvm/ADT/SmallPtrSet.h" | #include "llvm/ADT/SmallPtrSet.h" | ||||||
| #include "llvm/ADT/Statistic.h" | #include "llvm/ADT/Statistic.h" | ||||||
| @@ -710,7 +709,6 @@ namespace { | |||||||
|     void dump(DenseMap<uint32_t, Value*> &d); |     void dump(DenseMap<uint32_t, Value*> &d); | ||||||
|     bool iterateOnFunction(Function &F); |     bool iterateOnFunction(Function &F); | ||||||
|     bool performPRE(Function &F); |     bool performPRE(Function &F); | ||||||
|     bool performScalarPRE(Instruction *I); |  | ||||||
|     Value *findLeader(const BasicBlock *BB, uint32_t num); |     Value *findLeader(const BasicBlock *BB, uint32_t num); | ||||||
|     void cleanupGlobalSets(); |     void cleanupGlobalSets(); | ||||||
|     void verifyRemoved(const Instruction *I) const; |     void verifyRemoved(const Instruction *I) const; | ||||||
| @@ -1731,15 +1729,6 @@ bool GVN::processNonLocalLoad(LoadInst *LI) { | |||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // If this load follows a GEP, see if we can PRE the indices before analyzing. |  | ||||||
|   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0))) { |  | ||||||
|     for (GetElementPtrInst::op_iterator OI = GEP->idx_begin(), |  | ||||||
|                                         OE = GEP->idx_end(); |  | ||||||
|          OI != OE; ++OI) |  | ||||||
|       if (Instruction *I = dyn_cast<Instruction>(OI->get())) |  | ||||||
|         performScalarPRE(I); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Step 2: Analyze the availability of the load |   // Step 2: Analyze the availability of the load | ||||||
|   AvailValInBlkVect ValuesPerBlock; |   AvailValInBlkVect ValuesPerBlock; | ||||||
|   UnavailBlkVect UnavailableBlocks; |   UnavailBlkVect UnavailableBlocks; | ||||||
| @@ -2442,26 +2431,40 @@ bool GVN::processBlock(BasicBlock *BB) { | |||||||
|   return ChangedFunction; |   return ChangedFunction; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool GVN::performScalarPRE(Instruction *CurInst) { | /// performPRE - Perform a purely local form of PRE that looks for diamond | ||||||
|  | /// control flow patterns and attempts to perform simple PRE at the join point. | ||||||
|  | bool GVN::performPRE(Function &F) { | ||||||
|  |   bool Changed = false; | ||||||
|   SmallVector<std::pair<Value*, BasicBlock*>, 8> predMap; |   SmallVector<std::pair<Value*, BasicBlock*>, 8> predMap; | ||||||
|  |   for (BasicBlock *CurrentBlock : depth_first(&F.getEntryBlock())) { | ||||||
|  |     // Nothing to PRE in the entry block. | ||||||
|  |     if (CurrentBlock == &F.getEntryBlock()) continue; | ||||||
|  |  | ||||||
|   if (isa<AllocaInst>(CurInst) || isa<TerminatorInst>(CurInst) || |     // Don't perform PRE on a landing pad. | ||||||
|       isa<PHINode>(CurInst) || CurInst->getType()->isVoidTy() || |     if (CurrentBlock->isLandingPad()) continue; | ||||||
|  |  | ||||||
|  |     for (BasicBlock::iterator BI = CurrentBlock->begin(), | ||||||
|  |          BE = CurrentBlock->end(); BI != BE; ) { | ||||||
|  |       Instruction *CurInst = BI++; | ||||||
|  |  | ||||||
|  |       if (isa<AllocaInst>(CurInst) || | ||||||
|  |           isa<TerminatorInst>(CurInst) || isa<PHINode>(CurInst) || | ||||||
|  |           CurInst->getType()->isVoidTy() || | ||||||
|           CurInst->mayReadFromMemory() || CurInst->mayHaveSideEffects() || |           CurInst->mayReadFromMemory() || CurInst->mayHaveSideEffects() || | ||||||
|           isa<DbgInfoIntrinsic>(CurInst)) |           isa<DbgInfoIntrinsic>(CurInst)) | ||||||
|     return false; |         continue; | ||||||
|  |  | ||||||
|       // Don't do PRE on compares. The PHI would prevent CodeGenPrepare from |       // Don't do PRE on compares. The PHI would prevent CodeGenPrepare from | ||||||
|       // sinking the compare again, and it would force the code generator to |       // sinking the compare again, and it would force the code generator to | ||||||
|       // move the i1 from processor flags or predicate registers into a general |       // move the i1 from processor flags or predicate registers into a general | ||||||
|       // purpose register. |       // purpose register. | ||||||
|       if (isa<CmpInst>(CurInst)) |       if (isa<CmpInst>(CurInst)) | ||||||
|     return false; |         continue; | ||||||
|  |  | ||||||
|       // We don't currently value number ANY inline asm calls. |       // We don't currently value number ANY inline asm calls. | ||||||
|       if (CallInst *CallI = dyn_cast<CallInst>(CurInst)) |       if (CallInst *CallI = dyn_cast<CallInst>(CurInst)) | ||||||
|         if (CallI->isInlineAsm()) |         if (CallI->isInlineAsm()) | ||||||
|       return false; |           continue; | ||||||
|  |  | ||||||
|       uint32_t ValNo = VN.lookup(CurInst); |       uint32_t ValNo = VN.lookup(CurInst); | ||||||
|  |  | ||||||
| @@ -2474,11 +2477,10 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|       unsigned NumWith = 0; |       unsigned NumWith = 0; | ||||||
|       unsigned NumWithout = 0; |       unsigned NumWithout = 0; | ||||||
|       BasicBlock *PREPred = nullptr; |       BasicBlock *PREPred = nullptr; | ||||||
|   BasicBlock *CurrentBlock = CurInst->getParent(); |  | ||||||
|       predMap.clear(); |       predMap.clear(); | ||||||
|  |  | ||||||
|   for (pred_iterator PI = pred_begin(CurrentBlock), PE = pred_end(CurrentBlock); |       for (pred_iterator PI = pred_begin(CurrentBlock), | ||||||
|        PI != PE; ++PI) { |            PE = pred_end(CurrentBlock); PI != PE; ++PI) { | ||||||
|         BasicBlock *P = *PI; |         BasicBlock *P = *PI; | ||||||
|         // We're not interested in PRE where the block is its |         // We're not interested in PRE where the block is its | ||||||
|         // own predecessor, or in blocks with predecessors |         // own predecessor, or in blocks with predecessors | ||||||
| @@ -2491,7 +2493,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     Value *predV = findLeader(P, ValNo); |         Value* predV = findLeader(P, ValNo); | ||||||
|         if (!predV) { |         if (!predV) { | ||||||
|           predMap.push_back(std::make_pair(static_cast<Value *>(nullptr), P)); |           predMap.push_back(std::make_pair(static_cast<Value *>(nullptr), P)); | ||||||
|           PREPred = P; |           PREPred = P; | ||||||
| @@ -2509,11 +2511,11 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|       // Don't do PRE when it might increase code size, i.e. when |       // Don't do PRE when it might increase code size, i.e. when | ||||||
|       // we would need to insert instructions in more than one pred. |       // we would need to insert instructions in more than one pred. | ||||||
|       if (NumWithout != 1 || NumWith == 0) |       if (NumWithout != 1 || NumWith == 0) | ||||||
|     return false; |         continue; | ||||||
|  |  | ||||||
|       // Don't do PRE across indirect branch. |       // Don't do PRE across indirect branch. | ||||||
|       if (isa<IndirectBrInst>(PREPred->getTerminator())) |       if (isa<IndirectBrInst>(PREPred->getTerminator())) | ||||||
|     return false; |         continue; | ||||||
|  |  | ||||||
|       // We can't do PRE safely on a critical edge, so instead we schedule |       // We can't do PRE safely on a critical edge, so instead we schedule | ||||||
|       // the edge to be split and perform the PRE the next time we iterate |       // the edge to be split and perform the PRE the next time we iterate | ||||||
| @@ -2521,7 +2523,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|       unsigned SuccNum = GetSuccessorNumber(PREPred, CurrentBlock); |       unsigned SuccNum = GetSuccessorNumber(PREPred, CurrentBlock); | ||||||
|       if (isCriticalEdge(PREPred->getTerminator(), SuccNum)) { |       if (isCriticalEdge(PREPred->getTerminator(), SuccNum)) { | ||||||
|         toSplit.push_back(std::make_pair(PREPred->getTerminator(), SuccNum)); |         toSplit.push_back(std::make_pair(PREPred->getTerminator(), SuccNum)); | ||||||
|     return false; |         continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       // Instantiate the expression in the predecessor that lacked it. |       // Instantiate the expression in the predecessor that lacked it. | ||||||
| @@ -2550,7 +2552,7 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|       if (!success) { |       if (!success) { | ||||||
|         DEBUG(verifyRemoved(PREInstr)); |         DEBUG(verifyRemoved(PREInstr)); | ||||||
|         delete PREInstr; |         delete PREInstr; | ||||||
|     return false; |         continue; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       PREInstr->insertBefore(PREPred->getTerminator()); |       PREInstr->insertBefore(PREPred->getTerminator()); | ||||||
| @@ -2563,9 +2565,9 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|       addToLeaderTable(ValNo, PREInstr, PREPred); |       addToLeaderTable(ValNo, PREInstr, PREPred); | ||||||
|  |  | ||||||
|       // Create a PHI to make the value available in this block. |       // Create a PHI to make the value available in this block. | ||||||
|   PHINode *Phi = |       PHINode* Phi = PHINode::Create(CurInst->getType(), predMap.size(), | ||||||
|       PHINode::Create(CurInst->getType(), predMap.size(), |                                      CurInst->getName() + ".pre-phi", | ||||||
|                       CurInst->getName() + ".pre-phi", CurrentBlock->begin()); |                                      CurrentBlock->begin()); | ||||||
|       for (unsigned i = 0, e = predMap.size(); i != e; ++i) { |       for (unsigned i = 0, e = predMap.size(); i != e; ++i) { | ||||||
|         if (Value *V = predMap[i].first) |         if (Value *V = predMap[i].first) | ||||||
|           Phi->addIncoming(V, predMap[i].second); |           Phi->addIncoming(V, predMap[i].second); | ||||||
| @@ -2581,7 +2583,8 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|         // Because we have added a PHI-use of the pointer value, it has now |         // Because we have added a PHI-use of the pointer value, it has now | ||||||
|         // "escaped" from alias analysis' perspective.  We need to inform |         // "escaped" from alias analysis' perspective.  We need to inform | ||||||
|         // AA of this. |         // AA of this. | ||||||
|     for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee; ++ii) { |         for (unsigned ii = 0, ee = Phi->getNumIncomingValues(); ii != ee; | ||||||
|  |              ++ii) { | ||||||
|           unsigned jj = PHINode::getOperandNumForIncomingValue(ii); |           unsigned jj = PHINode::getOperandNumForIncomingValue(ii); | ||||||
|           VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(jj)); |           VN.getAliasAnalysis()->addEscapingUse(Phi->getOperandUse(jj)); | ||||||
|         } |         } | ||||||
| @@ -2593,31 +2596,10 @@ bool GVN::performScalarPRE(Instruction *CurInst) { | |||||||
|       removeFromLeaderTable(ValNo, CurInst, CurrentBlock); |       removeFromLeaderTable(ValNo, CurInst, CurrentBlock); | ||||||
|  |  | ||||||
|       DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n'); |       DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n'); | ||||||
|   if (MD) |       if (MD) MD->removeInstruction(CurInst); | ||||||
|     MD->removeInstruction(CurInst); |  | ||||||
|       DEBUG(verifyRemoved(CurInst)); |       DEBUG(verifyRemoved(CurInst)); | ||||||
|       CurInst->eraseFromParent(); |       CurInst->eraseFromParent(); | ||||||
|   return true; |       Changed = true; | ||||||
| } |  | ||||||
|  |  | ||||||
| /// performPRE - Perform a purely local form of PRE that looks for diamond |  | ||||||
| /// control flow patterns and attempts to perform simple PRE at the join point. |  | ||||||
| bool GVN::performPRE(Function &F) { |  | ||||||
|   bool Changed = false; |  | ||||||
|   for (BasicBlock *CurrentBlock : depth_first(&F.getEntryBlock())) { |  | ||||||
|     // Nothing to PRE in the entry block. |  | ||||||
|     if (CurrentBlock == &F.getEntryBlock()) |  | ||||||
|       continue; |  | ||||||
|  |  | ||||||
|     // Don't perform PRE on a landing pad. |  | ||||||
|     if (CurrentBlock->isLandingPad()) |  | ||||||
|       continue; |  | ||||||
|  |  | ||||||
|     for (BasicBlock::iterator BI = CurrentBlock->begin(), |  | ||||||
|                               BE = CurrentBlock->end(); |  | ||||||
|          BI != BE;) { |  | ||||||
|       Instruction *CurInst = BI++; |  | ||||||
|       Changed = performScalarPRE(CurInst); |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -2655,21 +2637,25 @@ bool GVN::iterateOnFunction(Function &F) { | |||||||
|  |  | ||||||
|   // Top-down walk of the dominator tree |   // Top-down walk of the dominator tree | ||||||
|   bool Changed = false; |   bool Changed = false; | ||||||
|  | #if 0 | ||||||
|  |   // Needed for value numbering with phi construction to work. | ||||||
|  |   ReversePostOrderTraversal<Function*> RPOT(&F); | ||||||
|  |   for (ReversePostOrderTraversal<Function*>::rpo_iterator RI = RPOT.begin(), | ||||||
|  |        RE = RPOT.end(); RI != RE; ++RI) | ||||||
|  |     Changed |= processBlock(*RI); | ||||||
|  | #else | ||||||
|   // Save the blocks this function have before transformation begins. GVN may |   // Save the blocks this function have before transformation begins. GVN may | ||||||
|   // split critical edge, and hence may invalidate the RPO/DT iterator. |   // split critical edge, and hence may invalidate the RPO/DT iterator. | ||||||
|   // |   // | ||||||
|   std::vector<BasicBlock *> BBVect; |   std::vector<BasicBlock *> BBVect; | ||||||
|   BBVect.reserve(256); |   BBVect.reserve(256); | ||||||
|   // Needed for value numbering with phi construction to work. |   for (DomTreeNode *X : depth_first(DT->getRootNode())) | ||||||
|   ReversePostOrderTraversal<Function *> RPOT(&F); |     BBVect.push_back(X->getBlock()); | ||||||
|   for (ReversePostOrderTraversal<Function *>::rpo_iterator RI = RPOT.begin(), |  | ||||||
|                                                            RE = RPOT.end(); |  | ||||||
|        RI != RE; ++RI) |  | ||||||
|     BBVect.push_back(*RI); |  | ||||||
|  |  | ||||||
|   for (std::vector<BasicBlock *>::iterator I = BBVect.begin(), E = BBVect.end(); |   for (std::vector<BasicBlock *>::iterator I = BBVect.begin(), E = BBVect.end(); | ||||||
|        I != E; I++) |        I != E; I++) | ||||||
|     Changed |= processBlock(*I); |     Changed |= processBlock(*I); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   return Changed; |   return Changed; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -46,12 +46,12 @@ entry: | |||||||
|   br i1 %c, label %if.else, label %if.then |   br i1 %c, label %if.else, label %if.then | ||||||
|  |  | ||||||
| if.then: | if.then: | ||||||
|   %t = load i32* %p, !tbaa !3 |   %t = load i32* %p, !tbaa !4 | ||||||
|   store i32 %t, i32* %q |   store i32 %t, i32* %q | ||||||
|   ret void |   ret void | ||||||
|  |  | ||||||
| if.else: | if.else: | ||||||
|   %u = load i32* %p, !tbaa !4 |   %u = load i32* %p, !tbaa !3 | ||||||
|   store i32 %u, i32* %q |   store i32 %u, i32* %q | ||||||
|   ret void |   ret void | ||||||
| } | } | ||||||
| @@ -61,11 +61,11 @@ if.else: | |||||||
|  |  | ||||||
| ; CHECK: @watch_out_for_another_type_change | ; CHECK: @watch_out_for_another_type_change | ||||||
| ; CHECK: if.then: | ; CHECK: if.then: | ||||||
| ; CHECK:   store i32 0, i32* %q | ; CHECK:   %t = load i32* %p | ||||||
|  | ; CHECK:   store i32 %t, i32* %q | ||||||
| ; CHECK:   ret void | ; CHECK:   ret void | ||||||
| ; CHECK: if.else: | ; CHECK: if.else: | ||||||
| ; CHECK:   %u = load i32* %p | ; CHECK:   store i32 0, i32* %q | ||||||
| ; CHECK:   store i32 %u, i32* %q |  | ||||||
|  |  | ||||||
| define void @watch_out_for_another_type_change(i1 %c, i32* %p, i32* %p1, i32* %q) nounwind { | define void @watch_out_for_another_type_change(i1 %c, i32* %p, i32* %p1, i32* %q) nounwind { | ||||||
| entry: | entry: | ||||||
| @@ -74,12 +74,12 @@ entry: | |||||||
|   br i1 %c, label %if.else, label %if.then |   br i1 %c, label %if.else, label %if.then | ||||||
|  |  | ||||||
| if.then: | if.then: | ||||||
|   %t = load i32* %p, !tbaa !4 |   %t = load i32* %p, !tbaa !3 | ||||||
|   store i32 %t, i32* %q |   store i32 %t, i32* %q | ||||||
|   ret void |   ret void | ||||||
|  |  | ||||||
| if.else: | if.else: | ||||||
|   %u = load i32* %p, !tbaa !3 |   %u = load i32* %p, !tbaa !4 | ||||||
|   store i32 %u, i32* %q |   store i32 %u, i32* %q | ||||||
|   ret void |   ret void | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,49 +0,0 @@ | |||||||
| ; RUN: opt < %s -basicaa -gvn -enable-load-pre -S | FileCheck %s |  | ||||||
| target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" |  | ||||||
| target triple = "aarch64--linux-gnu" |  | ||||||
|  |  | ||||||
| define double @foo(i32 %stat, i32 %i, double** %p) { |  | ||||||
| ; CHECK-LABEL: @foo( |  | ||||||
| entry: |  | ||||||
|   switch i32 %stat, label %sw.default [ |  | ||||||
|     i32 0, label %sw.bb |  | ||||||
|     i32 1, label %sw.bb |  | ||||||
|     i32 2, label %sw.bb2 |  | ||||||
|   ] |  | ||||||
|  |  | ||||||
| sw.bb:                                            ; preds = %entry, %entry |  | ||||||
|   %idxprom = sext i32 %i to i64 |  | ||||||
|   %arrayidx = getelementptr inbounds double** %p, i64 0 |  | ||||||
|   %0 = load double** %arrayidx, align 8 |  | ||||||
|   %arrayidx1 = getelementptr inbounds double* %0, i64 %idxprom |  | ||||||
|   %1 = load double* %arrayidx1, align 8 |  | ||||||
|   %sub = fsub double %1, 1.000000e+00 |  | ||||||
|   %cmp = fcmp olt double %sub, 0.000000e+00 |  | ||||||
|   br i1 %cmp, label %if.then, label %if.end |  | ||||||
|  |  | ||||||
| if.then:                                          ; preds = %sw.bb |  | ||||||
|   br label %return |  | ||||||
|  |  | ||||||
| if.end:                                           ; preds = %sw.bb |  | ||||||
|   br label %sw.bb2 |  | ||||||
|  |  | ||||||
| sw.bb2:                                           ; preds = %if.end, %entry |  | ||||||
|   %idxprom3 = sext i32 %i to i64 |  | ||||||
|   %arrayidx4 = getelementptr inbounds double** %p, i64 0 |  | ||||||
|   %2 = load double** %arrayidx4, align 8 |  | ||||||
|   %arrayidx5 = getelementptr inbounds double* %2, i64 %idxprom3 |  | ||||||
|   %3 = load double* %arrayidx5, align 8 |  | ||||||
| ; CHECK: sw.bb2: |  | ||||||
| ; CHECK-NEXT-NOT: sext |  | ||||||
| ; CHECK-NEXT: phi double [ |  | ||||||
| ; CHECK-NOT: load |  | ||||||
|   %sub6 = fsub double 3.000000e+00, %3 |  | ||||||
|   br label %return |  | ||||||
|  |  | ||||||
| sw.default:                                       ; preds = %entry |  | ||||||
|   br label %return |  | ||||||
|  |  | ||||||
| return:                                           ; preds = %sw.default, %sw.bb2, %if.then |  | ||||||
|   %retval.0 = phi double [ 0.000000e+00, %sw.default ], [ %sub6, %sw.bb2 ], [ %sub, %if.then ] |  | ||||||
|   ret double %retval.0 |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user