diff options
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/ABCD.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/CodeGenPrepare.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 135 | ||||
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 74 | ||||
-rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LICM.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopStrengthReduce.cpp | 364 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/Reassociate.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 58 | ||||
-rw-r--r-- | lib/Transforms/Scalar/ScalarReplAggregates.cpp | 36 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 318 |
12 files changed, 563 insertions, 442 deletions
diff --git a/lib/Transforms/Scalar/ABCD.cpp b/lib/Transforms/Scalar/ABCD.cpp index cf5e8c0..ea8e5c3 100644 --- a/lib/Transforms/Scalar/ABCD.cpp +++ b/lib/Transforms/Scalar/ABCD.cpp @@ -505,7 +505,7 @@ void ABCD::executeABCD(Function &F) { continue; ICmpInst *ICI = dyn_cast<ICmpInst>(TI->getOperand(0)); - if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType())) + if (!ICI || !ICI->getOperand(0)->getType()->isIntegerTy()) continue; createConstraintCmpInst(ICI, TI); @@ -713,7 +713,7 @@ void ABCD::createConstraintCmpInst(ICmpInst *ICI, TerminatorInst *TI) { Value *V_op1 = ICI->getOperand(0); Value *V_op2 = ICI->getOperand(1); - if (!isa<IntegerType>(V_op1->getType())) + if (!V_op1->getType()->isIntegerTy()) return; Instruction *I_op1 = dyn_cast<Instruction>(V_op1); diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index 21e6f89..7ceda1f 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -612,7 +612,7 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr, // we'd end up sinking both muls. if (AddrMode.BaseReg) { Value *V = AddrMode.BaseReg; - if (isa<PointerType>(V->getType())) + if (V->getType()->isPointerTy()) V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt); if (V->getType() != IntPtrTy) V = CastInst::CreateIntegerCast(V, IntPtrTy, /*isSigned=*/true, @@ -625,7 +625,7 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr, Value *V = AddrMode.ScaledReg; if (V->getType() == IntPtrTy) { // done. - } else if (isa<PointerType>(V->getType())) { + } else if (V->getType()->isPointerTy()) { V = new PtrToIntInst(V, IntPtrTy, "sunkaddr", InsertPt); } else if (cast<IntegerType>(IntPtrTy)->getBitWidth() < cast<IntegerType>(V->getType())->getBitWidth()) { diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 3ce7482..fcb802a 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -662,11 +662,10 @@ namespace { bool runOnFunction(Function &F); public: static char ID; // Pass identification, replacement for typeid - explicit GVN(bool nopre = false, bool noloads = false) - : FunctionPass(&ID), NoPRE(nopre), NoLoads(noloads), MD(0) { } + explicit GVN(bool noloads = false) + : FunctionPass(&ID), NoLoads(noloads), MD(0) { } private: - bool NoPRE; bool NoLoads; MemoryDependenceAnalysis *MD; DominatorTree *DT; @@ -674,6 +673,9 @@ namespace { ValueTable VN; DenseMap<BasicBlock*, ValueNumberScope*> localAvail; + // List of critical edges to be split between iterations. + SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit; + // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<DominatorTree>(); @@ -701,14 +703,15 @@ namespace { Value *lookupNumber(BasicBlock *BB, uint32_t num); void cleanupGlobalSets(); void verifyRemoved(const Instruction *I) const; + bool splitCriticalEdges(); }; char GVN::ID = 0; } // createGVNPass - The public interface to this file... -FunctionPass *llvm::createGVNPass(bool NoPRE, bool NoLoads) { - return new GVN(NoPRE, NoLoads); +FunctionPass *llvm::createGVNPass(bool NoLoads) { + return new GVN(NoLoads); } static RegisterPass<GVN> X("gvn", @@ -836,9 +839,9 @@ static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, const TargetData &TD) { // If the loaded or stored value is an first class array or struct, don't try // to transform them. We need to be able to bitcast to integer. - if (isa<StructType>(LoadTy) || isa<ArrayType>(LoadTy) || - isa<StructType>(StoredVal->getType()) || - isa<ArrayType>(StoredVal->getType())) + if (LoadTy->isStructTy() || LoadTy->isArrayTy() || + StoredVal->getType()->isStructTy() || + StoredVal->getType()->isArrayTy()) return false; // The store has to be at least as big as the load. @@ -870,26 +873,26 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, // If the store and reload are the same size, we can always reuse it. if (StoreSize == LoadSize) { - if (isa<PointerType>(StoredValTy) && isa<PointerType>(LoadedTy)) { + if (StoredValTy->isPointerTy() && LoadedTy->isPointerTy()) { // Pointer to Pointer -> use bitcast. return new BitCastInst(StoredVal, LoadedTy, "", InsertPt); } // Convert source pointers to integers, which can be bitcast. - if (isa<PointerType>(StoredValTy)) { + if (StoredValTy->isPointerTy()) { StoredValTy = TD.getIntPtrType(StoredValTy->getContext()); StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt); } const Type *TypeToCastTo = LoadedTy; - if (isa<PointerType>(TypeToCastTo)) + if (TypeToCastTo->isPointerTy()) TypeToCastTo = TD.getIntPtrType(StoredValTy->getContext()); if (StoredValTy != TypeToCastTo) StoredVal = new BitCastInst(StoredVal, TypeToCastTo, "", InsertPt); // Cast to pointer if the load needs a pointer type. - if (isa<PointerType>(LoadedTy)) + if (LoadedTy->isPointerTy()) StoredVal = new IntToPtrInst(StoredVal, LoadedTy, "", InsertPt); return StoredVal; @@ -901,13 +904,13 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, assert(StoreSize >= LoadSize && "CanCoerceMustAliasedValueToLoad fail"); // Convert source pointers to integers, which can be manipulated. - if (isa<PointerType>(StoredValTy)) { + if (StoredValTy->isPointerTy()) { StoredValTy = TD.getIntPtrType(StoredValTy->getContext()); StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt); } // Convert vectors and fp to integer, which can be manipulated. - if (!isa<IntegerType>(StoredValTy)) { + if (!StoredValTy->isIntegerTy()) { StoredValTy = IntegerType::get(StoredValTy->getContext(), StoreSize); StoredVal = new BitCastInst(StoredVal, StoredValTy, "", InsertPt); } @@ -927,7 +930,7 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, return StoredVal; // If the result is a pointer, inttoptr. - if (isa<PointerType>(LoadedTy)) + if (LoadedTy->isPointerTy()) return new IntToPtrInst(StoredVal, LoadedTy, "inttoptr", InsertPt); // Otherwise, bitcast. @@ -989,7 +992,7 @@ static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr, const TargetData &TD) { // If the loaded or stored value is an first class array or struct, don't try // to transform them. We need to be able to bitcast to integer. - if (isa<StructType>(LoadTy) || isa<ArrayType>(LoadTy)) + if (LoadTy->isStructTy() || LoadTy->isArrayTy()) return -1; int64_t StoreOffset = 0, LoadOffset = 0; @@ -1064,8 +1067,8 @@ static int AnalyzeLoadFromClobberingStore(const Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const TargetData &TD) { // Cannot handle reading from store of first-class aggregate yet. - if (isa<StructType>(DepSI->getOperand(0)->getType()) || - isa<ArrayType>(DepSI->getOperand(0)->getType())) + if (DepSI->getOperand(0)->getType()->isStructTy() || + DepSI->getOperand(0)->getType()->isArrayTy()) return -1; Value *StorePtr = DepSI->getPointerOperand(); @@ -1136,9 +1139,9 @@ static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset, // Compute which bits of the stored value are being used by the load. Convert // to an integer type to start with. - if (isa<PointerType>(SrcVal->getType())) + if (SrcVal->getType()->isPointerTy()) SrcVal = Builder.CreatePtrToInt(SrcVal, TD.getIntPtrType(Ctx), "tmp"); - if (!isa<IntegerType>(SrcVal->getType())) + if (!SrcVal->getType()->isIntegerTy()) SrcVal = Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize*8), "tmp"); @@ -1323,7 +1326,7 @@ static Value *ConstructSSAForLoadSet(LoadInst *LI, Value *V = SSAUpdate.GetValueInMiddleOfBlock(LI->getParent()); // If new PHI nodes were created, notify alias analysis. - if (isa<PointerType>(V->getType())) + if (V->getType()->isPointerTy()) for (unsigned i = 0, e = NewPHIs.size(); i != e; ++i) AA->copyValue(LI, NewPHIs[i]); @@ -1491,8 +1494,9 @@ bool GVN::processNonLocalLoad(LoadInst *LI, if (isa<PHINode>(V)) V->takeName(LI); - if (isa<PointerType>(V->getType())) + if (V->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(V); + VN.erase(LI); toErase.push_back(LI); NumGVNLoad++; return true; @@ -1538,11 +1542,13 @@ bool GVN::processNonLocalLoad(LoadInst *LI, // at least one of the values is LI. Since this means that we won't be able // to eliminate LI even if we insert uses in the other predecessors, we will // end up increasing code size. Reject this by scanning for LI. - if (!EnableFullLoadPRE) { - for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) - if (ValuesPerBlock[i].isSimpleValue() && - ValuesPerBlock[i].getSimpleValue() == LI) + for (unsigned i = 0, e = ValuesPerBlock.size(); i != e; ++i) { + if (ValuesPerBlock[i].isSimpleValue() && + ValuesPerBlock[i].getSimpleValue() == LI) { + // Skip cases where LI is the only definition, even for EnableFullLoadPRE. + if (!EnableFullLoadPRE || e == 1) return false; + } } // FIXME: It is extremely unclear what this loop is doing, other than @@ -1576,6 +1582,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI, for (unsigned i = 0, e = UnavailableBlocks.size(); i != e; ++i) FullyAvailableBlocks[UnavailableBlocks[i]] = false; + bool NeedToSplitEdges = false; for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB); PI != E; ++PI) { BasicBlock *Pred = *PI; @@ -1583,13 +1590,20 @@ bool GVN::processNonLocalLoad(LoadInst *LI, continue; } PredLoads[Pred] = 0; - // We don't currently handle critical edges :( + if (Pred->getTerminator()->getNumSuccessors() != 1) { - DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '" - << Pred->getName() << "': " << *LI << '\n'); - return false; + if (isa<IndirectBrInst>(Pred->getTerminator())) { + DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '" + << Pred->getName() << "': " << *LI << '\n'); + return false; + } + unsigned SuccNum = GetSuccessorNumber(Pred, LoadBB); + toSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum)); + NeedToSplitEdges = true; } } + if (NeedToSplitEdges) + return false; // Decide whether PRE is profitable for this load. unsigned NumUnavailablePreds = PredLoads.size(); @@ -1623,13 +1637,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI, LoadPtr = Address.PHITranslateWithInsertion(LoadBB, UnavailablePred, *DT, NewInsts); } else { - Address.PHITranslateValue(LoadBB, UnavailablePred); + Address.PHITranslateValue(LoadBB, UnavailablePred, DT); LoadPtr = Address.getAddr(); - - // Make sure the value is live in the predecessor. - if (Instruction *Inst = dyn_cast_or_null<Instruction>(LoadPtr)) - if (!DT->dominates(Inst->getParent(), UnavailablePred)) - LoadPtr = 0; } // If we couldn't find or insert a computation of this phi translated value, @@ -1697,6 +1706,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI, // Add the newly created load. ValuesPerBlock.push_back(AvailableValueInBlock::get(UnavailablePred, NewLoad)); + MD->invalidateCachedPointerInfo(LoadPtr); + DEBUG(dbgs() << "GVN INSERTED " << *NewLoad << '\n'); } // Perform PHI construction. @@ -1705,8 +1716,9 @@ bool GVN::processNonLocalLoad(LoadInst *LI, LI->replaceAllUsesWith(V); if (isa<PHINode>(V)) V->takeName(LI); - if (isa<PointerType>(V->getType())) + if (V->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(V); + VN.erase(LI); toErase.push_back(LI); NumPRELoad++; return true; @@ -1765,8 +1777,9 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { // Replace the load! L->replaceAllUsesWith(AvailVal); - if (isa<PointerType>(AvailVal->getType())) + if (AvailVal->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(AvailVal); + VN.erase(L); toErase.push_back(L); NumGVNLoad++; return true; @@ -1810,8 +1823,9 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { // Remove it! L->replaceAllUsesWith(StoredVal); - if (isa<PointerType>(StoredVal->getType())) + if (StoredVal->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(StoredVal); + VN.erase(L); toErase.push_back(L); NumGVNLoad++; return true; @@ -1839,8 +1853,9 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { // Remove it! L->replaceAllUsesWith(AvailableVal); - if (isa<PointerType>(DepLI->getType())) + if (DepLI->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(DepLI); + VN.erase(L); toErase.push_back(L); NumGVNLoad++; return true; @@ -1851,6 +1866,7 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { // intervening stores, for example. if (isa<AllocaInst>(DepInst) || isMalloc(DepInst)) { L->replaceAllUsesWith(UndefValue::get(L->getType())); + VN.erase(L); toErase.push_back(L); NumGVNLoad++; return true; @@ -1861,6 +1877,7 @@ bool GVN::processLoad(LoadInst *L, SmallVectorImpl<Instruction*> &toErase) { if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(DepInst)) { if (II->getIntrinsicID() == Intrinsic::lifetime_start) { L->replaceAllUsesWith(UndefValue::get(L->getType())); + VN.erase(L); toErase.push_back(L); NumGVNLoad++; return true; @@ -1943,7 +1960,7 @@ bool GVN::processInstruction(Instruction *I, if (constVal) { p->replaceAllUsesWith(constVal); - if (MD && isa<PointerType>(constVal->getType())) + if (MD && constVal->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(constVal); VN.erase(p); @@ -1964,7 +1981,7 @@ bool GVN::processInstruction(Instruction *I, // Remove it! VN.erase(I); I->replaceAllUsesWith(repl); - if (MD && isa<PointerType>(repl->getType())) + if (MD && repl->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(repl); toErase.push_back(I); return true; @@ -2004,6 +2021,8 @@ bool GVN::runOnFunction(Function& F) { while (ShouldContinue) { DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n"); ShouldContinue = iterateOnFunction(F); + if (splitCriticalEdges()) + ShouldContinue = true; Changed |= ShouldContinue; ++Iteration; } @@ -2070,7 +2089,6 @@ bool GVN::processBlock(BasicBlock *BB) { /// control flow patterns and attempts to perform simple PRE at the join point. bool GVN::performPRE(Function &F) { bool Changed = false; - SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit; DenseMap<BasicBlock*, Value*> predMap; for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()), DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) { @@ -2141,14 +2159,7 @@ bool GVN::performPRE(Function &F) { // 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 // on the function. - unsigned SuccNum = 0; - for (unsigned i = 0, e = PREPred->getTerminator()->getNumSuccessors(); - i != e; ++i) - if (PREPred->getTerminator()->getSuccessor(i) == CurrentBlock) { - SuccNum = i; - break; - } - + unsigned SuccNum = GetSuccessorNumber(PREPred, CurrentBlock); if (isCriticalEdge(PREPred->getTerminator(), SuccNum)) { toSplit.push_back(std::make_pair(PREPred->getTerminator(), SuccNum)); continue; @@ -2204,7 +2215,7 @@ bool GVN::performPRE(Function &F) { localAvail[CurrentBlock]->table[ValNo] = Phi; CurInst->replaceAllUsesWith(Phi); - if (MD && isa<PointerType>(Phi->getType())) + if (MD && Phi->getType()->isPointerTy()) MD->invalidateCachedPointerInfo(Phi); VN.erase(CurInst); @@ -2216,11 +2227,23 @@ bool GVN::performPRE(Function &F) { } } - for (SmallVector<std::pair<TerminatorInst*, unsigned>, 4>::iterator - I = toSplit.begin(), E = toSplit.end(); I != E; ++I) - SplitCriticalEdge(I->first, I->second, this); + if (splitCriticalEdges()) + Changed = true; - return Changed || toSplit.size(); + return Changed; +} + +/// splitCriticalEdges - Split critical edges found during the previous +/// iteration that may enable further optimization. +bool GVN::splitCriticalEdges() { + if (toSplit.empty()) + return false; + do { + std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val(); + SplitCriticalEdge(Edge.first, Edge.second, this); + } while (!toSplit.empty()); + if (MD) MD->invalidateCachedPredecessors(); + return true; } /// iterateOnFunction - Executes one iteration of GVN diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 5302fdc..cb563c3 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -103,11 +103,9 @@ namespace { BasicBlock *ExitingBlock, BranchInst *BI, SCEVExpander &Rewriter); - void RewriteLoopExitValues(Loop *L, const SCEV *BackedgeTakenCount, - SCEVExpander &Rewriter); + void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter); - void RewriteIVExpressions(Loop *L, const Type *LargestType, - SCEVExpander &Rewriter); + void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter); void SinkUnusedInvariants(Loop *L); @@ -190,7 +188,7 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L, ICmpInst *Cond = new ICmpInst(BI, Opcode, CmpIndVar, ExitCnt, "exitcond"); - Instruction *OrigCond = cast<Instruction>(BI->getCondition()); + Value *OrigCond = BI->getCondition(); // It's tempting to use replaceAllUsesWith here to fully replace the old // comparison, but that's not immediately safe, since users of the old // comparison may not be dominated by the new comparison. Instead, just @@ -215,7 +213,6 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L, /// able to brute-force evaluate arbitrary instructions as long as they have /// constant operands at the beginning of the loop. void IndVarSimplify::RewriteLoopExitValues(Loop *L, - const SCEV *BackedgeTakenCount, SCEVExpander &Rewriter) { // Verify the input to the pass in already in LCSSA form. assert(L->isLCSSAForm()); @@ -241,15 +238,24 @@ void IndVarSimplify::RewriteLoopExitValues(Loop *L, while ((PN = dyn_cast<PHINode>(BBI++))) { if (PN->use_empty()) continue; // dead use, don't replace it + + // SCEV only supports integer expressions for now. + if (!PN->getType()->isIntegerTy() && !PN->getType()->isPointerTy()) + continue; + + // It's necessary to tell ScalarEvolution about this explicitly so that + // it can walk the def-use list and forget all SCEVs, as it may not be + // watching the PHI itself. Once the new exit value is in place, there + // may not be a def-use connection between the loop and every instruction + // which got a SCEVAddRecExpr for that loop. + SE->forgetValue(PN); + // Iterate over all of the values in all the PHI nodes. for (unsigned i = 0; i != NumPreds; ++i) { // If the value being merged in is not integer or is not defined // in the loop, skip it. Value *InVal = PN->getIncomingValue(i); - if (!isa<Instruction>(InVal) || - // SCEV only supports integer expressions for now. - (!isa<IntegerType>(InVal->getType()) && - !isa<PointerType>(InVal->getType()))) + if (!isa<Instruction>(InVal)) continue; // If this pred is for a subloop, not L itself, skip it. @@ -349,7 +355,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { // the current expressions. // if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount)) - RewriteLoopExitValues(L, BackedgeTakenCount, Rewriter); + RewriteLoopExitValues(L, Rewriter); // Compute the type of the largest recurrence expression, and decide whether // a canonical induction variable should be inserted. @@ -378,17 +384,18 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { // in this loop, insert a canonical induction variable of the largest size. Value *IndVar = 0; if (NeedCannIV) { - // Check to see if the loop already has a canonical-looking induction - // variable. If one is present and it's wider than the planned canonical - // induction variable, temporarily remove it, so that the Rewriter - // doesn't attempt to reuse it. - PHINode *OldCannIV = L->getCanonicalInductionVariable(); - if (OldCannIV) { + // Check to see if the loop already has any canonical-looking induction + // variables. If any are present and wider than the planned canonical + // induction variable, temporarily remove them, so that the Rewriter + // doesn't attempt to reuse them. + SmallVector<PHINode *, 2> OldCannIVs; + while (PHINode *OldCannIV = L->getCanonicalInductionVariable()) { if (SE->getTypeSizeInBits(OldCannIV->getType()) > SE->getTypeSizeInBits(LargestType)) OldCannIV->removeFromParent(); else - OldCannIV = 0; + break; + OldCannIVs.push_back(OldCannIV); } IndVar = Rewriter.getOrInsertCanonicalInductionVariable(L, LargestType); @@ -398,17 +405,21 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { DEBUG(dbgs() << "INDVARS: New CanIV: " << *IndVar << '\n'); // Now that the official induction variable is established, reinsert - // the old canonical-looking variable after it so that the IR remains - // consistent. It will be deleted as part of the dead-PHI deletion at + // any old canonical-looking variables after it so that the IR remains + // consistent. They will be deleted as part of the dead-PHI deletion at // the end of the pass. - if (OldCannIV) - OldCannIV->insertAfter(cast<Instruction>(IndVar)); + while (!OldCannIVs.empty()) { + PHINode *OldCannIV = OldCannIVs.pop_back_val(); + OldCannIV->insertBefore(L->getHeader()->getFirstNonPHI()); + } } // If we have a trip count expression, rewrite the loop's exit condition // using it. We can currently only handle loops with a single exit. ICmpInst *NewICmp = 0; - if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) && ExitingBlock) { + if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) && + !BackedgeTakenCount->isZero() && + ExitingBlock) { assert(NeedCannIV && "LinearFunctionTestReplace requires a canonical induction variable"); // Can't rewrite non-branch yet. @@ -418,7 +429,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { } // Rewrite IV-derived expressions. Clears the rewriter cache. - RewriteIVExpressions(L, LargestType, Rewriter); + RewriteIVExpressions(L, Rewriter); // The Rewriter may not be used from this point on. @@ -438,8 +449,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { return Changed; } -void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType, - SCEVExpander &Rewriter) { +void IndVarSimplify::RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter) { SmallVector<WeakVH, 16> DeadInsts; // Rewrite all induction variable expressions in terms of the canonical @@ -584,8 +594,8 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) { } } -/// Return true if it is OK to use SIToFPInst for an inducation variable -/// with given inital and exit values. +/// Return true if it is OK to use SIToFPInst for an induction variable +/// with given initial and exit values. static bool useSIToFPInst(ConstantFP &InitV, ConstantFP &ExitV, uint64_t intIV, uint64_t intEV) { @@ -638,7 +648,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH) { if (!convertToInt(InitValue->getValueAPF(), &newInitValue)) return; - // Check IV increment. Reject this PH if increement operation is not + // Check IV increment. Reject this PH if increment operation is not // an add or increment value can not be represented by an integer. BinaryOperator *Incr = dyn_cast<BinaryOperator>(PH->getIncomingValue(BackEdge)); @@ -674,7 +684,7 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH) { if (BI->getCondition() != EC) return; } - // Find exit value. If exit value can not be represented as an interger then + // Find exit value. If exit value can not be represented as an integer then // do not handle this floating point PH. ConstantFP *EV = NULL; unsigned EVIndex = 1; @@ -736,11 +746,11 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PH) { ICmpInst *NewEC = new ICmpInst(EC->getParent()->getTerminator(), NewPred, LHS, RHS, EC->getName()); - // In the following deltions, PH may become dead and may be deleted. + // In the following deletions, PH may become dead and may be deleted. // Use a WeakVH to observe whether this happens. WeakVH WeakPH = PH; - // Delete old, floating point, exit comparision instruction. + // Delete old, floating point, exit comparison instruction. NewEC->takeName(EC); EC->replaceAllUsesWith(NewEC); RecursivelyDeleteTriviallyDeadInstructions(EC); diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 8f21aac..a6489ec 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -201,7 +201,7 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB) { if (isa<DbgInfoIntrinsic>(I)) continue; // If this is a pointer->pointer bitcast, it is free. - if (isa<BitCastInst>(I) && isa<PointerType>(I->getType())) + if (isa<BitCastInst>(I) && I->getType()->isPointerTy()) continue; // All other instructions count for at least one unit. @@ -214,7 +214,7 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB) { if (const CallInst *CI = dyn_cast<CallInst>(I)) { if (!isa<IntrinsicInst>(CI)) Size += 3; - else if (!isa<VectorType>(CI->getType())) + else if (!CI->getType()->isVectorTy()) Size += 1; } } diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index 81f9ae6..d7ace342 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -678,7 +678,7 @@ void LICM::PromoteValuesInLoop() { // If we are promoting a pointer value, update alias information for the // inserted load. Value *LoadValue = 0; - if (isa<PointerType>(cast<PointerType>(Ptr->getType())->getElementType())) { + if (cast<PointerType>(Ptr->getType())->getElementType()->isPointerTy()) { // Locate a load or store through the pointer, and assign the same value // to LI as we are loading or storing. Since we know that the value is // stored in this loop, this will always succeed. @@ -751,7 +751,7 @@ void LICM::PromoteValuesInLoop() { LoadInst *LI = new LoadInst(PromotedValues[i].first, "", InsertPos); // If this is a pointer type, update alias info appropriately. - if (isa<PointerType>(LI->getType())) + if (LI->getType()->isPointerTy()) CurAST->copyValue(PointerValueNumbers[PVN++], LI); // Store into the memory we promoted. diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 240b298..f920dca 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -198,7 +198,7 @@ struct Formula { } -/// DoInitialMatch - Recurrsion helper for InitialMatch. +/// DoInitialMatch - Recursion helper for InitialMatch. static void DoInitialMatch(const SCEV *S, Loop *L, SmallVectorImpl<const SCEV *> &Good, SmallVectorImpl<const SCEV *> &Bad, @@ -337,14 +337,42 @@ void Formula::dump() const { print(errs()); errs() << '\n'; } -/// getSDiv - Return an expression for LHS /s RHS, if it can be determined, -/// or null otherwise. If IgnoreSignificantBits is true, expressions like -/// (X * Y) /s Y are simplified to Y, ignoring that the multiplication may -/// overflow, which is useful when the result will be used in a context where -/// the most significant bits are ignored. -static const SCEV *getSDiv(const SCEV *LHS, const SCEV *RHS, - ScalarEvolution &SE, - bool IgnoreSignificantBits = false) { +/// isAddRecSExtable - Return true if the given addrec can be sign-extended +/// without changing its value. +static bool isAddRecSExtable(const SCEVAddRecExpr *AR, ScalarEvolution &SE) { + const Type *WideTy = + IntegerType::get(SE.getContext(), + SE.getTypeSizeInBits(AR->getType()) + 1); + return isa<SCEVAddRecExpr>(SE.getSignExtendExpr(AR, WideTy)); +} + +/// isAddSExtable - Return true if the given add can be sign-extended +/// without changing its value. +static bool isAddSExtable(const SCEVAddExpr *A, ScalarEvolution &SE) { + const Type *WideTy = + IntegerType::get(SE.getContext(), + SE.getTypeSizeInBits(A->getType()) + 1); + return isa<SCEVAddExpr>(SE.getSignExtendExpr(A, WideTy)); +} + +/// isMulSExtable - Return true if the given add can be sign-extended +/// without changing its value. +static bool isMulSExtable(const SCEVMulExpr *A, ScalarEvolution &SE) { + const Type *WideTy = + IntegerType::get(SE.getContext(), + SE.getTypeSizeInBits(A->getType()) + 1); + return isa<SCEVMulExpr>(SE.getSignExtendExpr(A, WideTy)); +} + +/// getExactSDiv - Return an expression for LHS /s RHS, if it can be determined +/// and if the remainder is known to be zero, or null otherwise. If +/// IgnoreSignificantBits is true, expressions like (X * Y) /s Y are simplified +/// to Y, ignoring that the multiplication may overflow, which is useful when +/// the result will be used in a context where the most significant bits are +/// ignored. +static const SCEV *getExactSDiv(const SCEV *LHS, const SCEV *RHS, + ScalarEvolution &SE, + bool IgnoreSignificantBits = false) { // Handle the trivial case, which works for any SCEV type. if (LHS == RHS) return SE.getIntegerSCEV(1, LHS->getType()); @@ -365,39 +393,44 @@ static const SCEV *getSDiv(const SCEV *LHS, const SCEV *RHS, .sdiv(RC->getValue()->getValue())); } - // Distribute the sdiv over addrec operands. + // Distribute the sdiv over addrec operands, if the addrec doesn't overflow. if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS)) { - const SCEV *Start = getSDiv(AR->getStart(), RHS, SE, - IgnoreSignificantBits); - if (!Start) return 0; - const SCEV *Step = getSDiv(AR->getStepRecurrence(SE), RHS, SE, - IgnoreSignificantBits); - if (!Step) return 0; - return SE.getAddRecExpr(Start, Step, AR->getLoop()); + if (IgnoreSignificantBits || isAddRecSExtable(AR, SE)) { + const SCEV *Start = getExactSDiv(AR->getStart(), RHS, SE, + IgnoreSignificantBits); + if (!Start) return 0; + const SCEV *Step = getExactSDiv(AR->getStepRecurrence(SE), RHS, SE, + IgnoreSignificantBits); + if (!Step) return 0; + return SE.getAddRecExpr(Start, Step, AR->getLoop()); + } } - // Distribute the sdiv over add operands. + // Distribute the sdiv over add operands, if the add doesn't overflow. if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(LHS)) { - SmallVector<const SCEV *, 8> Ops; - for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end(); - I != E; ++I) { - const SCEV *Op = getSDiv(*I, RHS, SE, - IgnoreSignificantBits); - if (!Op) return 0; - Ops.push_back(Op); + if (IgnoreSignificantBits || isAddSExtable(Add, SE)) { + SmallVector<const SCEV *, 8> Ops; + for (SCEVAddExpr::op_iterator I = Add->op_begin(), E = Add->op_end(); + I != E; ++I) { + const SCEV *Op = getExactSDiv(*I, RHS, SE, + IgnoreSignificantBits); + if (!Op) return 0; + Ops.push_back(Op); + } + return SE.getAddExpr(Ops); } - return SE.getAddExpr(Ops); } // Check for a multiply operand that we can pull RHS out of. if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(LHS)) - if (IgnoreSignificantBits || Mul->hasNoSignedWrap()) { + if (IgnoreSignificantBits || isMulSExtable(Mul, SE)) { SmallVector<const SCEV *, 4> Ops; bool Found = false; for (SCEVMulExpr::op_iterator I = Mul->op_begin(), E = Mul->op_end(); I != E; ++I) { if (!Found) - if (const SCEV *Q = getSDiv(*I, RHS, SE, IgnoreSignificantBits)) { + if (const SCEV *Q = getExactSDiv(*I, RHS, SE, + IgnoreSignificantBits)) { Ops.push_back(Q); Found = true; continue; @@ -640,9 +673,9 @@ void Cost::RateRegister(const SCEV *Reg, /// RatePrimaryRegister - Record this register in the set. If we haven't seen it /// before, rate it. void Cost::RatePrimaryRegister(const SCEV *Reg, - SmallPtrSet<const SCEV *, 16> &Regs, - const Loop *L, - ScalarEvolution &SE, DominatorTree &DT) { + SmallPtrSet<const SCEV *, 16> &Regs, + const Loop *L, + ScalarEvolution &SE, DominatorTree &DT) { if (Regs.insert(Reg)) RateRegister(Reg, Regs, L, SE, DT); } @@ -879,7 +912,7 @@ public: MaxOffset(INT64_MIN), AllFixupsOutsideLoop(true) {} - bool InsertFormula(size_t LUIdx, const Formula &F); + bool InsertFormula(const Formula &F); void check() const; @@ -889,7 +922,7 @@ public: /// InsertFormula - If the given formula has not yet been inserted, add it to /// the list, and return true. Return false otherwise. -bool LSRUse::InsertFormula(size_t LUIdx, const Formula &F) { +bool LSRUse::InsertFormula(const Formula &F) { SmallVector<const SCEV *, 2> Key = F.BaseRegs; if (F.ScaledReg) Key.push_back(F.ScaledReg); // Unstable sort by host order ok, because this is only used for uniquifying. @@ -925,7 +958,7 @@ void LSRUse::print(raw_ostream &OS) const { case ICmpZero: OS << "ICmpZero"; break; case Address: OS << "Address of "; - if (isa<PointerType>(AccessTy)) + if (AccessTy->isPointerTy()) OS << "pointer"; // the full pointer type could be really verbose else OS << *AccessTy; @@ -1024,8 +1057,7 @@ static bool isAlwaysFoldable(int64_t BaseOffs, GlobalValue *BaseGV, bool HasBaseReg, LSRUse::KindType Kind, const Type *AccessTy, - const TargetLowering *TLI, - ScalarEvolution &SE) { + const TargetLowering *TLI) { // Fast-path: zero is always foldable. if (BaseOffs == 0 && !BaseGV) return true; @@ -1153,7 +1185,7 @@ class LSRInstance { const Type *AccessTy); public: - void InsertInitialFormula(const SCEV *S, Loop *L, LSRUse &LU, size_t LUIdx); + void InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx); void InsertSupplementalFormula(const SCEV *S, LSRUse &LU, size_t LUIdx); void CountRegisters(const Formula &F, size_t LUIdx); bool InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F); @@ -1184,16 +1216,18 @@ public: Value *Expand(const LSRFixup &LF, const Formula &F, - BasicBlock::iterator IP, Loop *L, Instruction *IVIncInsertPos, + BasicBlock::iterator IP, SCEVExpander &Rewriter, - SmallVectorImpl<WeakVH> &DeadInsts, - ScalarEvolution &SE, DominatorTree &DT) const; + SmallVectorImpl<WeakVH> &DeadInsts) const; + void RewriteForPHI(PHINode *PN, const LSRFixup &LF, + const Formula &F, + SCEVExpander &Rewriter, + SmallVectorImpl<WeakVH> &DeadInsts, + Pass *P) const; void Rewrite(const LSRFixup &LF, const Formula &F, - Loop *L, Instruction *IVIncInsertPos, SCEVExpander &Rewriter, SmallVectorImpl<WeakVH> &DeadInsts, - ScalarEvolution &SE, DominatorTree &DT, Pass *P) const; void ImplementSolution(const SmallVectorImpl<const Formula *> &Solution, Pass *P); @@ -1212,7 +1246,7 @@ public: } /// OptimizeShadowIV - If IV is used in a int-to-float cast -/// inside the loop then try to eliminate the cast opeation. +/// inside the loop then try to eliminate the cast operation. void LSRInstance::OptimizeShadowIV() { const SCEV *BackedgeTakenCount = SE.getBackedgeTakenCount(L); if (isa<SCEVCouldNotCompute>(BackedgeTakenCount)) @@ -1522,7 +1556,7 @@ LSRInstance::OptimizeLoopTermCond() { A = SE.getSignExtendExpr(A, B->getType()); } if (const SCEVConstant *D = - dyn_cast_or_null<SCEVConstant>(getSDiv(B, A, SE))) { + dyn_cast_or_null<SCEVConstant>(getExactSDiv(B, A, SE))) { // Stride of one or negative one can have reuse with non-addresses. if (D->getValue()->isOne() || D->getValue()->isAllOnesValue()) @@ -1615,12 +1649,12 @@ LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset, // Conservatively assume HasBaseReg is true for now. if (NewOffset < LU.MinOffset) { if (!isAlwaysFoldable(LU.MaxOffset - NewOffset, 0, /*HasBaseReg=*/true, - Kind, AccessTy, TLI, SE)) + Kind, AccessTy, TLI)) return false; NewMinOffset = NewOffset; } else if (NewOffset > LU.MaxOffset) { if (!isAlwaysFoldable(NewOffset - LU.MinOffset, 0, /*HasBaseReg=*/true, - Kind, AccessTy, TLI, SE)) + Kind, AccessTy, TLI)) return false; NewMaxOffset = NewOffset; } @@ -1639,7 +1673,7 @@ LSRInstance::reconcileNewOffset(LSRUse &LU, int64_t NewOffset, /// getUse - Return an LSRUse index and an offset value for a fixup which /// needs the given expression, with the given kind and optional access type. -/// Either reuse an exisitng use or create a new one, as needed. +/// Either reuse an existing use or create a new one, as needed. std::pair<size_t, int64_t> LSRInstance::getUse(const SCEV *&Expr, LSRUse::KindType Kind, const Type *AccessTy) { @@ -1647,8 +1681,7 @@ LSRInstance::getUse(const SCEV *&Expr, int64_t Offset = ExtractImmediate(Expr, SE); // Basic uses can't accept any offset, for example. - if (!isAlwaysFoldable(Offset, 0, /*HasBaseReg=*/true, - Kind, AccessTy, TLI, SE)) { + if (!isAlwaysFoldable(Offset, 0, /*HasBaseReg=*/true, Kind, AccessTy, TLI)) { Expr = Copy; Offset = 0; } @@ -1683,21 +1716,29 @@ LSRInstance::getUse(const SCEV *&Expr, void LSRInstance::CollectInterestingTypesAndFactors() { SmallSetVector<const SCEV *, 4> Strides; - // Collect interesting types and factors. + // Collect interesting types and strides. for (IVUsers::const_iterator UI = IU.begin(), E = IU.end(); UI != E; ++UI) { const SCEV *Stride = UI->getStride(); // Collect interesting types. Types.insert(SE.getEffectiveSCEVType(Stride->getType())); - // Collect interesting factors. + // Add the stride for this loop. + Strides.insert(Stride); + + // Add strides for other mentioned loops. + for (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(UI->getOffset()); + AR; AR = dyn_cast<SCEVAddRecExpr>(AR->getStart())) + Strides.insert(AR->getStepRecurrence(SE)); + } + + // Compute interesting factors from the set of interesting strides. + for (SmallSetVector<const SCEV *, 4>::const_iterator + I = Strides.begin(), E = Strides.end(); I != E; ++I) for (SmallSetVector<const SCEV *, 4>::const_iterator NewStrideIter = - Strides.begin(), SEnd = Strides.end(); NewStrideIter != SEnd; - ++NewStrideIter) { - const SCEV *OldStride = Stride; + next(I); NewStrideIter != E; ++NewStrideIter) { + const SCEV *OldStride = *I; const SCEV *NewStride = *NewStrideIter; - if (OldStride == NewStride) - continue; if (SE.getTypeSizeInBits(OldStride->getType()) != SE.getTypeSizeInBits(NewStride->getType())) { @@ -1708,19 +1749,18 @@ void LSRInstance::CollectInterestingTypesAndFactors() { OldStride = SE.getSignExtendExpr(OldStride, NewStride->getType()); } if (const SCEVConstant *Factor = - dyn_cast_or_null<SCEVConstant>(getSDiv(NewStride, OldStride, - SE, true))) { + dyn_cast_or_null<SCEVConstant>(getExactSDiv(NewStride, OldStride, + SE, true))) { if (Factor->getValue()->getValue().getMinSignedBits() <= 64) Factors.insert(Factor->getValue()->getValue().getSExtValue()); } else if (const SCEVConstant *Factor = - dyn_cast_or_null<SCEVConstant>(getSDiv(OldStride, NewStride, - SE, true))) { + dyn_cast_or_null<SCEVConstant>(getExactSDiv(OldStride, + NewStride, + SE, true))) { if (Factor->getValue()->getValue().getMinSignedBits() <= 64) Factors.insert(Factor->getValue()->getValue().getSExtValue()); } } - Strides.insert(Stride); - } // If all uses use the same type, don't bother looking for truncation-based // reuse. @@ -1788,7 +1828,7 @@ void LSRInstance::CollectFixupsAndInitialFormulae() { // If this is the first use of this LSRUse, give it a formula. if (LU.Formulae.empty()) { - InsertInitialFormula(S, L, LU, LF.LUIdx); + InsertInitialFormula(S, LU, LF.LUIdx); CountRegisters(LU.Formulae.back(), LF.LUIdx); } } @@ -1797,8 +1837,7 @@ void LSRInstance::CollectFixupsAndInitialFormulae() { } void -LSRInstance::InsertInitialFormula(const SCEV *S, Loop *L, - LSRUse &LU, size_t LUIdx) { +LSRInstance::InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx) { Formula F; F.InitialMatch(S, L, SE, DT); bool Inserted = InsertFormula(LU, LUIdx, F); @@ -1828,7 +1867,7 @@ void LSRInstance::CountRegisters(const Formula &F, size_t LUIdx) { /// InsertFormula - If the given formula has not yet been inserted, add it to /// the list, and return true. Return false otherwise. bool LSRInstance::InsertFormula(LSRUse &LU, unsigned LUIdx, const Formula &F) { - if (!LU.InsertFormula(LUIdx, F)) + if (!LU.InsertFormula(F)) return false; CountRegisters(F, LUIdx); @@ -1996,7 +2035,7 @@ void LSRInstance::GenerateReassociations(LSRUse &LU, unsigned LUIdx, /// loop-dominating registers added into a single register. void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx, Formula Base) { - // This method is only intersting on a plurality of registers. + // This method is only interesting on a plurality of registers. if (Base.BaseRegs.size() <= 1) return; Formula F = Base; @@ -2015,7 +2054,7 @@ void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx, const SCEV *Sum = SE.getAddExpr(Ops); // TODO: If Sum is zero, it probably means ScalarEvolution missed an // opportunity to fold something. For now, just ignore such cases - // rather than procede with zero in a register. + // rather than proceed with zero in a register. if (!Sum->isZero()) { F.BaseRegs.push_back(Sum); (void)InsertFormula(LU, LUIdx, F); @@ -2105,14 +2144,18 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, Formula F = Base; // Check that the multiplication doesn't overflow. + if (F.AM.BaseOffs == INT64_MIN && Factor == -1) + continue; F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs * Factor; - if ((int64_t)F.AM.BaseOffs / Factor != Base.AM.BaseOffs) + if (F.AM.BaseOffs / Factor != Base.AM.BaseOffs) continue; // Check that multiplying with the use offset doesn't overflow. int64_t Offset = LU.MinOffset; + if (Offset == INT64_MIN && Factor == -1) + continue; Offset = (uint64_t)Offset * Factor; - if ((int64_t)Offset / Factor != LU.MinOffset) + if (Offset / Factor != LU.MinOffset) continue; // Check that this scale is legal. @@ -2127,14 +2170,14 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx, // Check that multiplying with each base register doesn't overflow. for (size_t i = 0, e = F.BaseRegs.size(); i != e; ++i) { F.BaseRegs[i] = SE.getMulExpr(F.BaseRegs[i], FactorS); - if (getSDiv(F.BaseRegs[i], FactorS, SE) != Base.BaseRegs[i]) + if (getExactSDiv(F.BaseRegs[i], FactorS, SE) != Base.BaseRegs[i]) goto next; } // Check that multiplying with the scaled register doesn't overflow. if (F.ScaledReg) { F.ScaledReg = SE.getMulExpr(F.ScaledReg, FactorS); - if (getSDiv(F.ScaledReg, FactorS, SE) != Base.ScaledReg) + if (getExactSDiv(F.ScaledReg, FactorS, SE) != Base.ScaledReg) continue; } @@ -2189,7 +2232,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, continue; // Divide out the factor, ignoring high bits, since we'll be // scaling the value back up in the end. - if (const SCEV *Quotient = getSDiv(AR, FactorS, SE, true)) { + if (const SCEV *Quotient = getExactSDiv(AR, FactorS, SE, true)) { // TODO: This could be optimized to avoid all the copying. Formula F = Base; F.ScaledReg = Quotient; @@ -2358,7 +2401,7 @@ void LSRInstance::GenerateCrossUseConstantOffsets() { const SCEV *NegImmS = SE.getSCEV(ConstantInt::get(IntTy, -(uint64_t)Imm)); unsigned BitWidth = SE.getTypeSizeInBits(IntTy); - // TODO: Use a more targetted data structure. + // TODO: Use a more targeted data structure. for (size_t L = 0, LE = LU.Formulae.size(); L != LE; ++L) { Formula F = LU.Formulae[L]; // Use the immediate in the scaled register. @@ -2526,9 +2569,9 @@ void LSRInstance::FilterOutUndesirableDedicatedRegisters() { }); } -/// NarrowSearchSpaceUsingHeuristics - If there are an extrordinary number of +/// NarrowSearchSpaceUsingHeuristics - If there are an extraordinary number of /// formulae to choose from, use some rough heuristics to prune down the number -/// of formulae. This keeps the main solver from taking an extrordinary amount +/// of formulae. This keeps the main solver from taking an extraordinary amount /// of time in some worst-case scenarios. void LSRInstance::NarrowSearchSpaceUsingHeuristics() { // This is a rough guess that seems to work fairly well. @@ -2578,7 +2621,7 @@ void LSRInstance::NarrowSearchSpaceUsingHeuristics() { } DEBUG(dbgs() << "Narrowing the search space by assuming " << *Best - << " will yeild profitable reuse.\n"); + << " will yield profitable reuse.\n"); Taken.insert(Best); // In any use with formulae which references this register, delete formulae @@ -2625,7 +2668,7 @@ void LSRInstance::SolveRecurse(SmallVectorImpl<const Formula *> &Solution, // - sort the formula so that the most profitable solutions are found first // - sort the uses too // - search faster: - // - dont compute a cost, and then compare. compare while computing a cost + // - don't compute a cost, and then compare. compare while computing a cost // and bail early. // - track register sets with SmallBitVector @@ -2736,10 +2779,8 @@ static BasicBlock *getImmediateDominator(BasicBlock *BB, DominatorTree &DT) { Value *LSRInstance::Expand(const LSRFixup &LF, const Formula &F, BasicBlock::iterator IP, - Loop *L, Instruction *IVIncInsertPos, SCEVExpander &Rewriter, - SmallVectorImpl<WeakVH> &DeadInsts, - ScalarEvolution &SE, DominatorTree &DT) const { + SmallVectorImpl<WeakVH> &DeadInsts) const { const LSRUse &LU = Uses[LF.LUIdx]; // Then, collect some instructions which we will remain dominated by when @@ -2752,8 +2793,12 @@ Value *LSRInstance::Expand(const LSRFixup &LF, if (Instruction *I = dyn_cast<Instruction>(cast<ICmpInst>(LF.UserInst)->getOperand(1))) Inputs.push_back(I); - if (LF.PostIncLoop && !L->contains(LF.UserInst)) - Inputs.push_back(L->getLoopLatch()->getTerminator()); + if (LF.PostIncLoop) { + if (!L->contains(LF.UserInst)) + Inputs.push_back(L->getLoopLatch()->getTerminator()); + else + Inputs.push_back(IVIncInsertPos); + } // Then, climb up the immediate dominator tree as far as we can go while // still being dominated by the input positions. @@ -2816,8 +2861,10 @@ Value *LSRInstance::Expand(const LSRFixup &LF, if (AR->getLoop() == LF.PostIncLoop) { Reg = SE.getAddExpr(Reg, AR->getStepRecurrence(SE)); // If the user is inside the loop, insert the code after the increment - // so that it is dominated by its operand. - if (L->contains(LF.UserInst)) + // so that it is dominated by its operand. If the original insert point + // was already dominated by the increment, keep it, because there may + // be loop-variant operands that need to be respected also. + if (L->contains(LF.UserInst) && !DT.dominates(IVIncInsertPos, IP)) IP = IVIncInsertPos; break; } @@ -2827,6 +2874,13 @@ Value *LSRInstance::Expand(const LSRFixup &LF, Ops.push_back(SE.getUnknown(Rewriter.expandCodeFor(Reg, 0, IP))); } + // Flush the operand list to suppress SCEVExpander hoisting. + if (!Ops.empty()) { + Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP); + Ops.clear(); + Ops.push_back(SE.getUnknown(FullV)); + } + // Expand the ScaledReg portion. Value *ICmpScaledV = 0; if (F.AM.Scale != 0) { @@ -2853,12 +2907,25 @@ Value *LSRInstance::Expand(const LSRFixup &LF, SE.getIntegerSCEV(F.AM.Scale, ScaledS->getType())); Ops.push_back(ScaledS); + + // Flush the operand list to suppress SCEVExpander hoisting. + Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP); + Ops.clear(); + Ops.push_back(SE.getUnknown(FullV)); } } - // Expand the immediate portions. - if (F.AM.BaseGV) - Ops.push_back(SE.getSCEV(F.AM.BaseGV)); + // Expand the GV portion. + if (F.AM.BaseGV) { + Ops.push_back(SE.getUnknown(F.AM.BaseGV)); + + // Flush the operand list to suppress SCEVExpander hoisting. + Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP); + Ops.clear(); + Ops.push_back(SE.getUnknown(FullV)); + } + + // Expand the immediate portion. int64_t Offset = (uint64_t)F.AM.BaseOffs + LF.Offset; if (Offset != 0) { if (LU.Kind == LSRUse::ICmpZero) { @@ -2873,7 +2940,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF, } else { // Just add the immediate values. These again are expected to be matched // as part of the address. - Ops.push_back(SE.getIntegerSCEV(Offset, IntTy)); + Ops.push_back(SE.getUnknown(ConstantInt::getSigned(IntTy, Offset))); } } @@ -2921,73 +2988,81 @@ Value *LSRInstance::Expand(const LSRFixup &LF, return FullV; } +/// RewriteForPHI - Helper for Rewrite. PHI nodes are special because the use +/// of their operands effectively happens in their predecessor blocks, so the +/// expression may need to be expanded in multiple places. +void LSRInstance::RewriteForPHI(PHINode *PN, + const LSRFixup &LF, + const Formula &F, + SCEVExpander &Rewriter, + SmallVectorImpl<WeakVH> &DeadInsts, + Pass *P) const { + DenseMap<BasicBlock *, Value *> Inserted; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == LF.OperandValToReplace) { + BasicBlock *BB = PN->getIncomingBlock(i); + + // If this is a critical edge, split the edge so that we do not insert + // the code on all predecessor/successor paths. We do this unless this + // is the canonical backedge for this loop, which complicates post-inc + // users. + if (e != 1 && BB->getTerminator()->getNumSuccessors() > 1 && + !isa<IndirectBrInst>(BB->getTerminator()) && + (PN->getParent() != L->getHeader() || !L->contains(BB))) { + // Split the critical edge. + BasicBlock *NewBB = SplitCriticalEdge(BB, PN->getParent(), P); + + // If PN is outside of the loop and BB is in the loop, we want to + // move the block to be immediately before the PHI block, not + // immediately after BB. + if (L->contains(BB) && !L->contains(PN)) + NewBB->moveBefore(PN->getParent()); + + // Splitting the edge can reduce the number of PHI entries we have. + e = PN->getNumIncomingValues(); + BB = NewBB; + i = PN->getBasicBlockIndex(BB); + } + + std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> Pair = + Inserted.insert(std::make_pair(BB, static_cast<Value *>(0))); + if (!Pair.second) + PN->setIncomingValue(i, Pair.first->second); + else { + Value *FullV = Expand(LF, F, BB->getTerminator(), Rewriter, DeadInsts); + + // If this is reuse-by-noop-cast, insert the noop cast. + const Type *OpTy = LF.OperandValToReplace->getType(); + if (FullV->getType() != OpTy) + FullV = + CastInst::Create(CastInst::getCastOpcode(FullV, false, + OpTy, false), + FullV, LF.OperandValToReplace->getType(), + "tmp", BB->getTerminator()); + + PN->setIncomingValue(i, FullV); + Pair.first->second = FullV; + } + } +} + /// Rewrite - Emit instructions for the leading candidate expression for this /// LSRUse (this is called "expanding"), and update the UserInst to reference /// the newly expanded value. void LSRInstance::Rewrite(const LSRFixup &LF, const Formula &F, - Loop *L, Instruction *IVIncInsertPos, SCEVExpander &Rewriter, SmallVectorImpl<WeakVH> &DeadInsts, - ScalarEvolution &SE, DominatorTree &DT, Pass *P) const { - const Type *OpTy = LF.OperandValToReplace->getType(); - // First, find an insertion point that dominates UserInst. For PHI nodes, // find the nearest block which dominates all the relevant uses. if (PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) { - DenseMap<BasicBlock *, Value *> Inserted; - for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) - if (PN->getIncomingValue(i) == LF.OperandValToReplace) { - BasicBlock *BB = PN->getIncomingBlock(i); - - // If this is a critical edge, split the edge so that we do not insert - // the code on all predecessor/successor paths. We do this unless this - // is the canonical backedge for this loop, which complicates post-inc - // users. - if (e != 1 && BB->getTerminator()->getNumSuccessors() > 1 && - !isa<IndirectBrInst>(BB->getTerminator()) && - (PN->getParent() != L->getHeader() || !L->contains(BB))) { - // Split the critical edge. - BasicBlock *NewBB = SplitCriticalEdge(BB, PN->getParent(), P); - - // If PN is outside of the loop and BB is in the loop, we want to - // move the block to be immediately before the PHI block, not - // immediately after BB. - if (L->contains(BB) && !L->contains(PN)) - NewBB->moveBefore(PN->getParent()); - - // Splitting the edge can reduce the number of PHI entries we have. - e = PN->getNumIncomingValues(); - BB = NewBB; - i = PN->getBasicBlockIndex(BB); - } - - std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> Pair = - Inserted.insert(std::make_pair(BB, static_cast<Value *>(0))); - if (!Pair.second) - PN->setIncomingValue(i, Pair.first->second); - else { - Value *FullV = Expand(LF, F, BB->getTerminator(), L, IVIncInsertPos, - Rewriter, DeadInsts, SE, DT); - - // If this is reuse-by-noop-cast, insert the noop cast. - if (FullV->getType() != OpTy) - FullV = - CastInst::Create(CastInst::getCastOpcode(FullV, false, - OpTy, false), - FullV, LF.OperandValToReplace->getType(), - "tmp", BB->getTerminator()); - - PN->setIncomingValue(i, FullV); - Pair.first->second = FullV; - } - } + RewriteForPHI(PN, LF, F, Rewriter, DeadInsts, P); } else { - Value *FullV = Expand(LF, F, LF.UserInst, L, IVIncInsertPos, - Rewriter, DeadInsts, SE, DT); + Value *FullV = Expand(LF, F, LF.UserInst, Rewriter, DeadInsts); // If this is reuse-by-noop-cast, insert the noop cast. + const Type *OpTy = LF.OperandValToReplace->getType(); if (FullV->getType() != OpTy) { Instruction *Cast = CastInst::Create(CastInst::getCastOpcode(FullV, false, OpTy, false), @@ -3024,8 +3099,7 @@ LSRInstance::ImplementSolution(const SmallVectorImpl<const Formula *> &Solution, for (size_t i = 0, e = Fixups.size(); i != e; ++i) { size_t LUIdx = Fixups[i].LUIdx; - Rewrite(Fixups[i], *Solution[LUIdx], L, IVIncInsertPos, Rewriter, - DeadInsts, SE, DT, P); + Rewrite(Fixups[i], *Solution[LUIdx], Rewriter, DeadInsts, P); Changed = true; } @@ -3054,7 +3128,7 @@ LSRInstance::LSRInstance(const TargetLowering *tli, Loop *l, Pass *P) dbgs() << ":\n"); /// OptimizeShadowIV - If IV is used in a int-to-float cast - /// inside the loop then try to eliminate the cast opeation. + /// inside the loop then try to eliminate the cast operation. OptimizeShadowIV(); // Change loop terminating condition to use the postinc iv when possible. diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 990e0c4..071e9b7 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -170,7 +170,7 @@ Pass *llvm::createLoopUnswitchPass(bool Os) { /// Otherwise, return null. static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) { // We can never unswitch on vector conditions. - if (isa<VectorType>(Cond->getType())) + if (Cond->getType()->isVectorTy()) return 0; // Constants should be folded, not unswitched on! diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 187216a..12827b6 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -930,7 +930,7 @@ void Reassociate::ReassociateBB(BasicBlock *BB) { // Reject cases where it is pointless to do this. if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPointTy() || - isa<VectorType>(BI->getType())) + BI->getType()->isVectorTy()) continue; // Floating point ops are not associative. // Do not reassociate boolean (i1) expressions. We want to preserve the diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 02b45a1..7e37938 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -295,7 +295,7 @@ public: } void markOverdefined(Value *V) { - assert(!isa<StructType>(V->getType()) && "Should use other method"); + assert(!V->getType()->isStructTy() && "Should use other method"); markOverdefined(ValueState[V], V); } @@ -321,12 +321,12 @@ private: } void markConstant(Value *V, Constant *C) { - assert(!isa<StructType>(V->getType()) && "Should use other method"); + assert(!V->getType()->isStructTy() && "Should use other method"); markConstant(ValueState[V], V, C); } void markForcedConstant(Value *V, Constant *C) { - assert(!isa<StructType>(V->getType()) && "Should use other method"); + assert(!V->getType()->isStructTy() && "Should use other method"); ValueState[V].markForcedConstant(C); DEBUG(dbgs() << "markForcedConstant: " << *C << ": " << *V << '\n'); InstWorkList.push_back(V); @@ -360,7 +360,7 @@ private: } void mergeInValue(Value *V, LatticeVal MergeWithV) { - assert(!isa<StructType>(V->getType()) && "Should use other method"); + assert(!V->getType()->isStructTy() && "Should use other method"); mergeInValue(ValueState[V], V, MergeWithV); } @@ -369,7 +369,7 @@ private: /// value. This function handles the case when the value hasn't been seen yet /// by properly seeding constants etc. LatticeVal &getValueState(Value *V) { - assert(!isa<StructType>(V->getType()) && "Should use getStructValueState"); + assert(!V->getType()->isStructTy() && "Should use getStructValueState"); std::pair<DenseMap<Value*, LatticeVal>::iterator, bool> I = ValueState.insert(std::make_pair(V, LatticeVal())); @@ -392,7 +392,7 @@ private: /// value/field pair. This function handles the case when the value hasn't /// been seen yet by properly seeding constants etc. LatticeVal &getStructValueState(Value *V, unsigned i) { - assert(isa<StructType>(V->getType()) && "Should use getValueState"); + assert(V->getType()->isStructTy() && "Should use getValueState"); assert(i < cast<StructType>(V->getType())->getNumElements() && "Invalid element #"); @@ -666,7 +666,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) { void SCCPSolver::visitPHINode(PHINode &PN) { // If this PN returns a struct, just mark the result overdefined. // TODO: We could do a lot better than this if code actually uses this. - if (isa<StructType>(PN.getType())) + if (PN.getType()->isStructTy()) return markAnythingOverdefined(&PN); if (getValueState(&PN).isOverdefined()) { @@ -742,7 +742,7 @@ void SCCPSolver::visitReturnInst(ReturnInst &I) { Value *ResultOp = I.getOperand(0); // If we are tracking the return value of this function, merge it in. - if (!TrackedRetVals.empty() && !isa<StructType>(ResultOp->getType())) { + if (!TrackedRetVals.empty() && !ResultOp->getType()->isStructTy()) { DenseMap<Function*, LatticeVal>::iterator TFRVI = TrackedRetVals.find(F); if (TFRVI != TrackedRetVals.end()) { @@ -787,7 +787,7 @@ void SCCPSolver::visitCastInst(CastInst &I) { void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { // If this returns a struct, mark all elements over defined, we don't track // structs in structs. - if (isa<StructType>(EVI.getType())) + if (EVI.getType()->isStructTy()) return markAnythingOverdefined(&EVI); // If this is extracting from more than one level of struct, we don't know. @@ -795,7 +795,7 @@ void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { return markOverdefined(&EVI); Value *AggVal = EVI.getAggregateOperand(); - if (isa<StructType>(AggVal->getType())) { + if (AggVal->getType()->isStructTy()) { unsigned i = *EVI.idx_begin(); LatticeVal EltVal = getStructValueState(AggVal, i); mergeInValue(getValueState(&EVI), &EVI, EltVal); @@ -828,7 +828,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) { } Value *Val = IVI.getInsertedValueOperand(); - if (isa<StructType>(Val->getType())) + if (Val->getType()->isStructTy()) // We don't track structs in structs. markOverdefined(getStructValueState(&IVI, i), &IVI); else { @@ -841,7 +841,7 @@ void SCCPSolver::visitInsertValueInst(InsertValueInst &IVI) { void SCCPSolver::visitSelectInst(SelectInst &I) { // If this select returns a struct, just mark the result overdefined. // TODO: We could do a lot better than this if code actually uses this. - if (isa<StructType>(I.getType())) + if (I.getType()->isStructTy()) return markAnythingOverdefined(&I); LatticeVal CondValue = getValueState(I.getCondition()); @@ -1166,7 +1166,7 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) { void SCCPSolver::visitStoreInst(StoreInst &SI) { // If this store is of a struct, ignore it. - if (isa<StructType>(SI.getOperand(0)->getType())) + if (SI.getOperand(0)->getType()->isStructTy()) return; if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.getOperand(1))) @@ -1187,7 +1187,7 @@ void SCCPSolver::visitStoreInst(StoreInst &SI) { // global, we can replace the load with the loaded constant value! void SCCPSolver::visitLoadInst(LoadInst &I) { // If this load is of a struct, just mark the result overdefined. - if (isa<StructType>(I.getType())) + if (I.getType()->isStructTy()) return markAnythingOverdefined(&I); LatticeVal PtrVal = getValueState(I.getOperand(0)); @@ -1241,7 +1241,7 @@ CallOverdefined: // Otherwise, if we have a single return value case, and if the function is // a declaration, maybe we can constant fold it. - if (F && F->isDeclaration() && !isa<StructType>(I->getType()) && + if (F && F->isDeclaration() && !I->getType()->isStructTy() && canConstantFoldCallTo(F)) { SmallVector<Constant*, 8> Operands; @@ -1352,7 +1352,7 @@ void SCCPSolver::Solve() { // since all of its users will have already been marked as overdefined. // Update all of the users of this instruction's value. // - if (isa<StructType>(I->getType()) || !getValueState(I).isOverdefined()) + if (I->getType()->isStructTy() || !getValueState(I).isOverdefined()) for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) if (Instruction *I = dyn_cast<Instruction>(*UI)) @@ -1418,7 +1418,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { if (!LV.isUndefined()) continue; // No instructions using structs need disambiguation. - if (isa<StructType>(I->getOperand(0)->getType())) + if (I->getOperand(0)->getType()->isStructTy()) continue; // Get the lattice values of the first two operands for use below. @@ -1426,7 +1426,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) { LatticeVal Op1LV; if (I->getNumOperands() == 2) { // No instructions using structs need disambiguation. - if (isa<StructType>(I->getOperand(1)->getType())) + if (I->getOperand(1)->getType()->isStructTy()) continue; // If this is a two-operand instruction, and if both operands are @@ -1656,7 +1656,7 @@ bool SCCP::runOnFunction(Function &F) { continue; // TODO: Reconstruct structs from their elements. - if (isa<StructType>(Inst->getType())) + if (Inst->getType()->isStructTy()) continue; LatticeVal IV = Solver.getLatticeValueFor(Inst); @@ -1792,7 +1792,7 @@ bool IPSCCP::runOnModule(Module &M) { if (Solver.isBlockExecutable(F->begin())) { for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) { - if (AI->use_empty() || isa<StructType>(AI->getType())) continue; + if (AI->use_empty() || AI->getType()->isStructTy()) continue; // TODO: Could use getStructLatticeValueFor to find out if the entire // result is a constant and replace it entirely if so. @@ -1835,7 +1835,7 @@ bool IPSCCP::runOnModule(Module &M) { for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) { Instruction *Inst = BI++; - if (Inst->getType()->isVoidTy() || isa<StructType>(Inst->getType())) + if (Inst->getType()->isVoidTy() || Inst->getType()->isStructTy()) continue; // TODO: Could use getStructLatticeValueFor to find out if the entire @@ -1918,6 +1918,14 @@ bool IPSCCP::runOnModule(Module &M) { // all call uses with the inferred value. This means we don't need to bother // actually returning anything from the function. Replace all return // instructions with return undef. + // + // Do this in two stages: first identify the functions we should process, then + // actually zap their returns. This is important because we can only do this + // if the address of the function isn't taken. In cases where a return is the + // last use of a function, the order of processing functions would affect + // whether other functions are optimizable. + SmallVector<ReturnInst*, 8> ReturnsToZap; + // TODO: Process multiple value ret instructions also. const DenseMap<Function*, LatticeVal> &RV = Solver.getTrackedRetVals(); for (DenseMap<Function*, LatticeVal>::const_iterator I = RV.begin(), @@ -1933,7 +1941,13 @@ bool IPSCCP::runOnModule(Module &M) { for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) if (!isa<UndefValue>(RI->getOperand(0))) - RI->setOperand(0, UndefValue::get(F->getReturnType())); + ReturnsToZap.push_back(RI); + } + + // Zap all returns which we've identified as zap to change. + for (unsigned i = 0, e = ReturnsToZap.size(); i != e; ++i) { + Function *F = ReturnsToZap[i]->getParent()->getParent(); + ReturnsToZap[i]->setOperand(0, UndefValue::get(F->getReturnType())); } // If we infered constant or undef values for globals variables, we can delete diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 822712e..bbe6270 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -302,7 +302,7 @@ bool SROA::performScalarRepl(Function &F) { // random stuff that doesn't use vectors (e.g. <9 x double>) because then // we just get a lot of insert/extracts. If at least one vector is // involved, then we probably really do have a union of vector/array. - if (VectorTy && isa<VectorType>(VectorTy) && HadAVector) { + if (VectorTy && VectorTy->isVectorTy() && HadAVector) { DEBUG(dbgs() << "CONVERT TO VECTOR: " << *AI << "\n TYPE = " << *VectorTy << '\n'); @@ -449,7 +449,7 @@ void SROA::isSafeGEP(GetElementPtrInst *GEPI, AllocaInst *AI, // into. for (; GEPIt != E; ++GEPIt) { // Ignore struct elements, no extra checking needed for these. - if (isa<StructType>(*GEPIt)) + if ((*GEPIt)->isStructTy()) continue; ConstantInt *IdxVal = dyn_cast<ConstantInt>(GEPIt.getOperand()); @@ -480,7 +480,7 @@ void SROA::isSafeMemAccess(AllocaInst *AI, uint64_t Offset, uint64_t MemSize, // (which are essentially the same as the MemIntrinsics, especially with // regard to copying padding between elements), or references using the // aggregate type of the alloca. - if (!MemOpType || isa<IntegerType>(MemOpType) || UsesAggregateType) { + if (!MemOpType || MemOpType->isIntegerTy() || UsesAggregateType) { if (!UsesAggregateType) { if (isStore) Info.isMemCpyDst = true; @@ -565,7 +565,7 @@ void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, } LI->replaceAllUsesWith(Insert); DeadInsts.push_back(LI); - } else if (isa<IntegerType>(LIType) && + } else if (LIType->isIntegerTy() && TD->getTypeAllocSize(LIType) == TD->getTypeAllocSize(AI->getAllocatedType())) { // If this is a load of the entire alloca to an integer, rewrite it. @@ -588,7 +588,7 @@ void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset, new StoreInst(Extract, NewElts[i], SI); } DeadInsts.push_back(SI); - } else if (isa<IntegerType>(SIType) && + } else if (SIType->isIntegerTy() && TD->getTypeAllocSize(SIType) == TD->getTypeAllocSize(AI->getAllocatedType())) { // If this is a store of the entire alloca from an integer, rewrite it. @@ -833,7 +833,7 @@ void SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst, // Convert the integer value to the appropriate type. StoreVal = ConstantInt::get(Context, TotalVal); - if (isa<PointerType>(ValTy)) + if (ValTy->isPointerTy()) StoreVal = ConstantExpr::getIntToPtr(StoreVal, ValTy); else if (ValTy->isFloatingPointTy()) StoreVal = ConstantExpr::getBitCast(StoreVal, ValTy); @@ -939,7 +939,7 @@ void SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI, Value *DestField = NewElts[i]; if (EltVal->getType() == FieldTy) { // Storing to an integer field of this size, just do it. - } else if (FieldTy->isFloatingPointTy() || isa<VectorType>(FieldTy)) { + } else if (FieldTy->isFloatingPointTy() || FieldTy->isVectorTy()) { // Bitcast to the right element type (for fp/vector values). EltVal = new BitCastInst(EltVal, FieldTy, "", SI); } else { @@ -984,7 +984,7 @@ void SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI, if (EltVal->getType() == ArrayEltTy) { // Storing to an integer field of this size, just do it. } else if (ArrayEltTy->isFloatingPointTy() || - isa<VectorType>(ArrayEltTy)) { + ArrayEltTy->isVectorTy()) { // Bitcast to the right element type (for fp/vector values). EltVal = new BitCastInst(EltVal, ArrayEltTy, "", SI); } else { @@ -1044,8 +1044,8 @@ void SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI, const IntegerType *FieldIntTy = IntegerType::get(LI->getContext(), FieldSizeBits); - if (!isa<IntegerType>(FieldTy) && !FieldTy->isFloatingPointTy() && - !isa<VectorType>(FieldTy)) + if (!FieldTy->isIntegerTy() && !FieldTy->isFloatingPointTy() && + !FieldTy->isVectorTy()) SrcField = new BitCastInst(SrcField, PointerType::getUnqual(FieldIntTy), "", LI); @@ -1183,7 +1183,7 @@ static void MergeInType(const Type *In, uint64_t Offset, const Type *&VecTy, return; } } else if (In->isFloatTy() || In->isDoubleTy() || - (isa<IntegerType>(In) && In->getPrimitiveSizeInBits() >= 8 && + (In->isIntegerTy() && In->getPrimitiveSizeInBits() >= 8 && isPowerOf2_32(In->getPrimitiveSizeInBits()))) { // If we're accessing something that could be an element of a vector, see // if the implied vector agrees with what we already have and if Offset is @@ -1227,7 +1227,7 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy, return false; MergeInType(LI->getType(), Offset, VecTy, AllocaSize, *TD, V->getContext()); - SawVec |= isa<VectorType>(LI->getType()); + SawVec |= LI->getType()->isVectorTy(); continue; } @@ -1236,7 +1236,7 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy, if (SI->getOperand(0) == V || SI->isVolatile()) return 0; MergeInType(SI->getOperand(0)->getType(), Offset, VecTy, AllocaSize, *TD, V->getContext()); - SawVec |= isa<VectorType>(SI->getOperand(0)->getType()); + SawVec |= SI->getOperand(0)->getType()->isVectorTy(); continue; } @@ -1438,7 +1438,7 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType, // If the result alloca is a vector type, this is either an element // access or a bitcast to another vector type of the same size. if (const VectorType *VTy = dyn_cast<VectorType>(FromVal->getType())) { - if (isa<VectorType>(ToType)) + if (ToType->isVectorTy()) return Builder.CreateBitCast(FromVal, ToType, "tmp"); // Otherwise it must be an element access. @@ -1521,9 +1521,9 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType, LIBitWidth), "tmp"); // If the result is an integer, this is a trunc or bitcast. - if (isa<IntegerType>(ToType)) { + if (ToType->isIntegerTy()) { // Should be done. - } else if (ToType->isFloatingPointTy() || isa<VectorType>(ToType)) { + } else if (ToType->isFloatingPointTy() || ToType->isVectorTy()) { // Just do a bitcast, we know the sizes match up. FromVal = Builder.CreateBitCast(FromVal, ToType, "tmp"); } else { @@ -1601,10 +1601,10 @@ Value *SROA::ConvertScalar_InsertValue(Value *SV, Value *Old, unsigned DestWidth = TD->getTypeSizeInBits(AllocaType); unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType()); unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType); - if (SV->getType()->isFloatingPointTy() || isa<VectorType>(SV->getType())) + if (SV->getType()->isFloatingPointTy() || SV->getType()->isVectorTy()) SV = Builder.CreateBitCast(SV, IntegerType::get(SV->getContext(),SrcWidth), "tmp"); - else if (isa<PointerType>(SV->getType())) + else if (SV->getType()->isPointerTy()) SV = Builder.CreatePtrToInt(SV, TD->getIntPtrType(SV->getContext()), "tmp"); // Zero extend or truncate the value if needed. diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 54b4380..cde214b 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -357,7 +357,7 @@ void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) { AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture); AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); Constant *F; - if (isa<PointerType>(File->getType())) + if (File->getType()->isPointerTy()) F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), Type::getInt32Ty(*Context), Type::getInt32Ty(*Context), File->getType(), @@ -384,7 +384,7 @@ void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) { AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture); AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); Constant *F; - if (isa<PointerType>(File->getType())) + if (File->getType()->isPointerTy()) F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3), Type::getInt32Ty(*Context), Type::getInt8PtrTy(*Context), @@ -409,7 +409,7 @@ void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File, AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture); AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind); Constant *F; - if (isa<PointerType>(File->getType())) + if (File->getType()->isPointerTy()) F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3), TD->getIntPtrType(*Context), Type::getInt8PtrTy(*Context), @@ -548,7 +548,7 @@ static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) { /// GetStringLength - If we can compute the length of the string pointed to by /// the specified pointer, return 'len+1'. If we can't, return 0. static uint64_t GetStringLength(Value *V) { - if (!isa<PointerType>(V->getType())) return 0; + if (!V->getType()->isPointerTy()) return 0; SmallPtrSet<PHINode*, 32> PHIs; uint64_t Len = GetStringLengthH(V, PHIs); @@ -638,7 +638,7 @@ struct StrNCatOpt : public StrCatOpt { FT->getReturnType() != Type::getInt8PtrTy(*Context) || FT->getParamType(0) != FT->getReturnType() || FT->getParamType(1) != FT->getReturnType() || - !isa<IntegerType>(FT->getParamType(2))) + !FT->getParamType(2)->isIntegerTy()) return 0; // Extract some information from the instruction @@ -790,7 +790,7 @@ struct StrNCmpOpt : public LibCallOptimization { !FT->getReturnType()->isIntegerTy(32) || FT->getParamType(0) != FT->getParamType(1) || FT->getParamType(0) != Type::getInt8PtrTy(*Context) || - !isa<IntegerType>(FT->getParamType(2))) + !FT->getParamType(2)->isIntegerTy()) return 0; Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2); @@ -866,7 +866,7 @@ struct StrNCpyOpt : public LibCallOptimization { if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || FT->getParamType(0) != FT->getParamType(1) || FT->getParamType(0) != Type::getInt8PtrTy(*Context) || - !isa<IntegerType>(FT->getParamType(2))) + !FT->getParamType(2)->isIntegerTy()) return 0; Value *Dst = CI->getOperand(1); @@ -915,7 +915,7 @@ struct StrLenOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 1 || FT->getParamType(0) != Type::getInt8PtrTy(*Context) || - !isa<IntegerType>(FT->getReturnType())) + !FT->getReturnType()->isIntegerTy()) return 0; Value *Src = CI->getOperand(1); @@ -939,8 +939,8 @@ struct StrToOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1))) + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy()) return 0; Value *EndPtr = CI->getOperand(2); @@ -960,9 +960,9 @@ struct StrStrOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 2 || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || - !isa<PointerType>(FT->getReturnType())) + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || + !FT->getReturnType()->isPointerTy()) return 0; // fold strstr(x, x) -> x. @@ -1006,8 +1006,8 @@ struct StrStrOpt : public LibCallOptimization { struct MemCmpOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 3 || !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || + if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || !FT->getReturnType()->isIntegerTy(32)) return 0; @@ -1055,8 +1055,8 @@ struct MemCpyOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; @@ -1076,8 +1076,8 @@ struct MemMoveOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; @@ -1097,8 +1097,8 @@ struct MemSetOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<IntegerType>(FT->getParamType(1)) || + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isIntegerTy() || FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; @@ -1124,9 +1124,9 @@ struct MemCpyChkOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || - !isa<IntegerType>(FT->getParamType(3)) || + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || + !FT->getParamType(3)->isIntegerTy() || FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; @@ -1152,9 +1152,9 @@ struct MemSetChkOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<IntegerType>(FT->getParamType(1)) || - !isa<IntegerType>(FT->getParamType(3)) || + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isIntegerTy() || + !FT->getParamType(3)->isIntegerTy() || FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; @@ -1182,9 +1182,9 @@ struct MemMoveChkOpt : public LibCallOptimization { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || - !isa<IntegerType>(FT->getParamType(3)) || + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || + !FT->getParamType(3)->isIntegerTy() || FT->getParamType(2) != TD->getIntPtrType(*Context)) return 0; @@ -1205,8 +1205,8 @@ struct StrCpyChkOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || - !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1))) + !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy()) return 0; ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(3)); @@ -1376,7 +1376,7 @@ struct FFSOpt : public LibCallOptimization { // result type. if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy(32) || - !isa<IntegerType>(FT->getParamType(0))) + !FT->getParamType(0)->isIntegerTy()) return 0; Value *Op = CI->getOperand(1); @@ -1410,7 +1410,7 @@ struct IsDigitOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); // We require integer(i32) - if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) || + if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || !FT->getParamType(0)->isIntegerTy(32)) return 0; @@ -1431,7 +1431,7 @@ struct IsAsciiOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); // We require integer(i32) - if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) || + if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || !FT->getParamType(0)->isIntegerTy(32)) return 0; @@ -1450,7 +1450,7 @@ struct AbsOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { const FunctionType *FT = Callee->getFunctionType(); // We require integer(integer) where the types agree. - if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) || + if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || FT->getParamType(0) != FT->getReturnType()) return 0; @@ -1493,8 +1493,8 @@ struct PrintFOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Require one fixed pointer argument and an integer/void result. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() < 1 || !isa<PointerType>(FT->getParamType(0)) || - !(isa<IntegerType>(FT->getReturnType()) || + if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || + !(FT->getReturnType()->isIntegerTy() || FT->getReturnType()->isVoidTy())) return 0; @@ -1534,7 +1534,7 @@ struct PrintFOpt : public LibCallOptimization { // Optimize specific format strings. // printf("%c", chr) --> putchar(*(i8*)dst) if (FormatStr == "%c" && CI->getNumOperands() > 2 && - isa<IntegerType>(CI->getOperand(2)->getType())) { + CI->getOperand(2)->getType()->isIntegerTy()) { Value *Res = EmitPutChar(CI->getOperand(2), B); if (CI->use_empty()) return CI; @@ -1543,7 +1543,7 @@ struct PrintFOpt : public LibCallOptimization { // printf("%s\n", str) --> puts(str) if (FormatStr == "%s\n" && CI->getNumOperands() > 2 && - isa<PointerType>(CI->getOperand(2)->getType()) && + CI->getOperand(2)->getType()->isPointerTy() && CI->use_empty()) { EmitPutS(CI->getOperand(2), B); return CI; @@ -1559,9 +1559,9 @@ struct SPrintFOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Require two fixed pointer arguments and an integer result. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || - !isa<IntegerType>(FT->getReturnType())) + if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || + !FT->getReturnType()->isIntegerTy()) return 0; // Check for a fixed format string. @@ -1595,7 +1595,7 @@ struct SPrintFOpt : public LibCallOptimization { // Decode the second character of the format string. if (FormatStr[1] == 'c') { // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 - if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0; + if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0; Value *V = B.CreateTrunc(CI->getOperand(3), Type::getInt8Ty(*Context), "char"); Value *Ptr = CastToCStr(CI->getOperand(1), B); @@ -1612,7 +1612,7 @@ struct SPrintFOpt : public LibCallOptimization { if (!TD) return 0; // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) - if (!isa<PointerType>(CI->getOperand(3)->getType())) return 0; + if (!CI->getOperand(3)->getType()->isPointerTy()) return 0; Value *Len = EmitStrLen(CI->getOperand(3), B); Value *IncLen = B.CreateAdd(Len, @@ -1634,11 +1634,11 @@ struct FWriteOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Require a pointer, an integer, an integer, a pointer, returning integer. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 4 || !isa<PointerType>(FT->getParamType(0)) || - !isa<IntegerType>(FT->getParamType(1)) || - !isa<IntegerType>(FT->getParamType(2)) || - !isa<PointerType>(FT->getParamType(3)) || - !isa<IntegerType>(FT->getReturnType())) + if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isIntegerTy() || + !FT->getParamType(2)->isIntegerTy() || + !FT->getParamType(3)->isPointerTy() || + !FT->getReturnType()->isIntegerTy()) return 0; // Get the element size and count. @@ -1672,8 +1672,8 @@ struct FPutsOpt : public LibCallOptimization { // Require two pointers. Also, we can't optimize if return value is used. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || + if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || !CI->use_empty()) return 0; @@ -1694,9 +1694,9 @@ struct FPrintFOpt : public LibCallOptimization { virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Require two fixed paramters as pointers and integer result. const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) || - !isa<PointerType>(FT->getParamType(1)) || - !isa<IntegerType>(FT->getReturnType())) + if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || + !FT->getParamType(1)->isPointerTy() || + !FT->getReturnType()->isIntegerTy()) return 0; // All the optimizations depend on the format string. @@ -1728,14 +1728,14 @@ struct FPrintFOpt : public LibCallOptimization { // Decode the second character of the format string. if (FormatStr[1] == 'c') { // fprintf(F, "%c", chr) --> *(i8*)dst = chr - if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0; + if (!CI->getOperand(3)->getType()->isIntegerTy()) return 0; EmitFPutC(CI->getOperand(3), CI->getOperand(1), B); return ConstantInt::get(CI->getType(), 1); } if (FormatStr[1] == 's') { // fprintf(F, "%s", str) -> fputs(str, F) - if (!isa<PointerType>(CI->getOperand(3)->getType()) || !CI->use_empty()) + if (!CI->getOperand(3)->getType()->isPointerTy() || !CI->use_empty()) return 0; EmitFPutS(CI->getOperand(3), CI->getOperand(1), B); return CI; @@ -2000,7 +2000,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 's': if (Name == "strlen") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setOnlyReadsMemory(F); setDoesNotThrow(F); @@ -2018,14 +2018,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "strncpy" || Name == "strtoull") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); } else if (Name == "strxfrm") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2038,8 +2038,8 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "strcasecmp" || Name == "strncasecmp") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setOnlyReadsMemory(F); setDoesNotThrow(F); @@ -2048,7 +2048,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { } else if (Name == "strstr" || Name == "strpbrk") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setOnlyReadsMemory(F); setDoesNotThrow(F); @@ -2056,7 +2056,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { } else if (Name == "strtok" || Name == "strtok_r") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); @@ -2064,15 +2064,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "setbuf" || Name == "setvbuf") { if (FTy->getNumParams() < 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "strdup" || Name == "strndup") { if (FTy->getNumParams() < 1 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2082,31 +2082,31 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "sprintf" || Name == "statvfs") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 2); } else if (Name == "snprintf") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(2))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(2)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 3); } else if (Name == "setitimer") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(1)) || - !isa<PointerType>(FTy->getParamType(2))) + !FTy->getParamType(1)->isPointerTy() || + !FTy->getParamType(2)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); setDoesNotCapture(F, 3); } else if (Name == "system") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; // May throw; "system" is a valid pthread cancellation point. setDoesNotCapture(F, 1); @@ -2115,14 +2115,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'm': if (Name == "malloc") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getReturnType())) + !FTy->getReturnType()->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); } else if (Name == "memcmp") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setOnlyReadsMemory(F); setDoesNotThrow(F); @@ -2141,18 +2141,18 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "memccpy" || Name == "memmove") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); } else if (Name == "memalign") { - if (!isa<PointerType>(FTy->getReturnType())) + if (!FTy->getReturnType()->isPointerTy()) continue; setDoesNotAlias(F, 0); } else if (Name == "mkdir" || Name == "mktime") { if (FTy->getNumParams() == 0 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2161,15 +2161,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'r': if (Name == "realloc") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getReturnType())) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getReturnType()->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); setDoesNotCapture(F, 1); } else if (Name == "read") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; // May throw; "read" is a valid pthread cancellation point. setDoesNotCapture(F, 2); @@ -2178,15 +2178,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "remove" || Name == "realpath") { if (FTy->getNumParams() < 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "rename" || Name == "readlink") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2196,7 +2196,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'w': if (Name == "write") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; // May throw; "write" is a valid pthread cancellation point. setDoesNotCapture(F, 2); @@ -2205,16 +2205,16 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'b': if (Name == "bcopy") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 2); } else if (Name == "bcmp") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setOnlyReadsMemory(F); @@ -2222,7 +2222,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { setDoesNotCapture(F, 2); } else if (Name == "bzero") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2231,7 +2231,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'c': if (Name == "calloc") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getReturnType())) + !FTy->getReturnType()->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2241,7 +2241,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "clearerr" || Name == "closedir") { if (FTy->getNumParams() == 0 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2253,14 +2253,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "atof" || Name == "atoll") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setOnlyReadsMemory(F); setDoesNotCapture(F, 1); } else if (Name == "access") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2269,9 +2269,9 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'f': if (Name == "fopen") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2279,8 +2279,8 @@ bool SimplifyLibCalls::doInitialization(Module &M) { setDoesNotCapture(F, 2); } else if (Name == "fdopen") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2300,13 +2300,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "funlockfile" || Name == "ftrylockfile") { if (FTy->getNumParams() == 0 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "ferror") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2318,22 +2318,22 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "frexpl" || Name == "fstatvfs") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); } else if (Name == "fgets") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(2))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(2)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 3); } else if (Name == "fread" || Name == "fwrite") { if (FTy->getNumParams() != 4 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(3))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(3)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2343,8 +2343,8 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "fprintf" || Name == "fgetpos") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2356,13 +2356,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "getlogin_r" || Name == "getc_unlocked") { if (FTy->getNumParams() == 0 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "getenv") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setOnlyReadsMemory(F); @@ -2372,13 +2372,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) { setDoesNotThrow(F); } else if (Name == "getitimer") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); } else if (Name == "getpwnam") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2387,7 +2387,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'u': if (Name == "ungetc") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); @@ -2395,15 +2395,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "unlink" || Name == "unsetenv") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "utime" || Name == "utimes") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2413,7 +2413,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'p': if (Name == "putc") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); @@ -2421,14 +2421,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "printf" || Name == "perror") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "pread" || Name == "pwrite") { if (FTy->getNumParams() != 4 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; // May throw; these are valid pthread cancellation points. setDoesNotCapture(F, 2); @@ -2436,9 +2436,9 @@ bool SimplifyLibCalls::doInitialization(Module &M) { setDoesNotThrow(F); } else if (Name == "popen") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2446,7 +2446,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { setDoesNotCapture(F, 2); } else if (Name == "pclose") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2455,43 +2455,43 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'v': if (Name == "vscanf") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "vsscanf" || Name == "vfscanf") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(1)) || - !isa<PointerType>(FTy->getParamType(2))) + !FTy->getParamType(1)->isPointerTy() || + !FTy->getParamType(2)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 2); } else if (Name == "valloc") { - if (!isa<PointerType>(FTy->getReturnType())) + if (!FTy->getReturnType()->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); } else if (Name == "vprintf") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "vfprintf" || Name == "vsprintf") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 2); } else if (Name == "vsnprintf") { if (FTy->getNumParams() != 4 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(2))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(2)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2501,14 +2501,14 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'o': if (Name == "open") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; // May throw; "open" is a valid pthread cancellation point. setDoesNotCapture(F, 1); } else if (Name == "opendir") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2517,13 +2517,13 @@ bool SimplifyLibCalls::doInitialization(Module &M) { break; case 't': if (Name == "tmpfile") { - if (!isa<PointerType>(FTy->getReturnType())) + if (!FTy->getReturnType()->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); } else if (Name == "times") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2546,15 +2546,15 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'l': if (Name == "lstat") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 2); } else if (Name == "lchown") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2563,7 +2563,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 'q': if (Name == "qsort") { if (FTy->getNumParams() != 4 || - !isa<PointerType>(FTy->getParamType(3))) + !FTy->getParamType(3)->isPointerTy()) continue; // May throw; places call through function pointer. setDoesNotCapture(F, 4); @@ -2573,27 +2573,27 @@ bool SimplifyLibCalls::doInitialization(Module &M) { if (Name == "__strdup" || Name == "__strndup") { if (FTy->getNumParams() < 1 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); setDoesNotCapture(F, 1); } else if (Name == "__strtok_r") { if (FTy->getNumParams() != 3 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); } else if (Name == "_IO_getc") { if (FTy->getNumParams() != 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "_IO_putc") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); @@ -2602,7 +2602,7 @@ bool SimplifyLibCalls::doInitialization(Module &M) { case 1: if (Name == "\1__isoc99_scanf") { if (FTy->getNumParams() < 1 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); @@ -2611,17 +2611,17 @@ bool SimplifyLibCalls::doInitialization(Module &M) { Name == "\1statvfs64" || Name == "\1__isoc99_sscanf") { if (FTy->getNumParams() < 1 || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); setDoesNotCapture(F, 2); } else if (Name == "\1fopen64") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getReturnType()) || - !isa<PointerType>(FTy->getParamType(0)) || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getReturnType()->isPointerTy() || + !FTy->getParamType(0)->isPointerTy() || + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); @@ -2630,25 +2630,25 @@ bool SimplifyLibCalls::doInitialization(Module &M) { } else if (Name == "\1fseeko64" || Name == "\1ftello64") { if (FTy->getNumParams() == 0 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 1); } else if (Name == "\1tmpfile64") { - if (!isa<PointerType>(FTy->getReturnType())) + if (!FTy->getReturnType()->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotAlias(F, 0); } else if (Name == "\1fstat64" || Name == "\1fstatvfs64") { if (FTy->getNumParams() != 2 || - !isa<PointerType>(FTy->getParamType(1))) + !FTy->getParamType(1)->isPointerTy()) continue; setDoesNotThrow(F); setDoesNotCapture(F, 2); } else if (Name == "\1open64") { if (FTy->getNumParams() < 2 || - !isa<PointerType>(FTy->getParamType(0))) + !FTy->getParamType(0)->isPointerTy()) continue; // May throw; "open" is a valid pthread cancellation point. setDoesNotCapture(F, 1); |