diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineInternal.h | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp | 230 |
2 files changed, 0 insertions, 234 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index bf21359bdca..6b7bcd97e8f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -670,10 +670,6 @@ private: Instruction *FoldPHIArgGEPIntoPHI(PHINode &PN); Instruction *FoldPHIArgLoadIntoPHI(PHINode &PN); Instruction *FoldPHIArgZextsIntoPHI(PHINode &PN); - /// If an integer typed PHI has only one use which is an IntToPtr operation, - /// replace the PHI with an existing pointer typed PHI if it exists. Otherwise - /// insert a new pointer typed PHI and replace the original one. - Instruction *FoldIntegerTypedPHI(PHINode &PN); /// Helper function for FoldPHIArgXIntoPHI() to set debug location for the /// folded operation. diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp index 553f98cd581..2f31ede32ac 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -40,233 +40,6 @@ void InstCombiner::PHIArgMergedDebugLoc(Instruction *Inst, PHINode &PN) { } } -// Replace Integer typed PHI PN if the PHI's value is used as a pointer value. -// If there is an existing pointer typed PHI that produces the same value as PN, -// replace PN and the IntToPtr operation with it. Otherwise, synthesize a new -// PHI node: -// -// Case-1: -// bb1: -// int_init = PtrToInt(ptr_init) -// br label %bb2 -// bb2: -// int_val = PHI([int_init, %bb1], [int_val_inc, %bb2] -// ptr_val = PHI([ptr_init, %bb1], [ptr_val_inc, %bb2] -// ptr_val2 = IntToPtr(int_val) -// ... -// use(ptr_val2) -// ptr_val_inc = ... -// inc_val_inc = PtrToInt(ptr_val_inc) -// -// ==> -// bb1: -// br label %bb2 -// bb2: -// ptr_val = PHI([ptr_init, %bb1], [ptr_val_inc, %bb2] -// ... -// use(ptr_val) -// ptr_val_inc = ... -// -// Case-2: -// bb1: -// int_ptr = BitCast(ptr_ptr) -// int_init = Load(int_ptr) -// br label %bb2 -// bb2: -// int_val = PHI([int_init, %bb1], [int_val_inc, %bb2] -// ptr_val2 = IntToPtr(int_val) -// ... -// use(ptr_val2) -// ptr_val_inc = ... -// inc_val_inc = PtrToInt(ptr_val_inc) -// ==> -// bb1: -// ptr_init = Load(ptr_ptr) -// br label %bb2 -// bb2: -// ptr_val = PHI([ptr_init, %bb1], [ptr_val_inc, %bb2] -// ... -// use(ptr_val) -// ptr_val_inc = ... -// ... -// -Instruction *InstCombiner::FoldIntegerTypedPHI(PHINode &PN) { - if (!PN.getType()->isIntegerTy()) - return nullptr; - if (!PN.hasOneUse()) - return nullptr; - - auto *IntToPtr = dyn_cast<IntToPtrInst>(PN.user_back()); - if (!IntToPtr) - return nullptr; - - // Check if the pointer is actually used as pointer: - auto HasPointerUse = [](Instruction *IIP) { - for (User *U : IIP->users()) { - Value *Ptr = nullptr; - if (LoadInst *LoadI = dyn_cast<LoadInst>(U)) { - Ptr = LoadI->getPointerOperand(); - } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) { - Ptr = SI->getPointerOperand(); - } else if (GetElementPtrInst *GI = dyn_cast<GetElementPtrInst>(U)) { - Ptr = GI->getPointerOperand(); - } - - if (Ptr && Ptr == IIP) - return true; - } - return false; - }; - - if (!HasPointerUse(IntToPtr)) - return nullptr; - - if (DL.getPointerSizeInBits(IntToPtr->getAddressSpace()) != - DL.getTypeSizeInBits(IntToPtr->getOperand(0)->getType())) - return nullptr; - - SmallVector<Value *, 4> AvailablePtrVals; - for (unsigned i = 0; i != PN.getNumIncomingValues(); ++i) { - Value *Arg = PN.getIncomingValue(i); - - // First look backward: - if (auto *PI = dyn_cast<PtrToIntInst>(Arg)) { - AvailablePtrVals.emplace_back(PI->getOperand(0)); - continue; - } - - // Next look forward: - Value *ArgIntToPtr = nullptr; - for (User *U : Arg->users()) { - if (isa<IntToPtrInst>(U) && U->getType() == IntToPtr->getType() && - (DT.dominates(cast<Instruction>(U), PN.getIncomingBlock(i)) || - cast<Instruction>(U)->getParent() == PN.getIncomingBlock(i))) { - ArgIntToPtr = U; - break; - } - } - - if (ArgIntToPtr) { - AvailablePtrVals.emplace_back(ArgIntToPtr); - continue; - } - - // If Arg is defined by a PHI, allow it. This will also create - // more opportunities iteratively. - if (isa<PHINode>(Arg)) { - AvailablePtrVals.emplace_back(Arg); - continue; - } - - // For a single use integer load: - auto *LoadI = dyn_cast<LoadInst>(Arg); - if (!LoadI) - return nullptr; - - if (!LoadI->hasOneUse()) - return nullptr; - - // Push the integer typed Load instruction into the available - // value set, and fix it up later when the pointer typed PHI - // is synthesized. - AvailablePtrVals.emplace_back(LoadI); - } - - // Now search for a matching PHI - auto *BB = PN.getParent(); - assert(AvailablePtrVals.size() == PN.getNumIncomingValues() && - "Not enough available ptr typed incoming values"); - PHINode *MatchingPtrPHI = nullptr; - for (auto II = BB->begin(), EI = BasicBlock::iterator(BB->getFirstNonPHI()); - II != EI; II++) { - PHINode *PtrPHI = dyn_cast<PHINode>(II); - if (!PtrPHI || PtrPHI == &PN || PtrPHI->getType() != IntToPtr->getType()) - continue; - MatchingPtrPHI = PtrPHI; - for (unsigned i = 0; i != PtrPHI->getNumIncomingValues(); ++i) { - if (AvailablePtrVals[i] != PtrPHI->getIncomingValue(i)) { - MatchingPtrPHI = nullptr; - break; - } - } - - if (MatchingPtrPHI) - break; - } - - if (MatchingPtrPHI) { - assert(MatchingPtrPHI->getType() == IntToPtr->getType() && - "Phi's Type does not match with IntToPtr"); - // The PtrToCast + IntToPtr will be simplified later - return CastInst::CreateBitOrPointerCast(MatchingPtrPHI, - IntToPtr->getOperand(0)->getType()); - } - - // If it requires a conversion for every PHI operand, do not do it. - if (std::all_of(AvailablePtrVals.begin(), AvailablePtrVals.end(), - [&](Value *V) { - return (V->getType() != IntToPtr->getType()) || - isa<IntToPtrInst>(V); - })) - return nullptr; - - // If any of the operand that requires casting is a terminator - // instruction, do not do it. - if (std::any_of(AvailablePtrVals.begin(), AvailablePtrVals.end(), - [&](Value *V) { - return (V->getType() != IntToPtr->getType()) && - isa<TerminatorInst>(V); - })) - return nullptr; - - PHINode *NewPtrPHI = PHINode::Create( - IntToPtr->getType(), PN.getNumIncomingValues(), PN.getName() + ".ptr"); - - InsertNewInstBefore(NewPtrPHI, PN); - for (unsigned i = 0; i != PN.getNumIncomingValues(); ++i) { - auto *IncomingBB = PN.getIncomingBlock(i); - auto *IncomingVal = AvailablePtrVals[i]; - - if (IncomingVal->getType() == IntToPtr->getType()) { - NewPtrPHI->addIncoming(IncomingVal, IncomingBB); - continue; - } - -#ifndef NDEBUG - LoadInst *LoadI = dyn_cast<LoadInst>(IncomingVal); - assert((isa<PHINode>(IncomingVal) || - IncomingVal->getType()->isPointerTy() || - (LoadI && LoadI->hasOneUse())) && - "Can not replace LoadInst with multiple uses"); -#endif - // Need to insert a BitCast. - // For an integer Load instruction with a single use, the load + IntToPtr - // cast will be simplified into a pointer load: - // %v = load i64, i64* %a.ip, align 8 - // %v.cast = inttoptr i64 %v to float ** - // ==> - // %v.ptrp = bitcast i64 * %a.ip to float ** - // %v.cast = load float *, float ** %v.ptrp, align 8 - auto *CI = CastInst::CreateBitOrPointerCast( - IncomingVal, IntToPtr->getType(), IncomingVal->getName() + ".ptr"); - if (auto *IncomingI = dyn_cast<Instruction>(IncomingVal)) { - BasicBlock::iterator InsertPos(IncomingI); - InsertPos++; - if (isa<PHINode>(IncomingI)) - InsertPos = IncomingI->getParent()->getFirstInsertionPt(); - InsertNewInstBefore(CI, *InsertPos); - } else { - auto *InsertBB = &IncomingBB->getParent()->getEntryBlock(); - InsertNewInstBefore(CI, *InsertBB->getFirstInsertionPt()); - } - NewPtrPHI->addIncoming(CI, IncomingBB); - } - - // The PtrToCast + IntToPtr will be simplified later - return CastInst::CreateBitOrPointerCast(NewPtrPHI, - IntToPtr->getOperand(0)->getType()); -} - /// If we have something like phi [add (a,b), add(a,c)] and if a/b/c and the /// adds all have a single use, turn this into a phi and a single binop. Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { @@ -1130,9 +903,6 @@ Instruction *InstCombiner::visitPHINode(PHINode &PN) { // this PHI only has a single use (a PHI), and if that PHI only has one use (a // PHI)... break the cycle. if (PN.hasOneUse()) { - if (Instruction *Result = FoldIntegerTypedPHI(PN)) - return Result; - Instruction *PHIUser = cast<Instruction>(PN.user_back()); if (PHINode *PU = dyn_cast<PHINode>(PHIUser)) { SmallPtrSet<PHINode*, 16> PotentiallyDeadPHIs; |