diff options
Diffstat (limited to 'lib/Transforms')
107 files changed, 1240 insertions, 616 deletions
diff --git a/lib/Transforms/Hello/CMakeLists.txt b/lib/Transforms/Hello/CMakeLists.txt index 3851b35..e0b8190 100644 --- a/lib/Transforms/Hello/CMakeLists.txt +++ b/lib/Transforms/Hello/CMakeLists.txt @@ -12,4 +12,7 @@ endif() add_llvm_loadable_module( LLVMHello Hello.cpp + + DEPENDS + intrinsics_gen ) diff --git a/lib/Transforms/Hello/Hello.cpp b/lib/Transforms/Hello/Hello.cpp index 29b9bb8..f90aafc 100644 --- a/lib/Transforms/Hello/Hello.cpp +++ b/lib/Transforms/Hello/Hello.cpp @@ -35,7 +35,7 @@ namespace { return false; } }; -} +} // namespace char Hello::ID = 0; static RegisterPass<Hello> X("hello", "Hello World Pass"); @@ -58,7 +58,7 @@ namespace { AU.setPreservesAll(); } }; -} +} // namespace char Hello2::ID = 0; static RegisterPass<Hello2> diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index c7c57ab..86b3faa 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -92,7 +92,7 @@ namespace { unsigned maxElements; DenseMap<const Function *, DISubprogram *> FunctionDIs; }; -} +} // namespace char ArgPromotion::ID = 0; INITIALIZE_PASS_BEGIN(ArgPromotion, "argpromotion", @@ -245,6 +245,24 @@ CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) { Argument *PtrArg = PointerArgs[i]; Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType(); + // Replace sret attribute with noalias. This reduces register pressure by + // avoiding a register copy. + if (PtrArg->hasStructRetAttr()) { + unsigned ArgNo = PtrArg->getArgNo(); + F->setAttributes( + F->getAttributes() + .removeAttribute(F->getContext(), ArgNo + 1, Attribute::StructRet) + .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias)); + for (Use &U : F->uses()) { + CallSite CS(U.getUser()); + CS.setAttributes( + CS.getAttributes() + .removeAttribute(F->getContext(), ArgNo + 1, + Attribute::StructRet) + .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias)); + } + } + // If this is a byval argument, and if the aggregate type is small, just // pass the elements, which is always safe, if the passed value is densely // packed or if we can prove the padding bytes are never accessed. This does @@ -553,7 +571,7 @@ bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg, LoadInst *Load = Loads[i]; BasicBlock *BB = Load->getParent(); - AliasAnalysis::Location Loc = MemoryLocation::get(Load); + MemoryLocation Loc = MemoryLocation::get(Load); if (AA.canInstructionRangeModRef(BB->front(), *Load, Loc, AliasAnalysis::Mod)) return false; // Pointer is invalidated! diff --git a/lib/Transforms/IPO/BarrierNoopPass.cpp b/lib/Transforms/IPO/BarrierNoopPass.cpp index 6af1043..7585fdc 100644 --- a/lib/Transforms/IPO/BarrierNoopPass.cpp +++ b/lib/Transforms/IPO/BarrierNoopPass.cpp @@ -38,7 +38,7 @@ public: bool runOnModule(Module &M) override { return false; } }; -} +} // namespace ModulePass *llvm::createBarrierNoopPass() { return new BarrierNoop(); } diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index 8ce7646..3b68743 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -53,7 +53,7 @@ namespace { unsigned getAlignment(GlobalVariable *GV) const; }; -} +} // namespace char ConstantMerge::ID = 0; INITIALIZE_PASS(ConstantMerge, "constmerge", diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index 76898f2..6bfd3d1 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -159,7 +159,7 @@ namespace { bool DeleteDeadVarargs(Function &Fn); bool RemoveDeadArgumentsFromCallers(Function &Fn); }; -} +} // namespace char DAE::ID = 0; @@ -175,7 +175,7 @@ namespace { bool ShouldHackArguments() const override { return true; } }; -} +} // namespace char DAH::ID = 0; INITIALIZE_PASS(DAH, "deadarghaX0r", diff --git a/lib/Transforms/IPO/ExtractGV.cpp b/lib/Transforms/IPO/ExtractGV.cpp index 2f8c7d9..7e0dddc 100644 --- a/lib/Transforms/IPO/ExtractGV.cpp +++ b/lib/Transforms/IPO/ExtractGV.cpp @@ -146,7 +146,7 @@ namespace { }; char GVExtractorPass::ID = 0; -} +} // namespace ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs, bool deleteFn) { diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp index ef8f42f..749ff99 100644 --- a/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/lib/Transforms/IPO/FunctionAttrs.cpp @@ -132,7 +132,7 @@ namespace { AliasAnalysis *AA; TargetLibraryInfo *TLI; }; -} +} // namespace char FunctionAttrs::ID = 0; INITIALIZE_PASS_BEGIN(FunctionAttrs, "functionattrs", @@ -208,8 +208,7 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) { AAMDNodes AAInfo; I->getAAMetadata(AAInfo); - AliasAnalysis::Location Loc(Arg, - AliasAnalysis::UnknownSize, AAInfo); + MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo); if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) { if (MRB & AliasAnalysis::Mod) // Writes non-local memory. Give up. @@ -232,20 +231,20 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) { } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) { // Ignore non-volatile loads from local memory. (Atomic is okay here.) if (!LI->isVolatile()) { - AliasAnalysis::Location Loc = MemoryLocation::get(LI); + MemoryLocation Loc = MemoryLocation::get(LI); if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) continue; } } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) { // Ignore non-volatile stores to local memory. (Atomic is okay here.) if (!SI->isVolatile()) { - AliasAnalysis::Location Loc = MemoryLocation::get(SI); + MemoryLocation Loc = MemoryLocation::get(SI); if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) continue; } } else if (VAArgInst *VI = dyn_cast<VAArgInst>(I)) { // Ignore vaargs on local memory. - AliasAnalysis::Location Loc = MemoryLocation::get(VI); + MemoryLocation Loc = MemoryLocation::get(VI); if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) continue; } @@ -380,7 +379,7 @@ namespace { const SmallPtrSet<Function*, 8> &SCCNodes; }; -} +} // namespace namespace llvm { template<> struct GraphTraits<ArgumentGraphNode*> { @@ -407,7 +406,7 @@ namespace llvm { return AG->end(); } }; -} +} // namespace llvm // Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone. static Attribute::AttrKind diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp index ba04c80..7983104 100644 --- a/lib/Transforms/IPO/GlobalDCE.cpp +++ b/lib/Transforms/IPO/GlobalDCE.cpp @@ -57,7 +57,7 @@ namespace { bool RemoveUnusedGlobalValue(GlobalValue &GV); }; -} +} // namespace /// Returns true if F contains only a single "ret" instruction. static bool isEmptyFunction(Function *F) { @@ -228,6 +228,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { if (F->hasPrologueData()) MarkUsedGlobalsAsNeeded(F->getPrologueData()); + if (F->hasPersonalityFn()) + MarkUsedGlobalsAsNeeded(F->getPersonalityFn()); + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) for (User::op_iterator U = I->op_begin(), E = I->op_end(); U != E; ++U) diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index cc4a79f..0d83c82 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -89,7 +89,7 @@ namespace { TargetLibraryInfo *TLI; SmallSet<const Comdat *, 8> NotDiscardableComdats; }; -} +} // namespace char GlobalOpt::ID = 0; INITIALIZE_PASS_BEGIN(GlobalOpt, "globalopt", @@ -2786,7 +2786,7 @@ public: setUsedInitializer(*CompilerUsedV, CompilerUsed); } }; -} +} // namespace static bool hasUseOtherThanLLVMUsed(GlobalAlias &GA, const LLVMUsed &U) { if (GA.use_empty()) // No use at all. diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp index af541d1..d717b25 100644 --- a/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -45,7 +45,7 @@ namespace { bool PropagateConstantsIntoArguments(Function &F); bool PropagateConstantReturn(Function &F); }; -} +} // namespace char IPCP::ID = 0; INITIALIZE_PASS(IPCP, "ipconstprop", diff --git a/lib/Transforms/IPO/InlineAlways.cpp b/lib/Transforms/IPO/InlineAlways.cpp index dc56a02..37ff091 100644 --- a/lib/Transforms/IPO/InlineAlways.cpp +++ b/lib/Transforms/IPO/InlineAlways.cpp @@ -62,7 +62,7 @@ public: } }; -} +} // namespace char AlwaysInliner::ID = 0; INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp index 8f65a98..93cdba6 100644 --- a/lib/Transforms/IPO/Inliner.cpp +++ b/lib/Transforms/IPO/Inliner.cpp @@ -93,19 +93,26 @@ static void AdjustCallerSSPLevel(Function *Caller, Function *Callee) { // clutter to the IR. AttrBuilder B; B.addAttribute(Attribute::StackProtect) - .addAttribute(Attribute::StackProtectStrong); + .addAttribute(Attribute::StackProtectStrong) + .addAttribute(Attribute::StackProtectReq); AttributeSet OldSSPAttr = AttributeSet::get(Caller->getContext(), AttributeSet::FunctionIndex, B); - if (Callee->hasFnAttribute(Attribute::StackProtectReq)) { + if (Callee->hasFnAttribute(Attribute::SafeStack)) { + Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr); + Caller->addFnAttr(Attribute::SafeStack); + } else if (Callee->hasFnAttribute(Attribute::StackProtectReq) && + !Caller->hasFnAttribute(Attribute::SafeStack)) { Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr); Caller->addFnAttr(Attribute::StackProtectReq); } else if (Callee->hasFnAttribute(Attribute::StackProtectStrong) && + !Caller->hasFnAttribute(Attribute::SafeStack) && !Caller->hasFnAttribute(Attribute::StackProtectReq)) { Caller->removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr); Caller->addFnAttr(Attribute::StackProtectStrong); } else if (Callee->hasFnAttribute(Attribute::StackProtect) && + !Caller->hasFnAttribute(Attribute::SafeStack) && !Caller->hasFnAttribute(Attribute::StackProtectReq) && !Caller->hasFnAttribute(Attribute::StackProtectStrong)) Caller->addFnAttr(Attribute::StackProtect); @@ -431,8 +438,8 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { SmallPtrSet<Function*, 8> SCCFunctions; DEBUG(dbgs() << "Inliner visiting SCC:"); - for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { - Function *F = (*I)->getFunction(); + for (CallGraphNode *Node : SCC) { + Function *F = Node->getFunction(); if (F) SCCFunctions.insert(F); DEBUG(dbgs() << " " << (F ? F->getName() : "INDIRECTNODE")); } @@ -448,13 +455,13 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { // index into the InlineHistory vector. SmallVector<std::pair<Function*, int>, 8> InlineHistory; - for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { - Function *F = (*I)->getFunction(); + for (CallGraphNode *Node : SCC) { + Function *F = Node->getFunction(); if (!F) continue; - for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - CallSite CS(cast<Value>(I)); + for (BasicBlock &BB : *F) + for (Instruction &I : BB) { + CallSite CS(cast<Value>(&I)); // If this isn't a call, or it is a call to an intrinsic, it can // never be inlined. if (!CS || isa<IntrinsicInst>(I)) @@ -496,6 +503,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { LocalChange = false; // Iterate over the outer loop because inlining functions can cause indirect // calls to become direct calls. + // CallSites may be modified inside so ranged for loop can not be used. for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi) { CallSite CS = CallSites[CSi].first; @@ -566,11 +574,8 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { int NewHistoryID = InlineHistory.size(); InlineHistory.push_back(std::make_pair(Callee, InlineHistoryID)); - for (unsigned i = 0, e = InlineInfo.InlinedCalls.size(); - i != e; ++i) { - Value *Ptr = InlineInfo.InlinedCalls[i]; + for (Value *Ptr : InlineInfo.InlinedCalls) CallSites.push_back(std::make_pair(CallSite(Ptr), NewHistoryID)); - } } } diff --git a/lib/Transforms/IPO/LoopExtractor.cpp b/lib/Transforms/IPO/LoopExtractor.cpp index 41334ca..ada4a76 100644 --- a/lib/Transforms/IPO/LoopExtractor.cpp +++ b/lib/Transforms/IPO/LoopExtractor.cpp @@ -51,7 +51,7 @@ namespace { AU.addRequired<DominatorTreeWrapperPass>(); } }; -} +} // namespace char LoopExtractor::ID = 0; INITIALIZE_PASS_BEGIN(LoopExtractor, "loop-extract", @@ -183,7 +183,7 @@ namespace { bool runOnModule(Module &M) override; }; -} +} // namespace char BlockExtractorPass::ID = 0; INITIALIZE_PASS(BlockExtractorPass, "extract-blocks", diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp index 052f1b4..5e41798 100644 --- a/lib/Transforms/IPO/MergeFunctions.cpp +++ b/lib/Transforms/IPO/MergeFunctions.cpp @@ -409,7 +409,7 @@ public: return (FunctionComparator(F, RHS.getFunc()).compare()) == -1; } }; -} +} // namespace int FunctionComparator::cmpNumbers(uint64_t L, uint64_t R) const { if (L < R) return -1; @@ -1397,28 +1397,26 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) { if (F->mayBeOverridden()) { assert(G->mayBeOverridden()); - if (HasGlobalAliases) { - // Make them both thunks to the same internal function. - Function *H = Function::Create(F->getFunctionType(), F->getLinkage(), "", - F->getParent()); - H->copyAttributesFrom(F); - H->takeName(F); - removeUsers(F); - F->replaceAllUsesWith(H); + // Make them both thunks to the same internal function. + Function *H = Function::Create(F->getFunctionType(), F->getLinkage(), "", + F->getParent()); + H->copyAttributesFrom(F); + H->takeName(F); + removeUsers(F); + F->replaceAllUsesWith(H); - unsigned MaxAlignment = std::max(G->getAlignment(), H->getAlignment()); + unsigned MaxAlignment = std::max(G->getAlignment(), H->getAlignment()); + if (HasGlobalAliases) { writeAlias(F, G); writeAlias(F, H); - - F->setAlignment(MaxAlignment); - F->setLinkage(GlobalValue::PrivateLinkage); } else { - // We can't merge them. Instead, pick one and update all direct callers - // to call it and hope that we improve the instruction cache hit rate. - replaceDirectCallers(G, F); + writeThunk(F, G); + writeThunk(F, H); } + F->setAlignment(MaxAlignment); + F->setLinkage(GlobalValue::PrivateLinkage); ++NumDoubleWeak; } else { writeThunkOrAlias(F, G); diff --git a/lib/Transforms/IPO/PartialInlining.cpp b/lib/Transforms/IPO/PartialInlining.cpp index 4a7cb7b..7a7065c 100644 --- a/lib/Transforms/IPO/PartialInlining.cpp +++ b/lib/Transforms/IPO/PartialInlining.cpp @@ -40,7 +40,7 @@ namespace { private: Function* unswitchFunction(Function* F); }; -} +} // namespace char PartialInliner::ID = 0; INITIALIZE_PASS(PartialInliner, "partial-inliner", diff --git a/lib/Transforms/IPO/PassManagerBuilder.cpp b/lib/Transforms/IPO/PassManagerBuilder.cpp index 3496a66..963f1bb 100644 --- a/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -94,7 +94,6 @@ PassManagerBuilder::PassManagerBuilder() { SizeLevel = 0; LibraryInfo = nullptr; Inliner = nullptr; - DisableTailCalls = false; DisableUnitAtATime = false; DisableUnrollLoops = false; BBVectorize = RunBBVectorization; @@ -238,8 +237,7 @@ void PassManagerBuilder::populateModulePassManager( MPM.add(createInstructionCombiningPass()); // Combine silly seq's addExtensionsToPM(EP_Peephole, MPM); - if (!DisableTailCalls) - MPM.add(createTailCallEliminationPass()); // Eliminate tail calls + MPM.add(createTailCallEliminationPass()); // Eliminate tail calls MPM.add(createCFGSimplificationPass()); // Merge & remove BBs MPM.add(createReassociatePass()); // Reassociate expressions // Rotate Loop - disable header duplication at -Oz diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp index 1943b93..a5ba9ee 100644 --- a/lib/Transforms/IPO/PruneEH.cpp +++ b/lib/Transforms/IPO/PruneEH.cpp @@ -49,7 +49,7 @@ namespace { bool SimplifyFunction(Function *F); void DeleteBasicBlock(BasicBlock *BB); }; -} +} // namespace char PruneEH::ID = 0; INITIALIZE_PASS_BEGIN(PruneEH, "prune-eh", @@ -177,7 +177,7 @@ bool PruneEH::SimplifyFunction(Function *F) { bool MadeChange = false; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) - if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(II)) { + if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(F)) { SmallVector<Value*, 8> Args(II->op_begin(), II->op_end() - 3); // Insert a call instruction before the invoke. CallInst *Call = CallInst::Create(II->getCalledValue(), Args, "", II); diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp index 60c9573..6f9af1d 100644 --- a/lib/Transforms/IPO/StripSymbols.cpp +++ b/lib/Transforms/IPO/StripSymbols.cpp @@ -95,7 +95,7 @@ namespace { AU.setPreservesAll(); } }; -} +} // namespace char StripSymbols::ID = 0; INITIALIZE_PASS(StripSymbols, "strip", diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index a8d0172..29ecc1d 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -193,7 +193,7 @@ namespace { void incCreateInstNum() {} #endif }; -} +} // namespace //===----------------------------------------------------------------------===// // diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index e83b9dd..6de380b 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1391,11 +1391,29 @@ static IntrinsicInst *FindInitTrampoline(Value *Callee) { // visitCallSite - Improvements for call and invoke instructions. // Instruction *InstCombiner::visitCallSite(CallSite CS) { + if (isAllocLikeFn(CS.getInstruction(), TLI)) return visitAllocSite(*CS.getInstruction()); bool Changed = false; + // Mark any parameters that are known to be non-null with the nonnull + // attribute. This is helpful for inlining calls to functions with null + // checks on their arguments. + unsigned ArgNo = 0; + for (Value *V : CS.args()) { + if (!CS.paramHasAttr(ArgNo+1, Attribute::NonNull) && + isKnownNonNull(V)) { + AttributeSet AS = CS.getAttributes(); + AS = AS.addAttribute(CS.getInstruction()->getContext(), ArgNo+1, + Attribute::NonNull); + CS.setAttributes(AS); + Changed = true; + } + ArgNo++; + } + assert(ArgNo == CS.arg_size() && "sanity check"); + // If the callee is a pointer to a function, attempt to move any casts to the // arguments of the call/invoke. Value *Callee = CS.getCalledValue(); diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index a554e9f..6b384b4 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -948,7 +948,7 @@ struct UDivFoldAction { UDivFoldAction(FoldUDivOperandCb FA, Value *InputOperand, size_t SLHS) : FoldAction(FA), OperandToFold(InputOperand), SelectLHSIdx(SLHS) {} }; -} +} // namespace // X udiv 2^C -> X >> C static Instruction *foldUDivPow2Cst(Value *Op0, Value *Op1, diff --git a/lib/Transforms/InstCombine/InstCombinePHI.cpp b/lib/Transforms/InstCombine/InstCombinePHI.cpp index 6a6693c..a93ffbe 100644 --- a/lib/Transforms/InstCombine/InstCombinePHI.cpp +++ b/lib/Transforms/InstCombine/InstCombinePHI.cpp @@ -582,7 +582,7 @@ struct LoweredPHIRecord { LoweredPHIRecord(PHINode *pn, unsigned Sh) : PN(pn), Shift(Sh), Width(0) {} }; -} +} // namespace namespace llvm { template<> @@ -603,7 +603,7 @@ namespace llvm { LHS.Width == RHS.Width; } }; -} +} // namespace llvm /// SliceUpIllegalIntegerPHI - This is an integer PHI and we know that it has an diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 9d602c6..53950ae 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2353,7 +2353,8 @@ Instruction *InstCombiner::visitLandingPadInst(LandingPadInst &LI) { // The logic here should be correct for any real-world personality function. // However if that turns out not to be true, the offending logic can always // be conditioned on the personality function, like the catch-all logic is. - EHPersonality Personality = classifyEHPersonality(LI.getPersonalityFn()); + EHPersonality Personality = + classifyEHPersonality(LI.getParent()->getParent()->getPersonalityFn()); // Simplify the list of clauses, eg by removing repeated catch clauses // (these are often created by inlining). @@ -2620,7 +2621,6 @@ Instruction *InstCombiner::visitLandingPadInst(LandingPadInst &LI) { // with a new one. if (MakeNewInstruction) { LandingPadInst *NLI = LandingPadInst::Create(LI.getType(), - LI.getPersonalityFn(), NewClauses.size()); for (unsigned i = 0, e = NewClauses.size(); i != e; ++i) NLI->addClause(NewClauses[i]); @@ -2691,7 +2691,8 @@ bool InstCombiner::run() { } // Instruction isn't dead, see if we can constant propagate it. - if (!I->use_empty() && isa<Constant>(I->getOperand(0))) { + if (!I->use_empty() && + (I->getNumOperands() == 0 || isa<Constant>(I->getOperand(0)))) { if (Constant *C = ConstantFoldInstruction(I, DL, TLI)) { DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << *I << '\n'); @@ -2846,7 +2847,8 @@ static bool AddReachableCodeToWorklist(BasicBlock *BB, const DataLayout &DL, } // ConstantProp instruction if trivially constant. - if (!Inst->use_empty() && isa<Constant>(Inst->getOperand(0))) + if (!Inst->use_empty() && + (Inst->getNumOperands() == 0 || isa<Constant>(Inst->getOperand(0)))) if (Constant *C = ConstantFoldInstruction(Inst, DL, TLI)) { DEBUG(dbgs() << "IC: ConstFold to: " << *C << " from: " << *Inst << '\n'); @@ -3044,7 +3046,7 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override; bool runOnFunction(Function &F) override; }; -} +} // namespace void InstructionCombiningPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 25f78b0..2dd2fe6 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -67,6 +67,7 @@ static const uint64_t kDefaultShadowOffset32 = 1ULL << 29; static const uint64_t kIOSShadowOffset32 = 1ULL << 30; static const uint64_t kDefaultShadowOffset64 = 1ULL << 44; static const uint64_t kSmallX86_64ShadowOffset = 0x7FFF8000; // < 2G. +static const uint64_t kLinuxKasan_ShadowOffset64 = 0xdffffc0000000000; static const uint64_t kPPC64_ShadowOffset64 = 1ULL << 41; static const uint64_t kMIPS32_ShadowOffset32 = 0x0aaa0000; static const uint64_t kMIPS64_ShadowOffset64 = 1ULL << 37; @@ -106,10 +107,8 @@ static const char *const kAsanUnpoisonStackMemoryName = static const char *const kAsanOptionDetectUAR = "__asan_option_detect_stack_use_after_return"; -static const char *const kAsanAllocaPoison = - "__asan_alloca_poison"; -static const char *const kAsanAllocasUnpoison = - "__asan_allocas_unpoison"; +static const char *const kAsanAllocaPoison = "__asan_alloca_poison"; +static const char *const kAsanAllocasUnpoison = "__asan_allocas_unpoison"; // Accesses sizes are powers of two: 1, 2, 4, 8, 16. static const size_t kNumberOfAccessSizes = 5; @@ -117,6 +116,9 @@ static const size_t kNumberOfAccessSizes = 5; static const unsigned kAllocaRzSize = 32; // Command-line flags. +static cl::opt<bool> ClEnableKasan( + "asan-kernel", cl::desc("Enable KernelAddressSanitizer instrumentation"), + cl::Hidden, cl::init(false)); // This flag may need to be replaced with -f[no-]asan-reads. static cl::opt<bool> ClInstrumentReads("asan-instrument-reads", @@ -317,7 +319,8 @@ struct ShadowMapping { bool OrShadowOffset; }; -static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize) { +static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize, + bool IsKasan) { bool IsAndroid = TargetTriple.getEnvironment() == llvm::Triple::Android; bool IsIOS = TargetTriple.isiOS(); bool IsFreeBSD = TargetTriple.isOSFreeBSD(); @@ -352,9 +355,12 @@ static ShadowMapping getShadowMapping(Triple &TargetTriple, int LongSize) { Mapping.Offset = kPPC64_ShadowOffset64; else if (IsFreeBSD) Mapping.Offset = kFreeBSD_ShadowOffset64; - else if (IsLinux && IsX86_64) - Mapping.Offset = kSmallX86_64ShadowOffset; - else if (IsMIPS64) + else if (IsLinux && IsX86_64) { + if (IsKasan) + Mapping.Offset = kLinuxKasan_ShadowOffset64; + else + Mapping.Offset = kSmallX86_64ShadowOffset; + } else if (IsMIPS64) Mapping.Offset = kMIPS64_ShadowOffset64; else if (IsAArch64) Mapping.Offset = kAArch64_ShadowOffset64; @@ -383,7 +389,8 @@ static size_t RedzoneSizeForScale(int MappingScale) { /// AddressSanitizer: instrument the code in module to find memory bugs. struct AddressSanitizer : public FunctionPass { - AddressSanitizer() : FunctionPass(ID) { + explicit AddressSanitizer(bool CompileKernel = false) + : FunctionPass(ID), CompileKernel(CompileKernel || ClEnableKasan) { initializeAddressSanitizerPass(*PassRegistry::getPassRegistry()); } const char *getPassName() const override { @@ -410,8 +417,7 @@ struct AddressSanitizer : public FunctionPass { /// If it is an interesting memory access, return the PointerOperand /// and set IsWrite/Alignment. Otherwise return nullptr. Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, - uint64_t *TypeSize, - unsigned *Alignment); + uint64_t *TypeSize, unsigned *Alignment); void instrumentMop(ObjectSizeOffsetVisitor &ObjSizeVis, Instruction *I, bool UseCalls, const DataLayout &DL); void instrumentPointerComparisonOrSubtraction(Instruction *I); @@ -447,11 +453,12 @@ struct AddressSanitizer : public FunctionPass { LLVMContext *C; Triple TargetTriple; int LongSize; + bool CompileKernel; Type *IntptrTy; ShadowMapping Mapping; DominatorTree *DT; - Function *AsanCtorFunction; - Function *AsanInitFunction; + Function *AsanCtorFunction = nullptr; + Function *AsanInitFunction = nullptr; Function *AsanHandleNoReturnFunc; Function *AsanPtrCmpFunction, *AsanPtrSubFunction; // This array is indexed by AccessIsWrite, Experiment and log2(AccessSize). @@ -470,7 +477,8 @@ struct AddressSanitizer : public FunctionPass { class AddressSanitizerModule : public ModulePass { public: - AddressSanitizerModule() : ModulePass(ID) {} + explicit AddressSanitizerModule(bool CompileKernel = false) + : ModulePass(ID), CompileKernel(CompileKernel || ClEnableKasan) {} bool runOnModule(Module &M) override; static char ID; // Pass identification, replacement for typeid const char *getPassName() const override { return "AddressSanitizerModule"; } @@ -487,6 +495,7 @@ class AddressSanitizerModule : public ModulePass { } GlobalsMetadata GlobalsMD; + bool CompileKernel; Type *IntptrTy; LLVMContext *C; Triple TargetTriple; @@ -588,7 +597,7 @@ struct FunctionStackPoisoner : public InstVisitor<FunctionStackPoisoner> { Value *SavedStack) { IRBuilder<> IRB(InstBefore); IRB.CreateCall(AsanAllocasUnpoisonFunc, - {IRB.CreateLoad(DynamicAllocaLayout), + {IRB.CreateLoad(DynamicAllocaLayout), IRB.CreatePtrToInt(SavedStack, IntptrTy)}); } @@ -692,8 +701,8 @@ INITIALIZE_PASS_END( AddressSanitizer, "asan", "AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false, false) -FunctionPass *llvm::createAddressSanitizerFunctionPass() { - return new AddressSanitizer(); +FunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel) { + return new AddressSanitizer(CompileKernel); } char AddressSanitizerModule::ID = 0; @@ -702,8 +711,8 @@ INITIALIZE_PASS( "AddressSanitizer: detects use-after-free and out-of-bounds bugs." "ModulePass", false, false) -ModulePass *llvm::createAddressSanitizerModulePass() { - return new AddressSanitizerModule(); +ModulePass *llvm::createAddressSanitizerModulePass(bool CompileKernel) { + return new AddressSanitizerModule(CompileKernel); } static size_t TypeSizeToSizeIndex(uint32_t TypeSize) { @@ -1347,16 +1356,18 @@ bool AddressSanitizerModule::runOnModule(Module &M) { int LongSize = M.getDataLayout().getPointerSizeInBits(); IntptrTy = Type::getIntNTy(*C, LongSize); TargetTriple = Triple(M.getTargetTriple()); - Mapping = getShadowMapping(TargetTriple, LongSize); + Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); initializeCallbacks(M); bool Changed = false; - Function *CtorFunc = M.getFunction(kAsanModuleCtorName); - assert(CtorFunc); - IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); - - if (ClGlobals) Changed |= InstrumentGlobals(IRB, M); + // TODO(glider): temporarily disabled globals instrumentation for KASan. + if (ClGlobals && !CompileKernel) { + Function *CtorFunc = M.getFunction(kAsanModuleCtorName); + assert(CtorFunc); + IRBuilder<> IRB(CtorFunc->getEntryBlock().getTerminator()); + Changed |= InstrumentGlobals(IRB, M); + } return Changed; } @@ -1369,38 +1380,44 @@ void AddressSanitizer::initializeCallbacks(Module &M) { for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) { const std::string TypeStr = AccessIsWrite ? "store" : "load"; const std::string ExpStr = Exp ? "exp_" : ""; + const std::string SuffixStr = CompileKernel ? "N" : "_n"; + const std::string EndingStr = CompileKernel ? "_noabort" : ""; const Type *ExpType = Exp ? Type::getInt32Ty(*C) : nullptr; + // TODO(glider): for KASan builds add _noabort to error reporting + // functions and make them actually noabort (remove the UnreachableInst). AsanErrorCallbackSized[AccessIsWrite][Exp] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - kAsanReportErrorTemplate + ExpStr + TypeStr + "_n", + kAsanReportErrorTemplate + ExpStr + TypeStr + SuffixStr, IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); AsanMemoryAccessCallbackSized[AccessIsWrite][Exp] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N", + ClMemoryAccessCallbackPrefix + ExpStr + TypeStr + "N" + EndingStr, IRB.getVoidTy(), IntptrTy, IntptrTy, ExpType, nullptr)); for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; AccessSizeIndex++) { const std::string Suffix = TypeStr + itostr(1 << AccessSizeIndex); AsanErrorCallback[AccessIsWrite][Exp][AccessSizeIndex] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - kAsanReportErrorTemplate + ExpStr + Suffix, IRB.getVoidTy(), - IntptrTy, ExpType, nullptr)); + kAsanReportErrorTemplate + ExpStr + Suffix, + IRB.getVoidTy(), IntptrTy, ExpType, nullptr)); AsanMemoryAccessCallback[AccessIsWrite][Exp][AccessSizeIndex] = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + ExpStr + Suffix, IRB.getVoidTy(), - IntptrTy, ExpType, nullptr)); + ClMemoryAccessCallbackPrefix + ExpStr + Suffix + EndingStr, + IRB.getVoidTy(), IntptrTy, ExpType, nullptr)); } } } + const std::string MemIntrinCallbackPrefix = + CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix; AsanMemmove = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + "memmove", IRB.getInt8PtrTy(), + MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); AsanMemcpy = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), + MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy, nullptr)); AsanMemset = checkSanitizerInterfaceFunction(M.getOrInsertFunction( - ClMemoryAccessCallbackPrefix + "memset", IRB.getInt8PtrTy(), + MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy, nullptr)); AsanHandleNoReturnFunc = checkSanitizerInterfaceFunction( @@ -1427,14 +1444,14 @@ bool AddressSanitizer::doInitialization(Module &M) { IntptrTy = Type::getIntNTy(*C, LongSize); TargetTriple = Triple(M.getTargetTriple()); - std::tie(AsanCtorFunction, AsanInitFunction) = - createSanitizerCtorAndInitFunctions(M, kAsanModuleCtorName, kAsanInitName, - /*InitArgTypes=*/{}, - /*InitArgs=*/{}); - - Mapping = getShadowMapping(TargetTriple, LongSize); - - appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); + if (!CompileKernel) { + std::tie(AsanCtorFunction, AsanInitFunction) = + createSanitizerCtorAndInitFunctions(M, kAsanModuleCtorName, kAsanInitName, + /*InitArgTypes=*/{}, + /*InitArgs=*/{}); + appendToGlobalCtors(M, AsanCtorFunction, kAsanCtorAndDtorPriority); + } + Mapping = getShadowMapping(TargetTriple, LongSize, CompileKernel); return true; } @@ -1516,11 +1533,10 @@ bool AddressSanitizer::runOnFunction(Function &F) { } } - bool UseCalls = false; - if (ClInstrumentationWithCallsThreshold >= 0 && - ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold) - UseCalls = true; - + bool UseCalls = + CompileKernel || + (ClInstrumentationWithCallsThreshold >= 0 && + ToInstrument.size() > (unsigned)ClInstrumentationWithCallsThreshold); const TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); const DataLayout &DL = F.getParent()->getDataLayout(); @@ -1706,8 +1722,7 @@ void FunctionStackPoisoner::poisonStack() { if (ClInstrumentAllocas && DynamicAllocaVec.size() > 0) { // Handle dynamic allocas. createDynamicAllocasInitStorage(); - for (auto &AI : DynamicAllocaVec) - handleDynamicAllocaCall(AI); + for (auto &AI : DynamicAllocaVec) handleDynamicAllocaCall(AI); unpoisonDynamicAllocas(); } @@ -1736,8 +1751,8 @@ void FunctionStackPoisoner::poisonStack() { ComputeASanStackFrameLayout(SVD, 1UL << Mapping.Scale, MinHeaderSize, &L); DEBUG(dbgs() << L.DescriptionString << " --- " << L.FrameSize << "\n"); uint64_t LocalStackSize = L.FrameSize; - bool DoStackMalloc = - ClUseAfterReturn && LocalStackSize <= kMaxStackMallocSize; + bool DoStackMalloc = ClUseAfterReturn && !ASan.CompileKernel && + LocalStackSize <= kMaxStackMallocSize; // Don't do dynamic alloca in presence of inline asm: too often it makes // assumptions on which registers are available. Don't do stack malloc in the // presence of inline asm on 32-bit platforms for the same reason. @@ -1901,9 +1916,9 @@ void FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, // For now just insert the call to ASan runtime. Value *AddrArg = IRB.CreatePointerCast(V, IntptrTy); Value *SizeArg = ConstantInt::get(IntptrTy, Size); - IRB.CreateCall(DoPoison ? AsanPoisonStackMemoryFunc - : AsanUnpoisonStackMemoryFunc, - {AddrArg, SizeArg}); + IRB.CreateCall( + DoPoison ? AsanPoisonStackMemoryFunc : AsanUnpoisonStackMemoryFunc, + {AddrArg, SizeArg}); } // Handling llvm.lifetime intrinsics for a given %alloca: diff --git a/lib/Transforms/Instrumentation/BoundsChecking.cpp b/lib/Transforms/Instrumentation/BoundsChecking.cpp index f685803..a887425 100644 --- a/lib/Transforms/Instrumentation/BoundsChecking.cpp +++ b/lib/Transforms/Instrumentation/BoundsChecking.cpp @@ -63,7 +63,7 @@ namespace { void emitBranchToTrap(Value *Cmp = nullptr); bool instrument(Value *Ptr, Value *Val, const DataLayout &DL); }; -} +} // namespace char BoundsChecking::ID = 0; INITIALIZE_PASS(BoundsChecking, "bounds-checking", "Run-time bounds checking", diff --git a/lib/Transforms/Instrumentation/CMakeLists.txt b/lib/Transforms/Instrumentation/CMakeLists.txt index b2ff033..9b81f4b 100644 --- a/lib/Transforms/Instrumentation/CMakeLists.txt +++ b/lib/Transforms/Instrumentation/CMakeLists.txt @@ -6,6 +6,7 @@ add_llvm_library(LLVMInstrumentation MemorySanitizer.cpp Instrumentation.cpp InstrProfiling.cpp + SafeStack.cpp SanitizerCoverage.cpp ThreadSanitizer.cpp diff --git a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 2de6e1a..4309157 100644 --- a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -346,7 +346,7 @@ class DFSanVisitor : public InstVisitor<DFSanVisitor> { void visitMemTransferInst(MemTransferInst &I); }; -} +} // namespace char DataFlowSanitizer::ID; INITIALIZE_PASS(DataFlowSanitizer, "dfsan", diff --git a/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/lib/Transforms/Instrumentation/GCOVProfiling.cpp index 9a3ed5c..43caf1f 100644 --- a/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -139,7 +139,7 @@ namespace { LLVMContext *Ctx; SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs; }; -} +} // namespace char GCOVProfiler::ID = 0; INITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", @@ -419,7 +419,7 @@ namespace { DenseMap<BasicBlock *, GCOVBlock> Blocks; GCOVBlock ReturnBlock; }; -} +} // namespace std::string GCOVProfiler::mangleName(const DICompileUnit *CU, const char *NewStem) { diff --git a/lib/Transforms/Instrumentation/Instrumentation.cpp b/lib/Transforms/Instrumentation/Instrumentation.cpp index a91fc0e..2750585 100644 --- a/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -30,6 +30,7 @@ void llvm::initializeInstrumentation(PassRegistry &Registry) { initializeThreadSanitizerPass(Registry); initializeSanitizerCoverageModulePass(Registry); initializeDataFlowSanitizerPass(Registry); + initializeSafeStackPass(Registry); } /// LLVMInitializeInstrumentation - C binding for diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 100824e..63eee2f 100644 --- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -2022,6 +2022,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { Value *CopyOp, *ConvertOp; switch (I.getNumArgOperands()) { + case 3: + assert(isa<ConstantInt>(I.getArgOperand(2)) && "Invalid rounding mode"); case 2: CopyOp = I.getArgOperand(0); ConvertOp = I.getArgOperand(1); diff --git a/lib/Transforms/Instrumentation/SafeStack.cpp b/lib/Transforms/Instrumentation/SafeStack.cpp new file mode 100644 index 0000000..13c5412 --- /dev/null +++ b/lib/Transforms/Instrumentation/SafeStack.cpp @@ -0,0 +1,608 @@ +//===-- SafeStack.cpp - Safe Stack Insertion ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass splits the stack into the safe stack (kept as-is for LLVM backend) +// and the unsafe stack (explicitly allocated and managed through the runtime +// support library). +// +// http://clang.llvm.org/docs/SafeStack.html +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Instrumentation.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DIBuilder.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/InstIterator.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_os_ostream.h" +#include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" + +using namespace llvm; + +#define DEBUG_TYPE "safestack" + +namespace llvm { + +STATISTIC(NumFunctions, "Total number of functions"); +STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack"); +STATISTIC(NumUnsafeStackRestorePointsFunctions, + "Number of functions that use setjmp or exceptions"); + +STATISTIC(NumAllocas, "Total number of allocas"); +STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas"); +STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas"); +STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads"); + +} // namespace llvm + +namespace { + +/// Check whether a given alloca instruction (AI) should be put on the safe +/// stack or not. The function analyzes all uses of AI and checks whether it is +/// only accessed in a memory safe way (as decided statically). +bool IsSafeStackAlloca(const AllocaInst *AI) { + // Go through all uses of this alloca and check whether all accesses to the + // allocated object are statically known to be memory safe and, hence, the + // object can be placed on the safe stack. + + SmallPtrSet<const Value *, 16> Visited; + SmallVector<const Instruction *, 8> WorkList; + WorkList.push_back(AI); + + // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc. + while (!WorkList.empty()) { + const Instruction *V = WorkList.pop_back_val(); + for (const Use &UI : V->uses()) { + auto I = cast<const Instruction>(UI.getUser()); + assert(V == UI.get()); + + switch (I->getOpcode()) { + case Instruction::Load: + // Loading from a pointer is safe. + break; + case Instruction::VAArg: + // "va-arg" from a pointer is safe. + break; + case Instruction::Store: + if (V == I->getOperand(0)) + // Stored the pointer - conservatively assume it may be unsafe. + return false; + // Storing to the pointee is safe. + break; + + case Instruction::GetElementPtr: + if (!cast<const GetElementPtrInst>(I)->hasAllConstantIndices()) + // GEP with non-constant indices can lead to memory errors. + // This also applies to inbounds GEPs, as the inbounds attribute + // represents an assumption that the address is in bounds, rather than + // an assertion that it is. + return false; + + // We assume that GEP on static alloca with constant indices is safe, + // otherwise a compiler would detect it and warn during compilation. + + if (!isa<const ConstantInt>(AI->getArraySize())) + // However, if the array size itself is not constant, the access + // might still be unsafe at runtime. + return false; + + /* fallthrough */ + + case Instruction::BitCast: + case Instruction::IntToPtr: + case Instruction::PHI: + case Instruction::PtrToInt: + case Instruction::Select: + // The object can be safe or not, depending on how the result of the + // instruction is used. + if (Visited.insert(I).second) + WorkList.push_back(cast<const Instruction>(I)); + break; + + case Instruction::Call: + case Instruction::Invoke: { + // FIXME: add support for memset and memcpy intrinsics. + ImmutableCallSite CS(I); + + // LLVM 'nocapture' attribute is only set for arguments whose address + // is not stored, passed around, or used in any other non-trivial way. + // We assume that passing a pointer to an object as a 'nocapture' + // argument is safe. + // FIXME: a more precise solution would require an interprocedural + // analysis here, which would look at all uses of an argument inside + // the function being called. + ImmutableCallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); + for (ImmutableCallSite::arg_iterator A = B; A != E; ++A) + if (A->get() == V && !CS.doesNotCapture(A - B)) + // The parameter is not marked 'nocapture' - unsafe. + return false; + continue; + } + + default: + // The object is unsafe if it is used in any other way. + return false; + } + } + } + + // All uses of the alloca are safe, we can place it on the safe stack. + return true; +} + +/// The SafeStack pass splits the stack of each function into the +/// safe stack, which is only accessed through memory safe dereferences +/// (as determined statically), and the unsafe stack, which contains all +/// local variables that are accessed in unsafe ways. +class SafeStack : public FunctionPass { + const DataLayout *DL; + + Type *StackPtrTy; + Type *IntPtrTy; + Type *Int32Ty; + Type *Int8Ty; + + Constant *UnsafeStackPtr; + + /// Unsafe stack alignment. Each stack frame must ensure that the stack is + /// aligned to this value. We need to re-align the unsafe stack if the + /// alignment of any object on the stack exceeds this value. + /// + /// 16 seems like a reasonable upper bound on the alignment of objects that we + /// might expect to appear on the stack on most common targets. + enum { StackAlignment = 16 }; + + /// \brief Build a constant representing a pointer to the unsafe stack + /// pointer. + Constant *getOrCreateUnsafeStackPtr(Module &M); + + /// \brief Find all static allocas, dynamic allocas, return instructions and + /// stack restore points (exception unwind blocks and setjmp calls) in the + /// given function and append them to the respective vectors. + void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas, + SmallVectorImpl<AllocaInst *> &DynamicAllocas, + SmallVectorImpl<ReturnInst *> &Returns, + SmallVectorImpl<Instruction *> &StackRestorePoints); + + /// \brief Allocate space for all static allocas in \p StaticAllocas, + /// replace allocas with pointers into the unsafe stack and generate code to + /// restore the stack pointer before all return instructions in \p Returns. + /// + /// \returns A pointer to the top of the unsafe stack after all unsafe static + /// allocas are allocated. + Value *moveStaticAllocasToUnsafeStack(Function &F, + ArrayRef<AllocaInst *> StaticAllocas, + ArrayRef<ReturnInst *> Returns); + + /// \brief Generate code to restore the stack after all stack restore points + /// in \p StackRestorePoints. + /// + /// \returns A local variable in which to maintain the dynamic top of the + /// unsafe stack if needed. + AllocaInst * + createStackRestorePoints(Function &F, + ArrayRef<Instruction *> StackRestorePoints, + Value *StaticTop, bool NeedDynamicTop); + + /// \brief Replace all allocas in \p DynamicAllocas with code to allocate + /// space dynamically on the unsafe stack and store the dynamic unsafe stack + /// top to \p DynamicTop if non-null. + void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr, + AllocaInst *DynamicTop, + ArrayRef<AllocaInst *> DynamicAllocas); + +public: + static char ID; // Pass identification, replacement for typeid. + SafeStack() : FunctionPass(ID), DL(nullptr) { + initializeSafeStackPass(*PassRegistry::getPassRegistry()); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<AliasAnalysis>(); + } + + virtual bool doInitialization(Module &M) { + DL = &M.getDataLayout(); + + StackPtrTy = Type::getInt8PtrTy(M.getContext()); + IntPtrTy = DL->getIntPtrType(M.getContext()); + Int32Ty = Type::getInt32Ty(M.getContext()); + Int8Ty = Type::getInt8Ty(M.getContext()); + + UnsafeStackPtr = getOrCreateUnsafeStackPtr(M); + + return false; + } + + bool runOnFunction(Function &F); + +}; // class SafeStack + +Constant *SafeStack::getOrCreateUnsafeStackPtr(Module &M) { + // The unsafe stack pointer is stored in a global variable with a magic name. + const char *kUnsafeStackPtrVar = "__safestack_unsafe_stack_ptr"; + + auto UnsafeStackPtr = + dyn_cast_or_null<GlobalVariable>(M.getNamedValue(kUnsafeStackPtrVar)); + + if (!UnsafeStackPtr) { + // The global variable is not defined yet, define it ourselves. + // We use the initial-exec TLS model because we do not support the variable + // living anywhere other than in the main executable. + UnsafeStackPtr = new GlobalVariable( + /*Module=*/M, /*Type=*/StackPtrTy, + /*isConstant=*/false, /*Linkage=*/GlobalValue::ExternalLinkage, + /*Initializer=*/0, /*Name=*/kUnsafeStackPtrVar, + /*InsertBefore=*/nullptr, + /*ThreadLocalMode=*/GlobalValue::InitialExecTLSModel); + } else { + // The variable exists, check its type and attributes. + if (UnsafeStackPtr->getValueType() != StackPtrTy) { + report_fatal_error(Twine(kUnsafeStackPtrVar) + " must have void* type"); + } + + if (!UnsafeStackPtr->isThreadLocal()) { + report_fatal_error(Twine(kUnsafeStackPtrVar) + " must be thread-local"); + } + } + + return UnsafeStackPtr; +} + +void SafeStack::findInsts(Function &F, + SmallVectorImpl<AllocaInst *> &StaticAllocas, + SmallVectorImpl<AllocaInst *> &DynamicAllocas, + SmallVectorImpl<ReturnInst *> &Returns, + SmallVectorImpl<Instruction *> &StackRestorePoints) { + for (Instruction &I : inst_range(&F)) { + if (auto AI = dyn_cast<AllocaInst>(&I)) { + ++NumAllocas; + + if (IsSafeStackAlloca(AI)) + continue; + + if (AI->isStaticAlloca()) { + ++NumUnsafeStaticAllocas; + StaticAllocas.push_back(AI); + } else { + ++NumUnsafeDynamicAllocas; + DynamicAllocas.push_back(AI); + } + } else if (auto RI = dyn_cast<ReturnInst>(&I)) { + Returns.push_back(RI); + } else if (auto CI = dyn_cast<CallInst>(&I)) { + // setjmps require stack restore. + if (CI->getCalledFunction() && CI->canReturnTwice()) + StackRestorePoints.push_back(CI); + } else if (auto LP = dyn_cast<LandingPadInst>(&I)) { + // Exception landing pads require stack restore. + StackRestorePoints.push_back(LP); + } else if (auto II = dyn_cast<IntrinsicInst>(&I)) { + if (II->getIntrinsicID() == Intrinsic::gcroot) + llvm::report_fatal_error( + "gcroot intrinsic not compatible with safestack attribute"); + } + } +} + +AllocaInst * +SafeStack::createStackRestorePoints(Function &F, + ArrayRef<Instruction *> StackRestorePoints, + Value *StaticTop, bool NeedDynamicTop) { + if (StackRestorePoints.empty()) + return nullptr; + + IRBuilder<> IRB(StaticTop + ? cast<Instruction>(StaticTop)->getNextNode() + : (Instruction *)F.getEntryBlock().getFirstInsertionPt()); + + // We need the current value of the shadow stack pointer to restore + // after longjmp or exception catching. + + // FIXME: On some platforms this could be handled by the longjmp/exception + // runtime itself. + + AllocaInst *DynamicTop = nullptr; + if (NeedDynamicTop) + // If we also have dynamic alloca's, the stack pointer value changes + // throughout the function. For now we store it in an alloca. + DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr, + "unsafe_stack_dynamic_ptr"); + + if (!StaticTop) + // We need the original unsafe stack pointer value, even if there are + // no unsafe static allocas. + StaticTop = IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr"); + + if (NeedDynamicTop) + IRB.CreateStore(StaticTop, DynamicTop); + + // Restore current stack pointer after longjmp/exception catch. + for (Instruction *I : StackRestorePoints) { + ++NumUnsafeStackRestorePoints; + + IRB.SetInsertPoint(cast<Instruction>(I->getNextNode())); + Value *CurrentTop = DynamicTop ? IRB.CreateLoad(DynamicTop) : StaticTop; + IRB.CreateStore(CurrentTop, UnsafeStackPtr); + } + + return DynamicTop; +} + +Value * +SafeStack::moveStaticAllocasToUnsafeStack(Function &F, + ArrayRef<AllocaInst *> StaticAllocas, + ArrayRef<ReturnInst *> Returns) { + if (StaticAllocas.empty()) + return nullptr; + + IRBuilder<> IRB(F.getEntryBlock().getFirstInsertionPt()); + DIBuilder DIB(*F.getParent()); + + // We explicitly compute and set the unsafe stack layout for all unsafe + // static alloca instructions. We save the unsafe "base pointer" in the + // prologue into a local variable and restore it in the epilogue. + + // Load the current stack pointer (we'll also use it as a base pointer). + // FIXME: use a dedicated register for it ? + Instruction *BasePointer = + IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr"); + assert(BasePointer->getType() == StackPtrTy); + + for (ReturnInst *RI : Returns) { + IRB.SetInsertPoint(RI); + IRB.CreateStore(BasePointer, UnsafeStackPtr); + } + + // Compute maximum alignment among static objects on the unsafe stack. + unsigned MaxAlignment = 0; + for (AllocaInst *AI : StaticAllocas) { + Type *Ty = AI->getAllocatedType(); + unsigned Align = + std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); + if (Align > MaxAlignment) + MaxAlignment = Align; + } + + if (MaxAlignment > StackAlignment) { + // Re-align the base pointer according to the max requested alignment. + assert(isPowerOf2_32(MaxAlignment)); + IRB.SetInsertPoint(cast<Instruction>(BasePointer->getNextNode())); + BasePointer = cast<Instruction>(IRB.CreateIntToPtr( + IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy), + ConstantInt::get(IntPtrTy, ~uint64_t(MaxAlignment - 1))), + StackPtrTy)); + } + + // Allocate space for every unsafe static AllocaInst on the unsafe stack. + int64_t StaticOffset = 0; // Current stack top. + for (AllocaInst *AI : StaticAllocas) { + IRB.SetInsertPoint(AI); + + auto CArraySize = cast<ConstantInt>(AI->getArraySize()); + Type *Ty = AI->getAllocatedType(); + + uint64_t Size = DL->getTypeAllocSize(Ty) * CArraySize->getZExtValue(); + if (Size == 0) + Size = 1; // Don't create zero-sized stack objects. + + // Ensure the object is properly aligned. + unsigned Align = + std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); + + // Add alignment. + // NOTE: we ensure that BasePointer itself is aligned to >= Align. + StaticOffset += Size; + StaticOffset = RoundUpToAlignment(StaticOffset, Align); + + Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8* + ConstantInt::get(Int32Ty, -StaticOffset)); + Value *NewAI = IRB.CreateBitCast(Off, AI->getType(), AI->getName()); + if (AI->hasName() && isa<Instruction>(NewAI)) + cast<Instruction>(NewAI)->takeName(AI); + + // Replace alloc with the new location. + replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true); + AI->replaceAllUsesWith(NewAI); + AI->eraseFromParent(); + } + + // Re-align BasePointer so that our callees would see it aligned as + // expected. + // FIXME: no need to update BasePointer in leaf functions. + StaticOffset = RoundUpToAlignment(StaticOffset, StackAlignment); + + // Update shadow stack pointer in the function epilogue. + IRB.SetInsertPoint(cast<Instruction>(BasePointer->getNextNode())); + + Value *StaticTop = + IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -StaticOffset), + "unsafe_stack_static_top"); + IRB.CreateStore(StaticTop, UnsafeStackPtr); + return StaticTop; +} + +void SafeStack::moveDynamicAllocasToUnsafeStack( + Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop, + ArrayRef<AllocaInst *> DynamicAllocas) { + DIBuilder DIB(*F.getParent()); + + for (AllocaInst *AI : DynamicAllocas) { + IRBuilder<> IRB(AI); + + // Compute the new SP value (after AI). + Value *ArraySize = AI->getArraySize(); + if (ArraySize->getType() != IntPtrTy) + ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false); + + Type *Ty = AI->getAllocatedType(); + uint64_t TySize = DL->getTypeAllocSize(Ty); + Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize)); + + Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(UnsafeStackPtr), IntPtrTy); + SP = IRB.CreateSub(SP, Size); + + // Align the SP value to satisfy the AllocaInst, type and stack alignments. + unsigned Align = std::max( + std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()), + (unsigned)StackAlignment); + + assert(isPowerOf2_32(Align)); + Value *NewTop = IRB.CreateIntToPtr( + IRB.CreateAnd(SP, ConstantInt::get(IntPtrTy, ~uint64_t(Align - 1))), + StackPtrTy); + + // Save the stack pointer. + IRB.CreateStore(NewTop, UnsafeStackPtr); + if (DynamicTop) + IRB.CreateStore(NewTop, DynamicTop); + + Value *NewAI = IRB.CreateIntToPtr(SP, AI->getType()); + if (AI->hasName() && isa<Instruction>(NewAI)) + NewAI->takeName(AI); + + replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true); + AI->replaceAllUsesWith(NewAI); + AI->eraseFromParent(); + } + + if (!DynamicAllocas.empty()) { + // Now go through the instructions again, replacing stacksave/stackrestore. + for (inst_iterator It = inst_begin(&F), Ie = inst_end(&F); It != Ie;) { + Instruction *I = &*(It++); + auto II = dyn_cast<IntrinsicInst>(I); + if (!II) + continue; + + if (II->getIntrinsicID() == Intrinsic::stacksave) { + IRBuilder<> IRB(II); + Instruction *LI = IRB.CreateLoad(UnsafeStackPtr); + LI->takeName(II); + II->replaceAllUsesWith(LI); + II->eraseFromParent(); + } else if (II->getIntrinsicID() == Intrinsic::stackrestore) { + IRBuilder<> IRB(II); + Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr); + SI->takeName(II); + assert(II->use_empty()); + II->eraseFromParent(); + } + } + } +} + +bool SafeStack::runOnFunction(Function &F) { + auto AA = &getAnalysis<AliasAnalysis>(); + + DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n"); + + if (!F.hasFnAttribute(Attribute::SafeStack)) { + DEBUG(dbgs() << "[SafeStack] safestack is not requested" + " for this function\n"); + return false; + } + + if (F.isDeclaration()) { + DEBUG(dbgs() << "[SafeStack] function definition" + " is not available\n"); + return false; + } + + { + // Make sure the regular stack protector won't run on this function + // (safestack attribute takes precedence). + AttrBuilder B; + B.addAttribute(Attribute::StackProtect) + .addAttribute(Attribute::StackProtectReq) + .addAttribute(Attribute::StackProtectStrong); + F.removeAttributes( + AttributeSet::FunctionIndex, + AttributeSet::get(F.getContext(), AttributeSet::FunctionIndex, B)); + } + + if (AA->onlyReadsMemory(&F)) { + // XXX: we don't protect against information leak attacks for now. + DEBUG(dbgs() << "[SafeStack] function only reads memory\n"); + return false; + } + + ++NumFunctions; + + SmallVector<AllocaInst *, 16> StaticAllocas; + SmallVector<AllocaInst *, 4> DynamicAllocas; + SmallVector<ReturnInst *, 4> Returns; + + // Collect all points where stack gets unwound and needs to be restored + // This is only necessary because the runtime (setjmp and unwind code) is + // not aware of the unsafe stack and won't unwind/restore it prorerly. + // To work around this problem without changing the runtime, we insert + // instrumentation to restore the unsafe stack pointer when necessary. + SmallVector<Instruction *, 4> StackRestorePoints; + + // Find all static and dynamic alloca instructions that must be moved to the + // unsafe stack, all return instructions and stack restore points. + findInsts(F, StaticAllocas, DynamicAllocas, Returns, StackRestorePoints); + + if (StaticAllocas.empty() && DynamicAllocas.empty() && + StackRestorePoints.empty()) + return false; // Nothing to do in this function. + + if (!StaticAllocas.empty() || !DynamicAllocas.empty()) + ++NumUnsafeStackFunctions; // This function has the unsafe stack. + + if (!StackRestorePoints.empty()) + ++NumUnsafeStackRestorePointsFunctions; + + // The top of the unsafe stack after all unsafe static allocas are allocated. + Value *StaticTop = moveStaticAllocasToUnsafeStack(F, StaticAllocas, Returns); + + // Safe stack object that stores the current unsafe stack top. It is updated + // as unsafe dynamic (non-constant-sized) allocas are allocated and freed. + // This is only needed if we need to restore stack pointer after longjmp + // or exceptions, and we have dynamic allocations. + // FIXME: a better alternative might be to store the unsafe stack pointer + // before setjmp / invoke instructions. + AllocaInst *DynamicTop = createStackRestorePoints( + F, StackRestorePoints, StaticTop, !DynamicAllocas.empty()); + + // Handle dynamic allocas. + moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop, + DynamicAllocas); + + DEBUG(dbgs() << "[SafeStack] safestack applied\n"); + return true; +} + +} // end anonymous namespace + +char SafeStack::ID = 0; +INITIALIZE_PASS_BEGIN(SafeStack, "safe-stack", + "Safe Stack instrumentation pass", false, false) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END(SafeStack, "safe-stack", "Safe Stack instrumentation pass", + false, false) + +FunctionPass *llvm::createSafeStackPass() { return new SafeStack(); } diff --git a/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/lib/Transforms/Instrumentation/SanitizerCoverage.cpp index f6ae0c2..dff39ef 100644 --- a/lib/Transforms/Instrumentation/SanitizerCoverage.cpp +++ b/lib/Transforms/Instrumentation/SanitizerCoverage.cpp @@ -33,6 +33,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" @@ -385,9 +386,14 @@ void SanitizerCoverageModule::InjectCoverageAtBlock(Function &F, BasicBlock &BB, } bool IsEntryBB = &BB == &F.getEntryBlock(); - DebugLoc EntryLoc = IsEntryBB && IP->getDebugLoc() - ? IP->getDebugLoc().getFnDebugLoc() - : IP->getDebugLoc(); + DebugLoc EntryLoc; + if (IsEntryBB) { + if (auto SP = getDISubprogram(&F)) + EntryLoc = DebugLoc::get(SP->getScopeLine(), 0, SP); + } else { + EntryLoc = IP->getDebugLoc(); + } + IRBuilder<> IRB(IP); IRB.SetCurrentDebugLocation(EntryLoc); SmallVector<Value *, 1> Indices; diff --git a/lib/Transforms/ObjCARC/BlotMapVector.h b/lib/Transforms/ObjCARC/BlotMapVector.h index d6439b6..f9fde26 100644 --- a/lib/Transforms/ObjCARC/BlotMapVector.h +++ b/lib/Transforms/ObjCARC/BlotMapVector.h @@ -105,4 +105,4 @@ public: return Map.empty(); } }; -} // +} // namespace llvm diff --git a/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp b/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp index d318643..c7c77ec 100644 --- a/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp @@ -50,7 +50,7 @@ namespace { initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry()); } }; -} +} // namespace char ObjCARCAPElim::ID = 0; INITIALIZE_PASS(ObjCARCAPElim, diff --git a/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp b/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp index b1515e3..94b092c 100644 --- a/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp @@ -58,7 +58,8 @@ ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { } AliasAnalysis::AliasResult -ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) { +ObjCARCAliasAnalysis::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) { if (!EnableARCOpts) return AliasAnalysis::alias(LocA, LocB); @@ -67,8 +68,8 @@ ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) { const Value *SA = GetRCIdentityRoot(LocA.Ptr); const Value *SB = GetRCIdentityRoot(LocB.Ptr); AliasResult Result = - AliasAnalysis::alias(Location(SA, LocA.Size, LocA.AATags), - Location(SB, LocB.Size, LocB.AATags)); + AliasAnalysis::alias(MemoryLocation(SA, LocA.Size, LocA.AATags), + MemoryLocation(SB, LocB.Size, LocB.AATags)); if (Result != MayAlias) return Result; @@ -77,7 +78,7 @@ ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) { const Value *UA = GetUnderlyingObjCPtr(SA, *DL); const Value *UB = GetUnderlyingObjCPtr(SB, *DL); if (UA != SA || UB != SB) { - Result = AliasAnalysis::alias(Location(UA), Location(UB)); + Result = AliasAnalysis::alias(MemoryLocation(UA), MemoryLocation(UB)); // We can't use MustAlias or PartialAlias results here because // GetUnderlyingObjCPtr may return an offsetted pointer value. if (Result == NoAlias) @@ -89,24 +90,23 @@ ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) { return MayAlias; } -bool -ObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc, - bool OrLocal) { +bool ObjCARCAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) { if (!EnableARCOpts) return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal); // First, strip off no-ops, including ObjC-specific no-ops, and try making // a precise alias query. const Value *S = GetRCIdentityRoot(Loc.Ptr); - if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.AATags), - OrLocal)) + if (AliasAnalysis::pointsToConstantMemory( + MemoryLocation(S, Loc.Size, Loc.AATags), OrLocal)) return true; // If that failed, climb to the underlying object, including climbing through // ObjC-specific no-ops, and try making an imprecise alias query. const Value *U = GetUnderlyingObjCPtr(S, *DL); if (U != S) - return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal); + return AliasAnalysis::pointsToConstantMemory(MemoryLocation(U), OrLocal); // If that failed, fail. We don't need to chain here, since that's covered // by the earlier precise query. @@ -135,7 +135,8 @@ ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) { } AliasAnalysis::ModRefResult -ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) { +ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, + const MemoryLocation &Loc) { if (!EnableARCOpts) return AliasAnalysis::getModRefInfo(CS, Loc); diff --git a/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h b/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h index 3c5a021..eecc82f 100644 --- a/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h +++ b/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h @@ -56,12 +56,14 @@ namespace objcarc { } void getAnalysisUsage(AnalysisUsage &AU) const override; - AliasResult alias(const Location &LocA, const Location &LocB) override; - bool pointsToConstantMemory(const Location &Loc, bool OrLocal) override; + AliasResult alias(const MemoryLocation &LocA, + const MemoryLocation &LocB) override; + bool pointsToConstantMemory(const MemoryLocation &Loc, + bool OrLocal) override; ModRefBehavior getModRefBehavior(ImmutableCallSite CS) override; ModRefBehavior getModRefBehavior(const Function *F) override; ModRefResult getModRefInfo(ImmutableCallSite CS, - const Location &Loc) override; + const MemoryLocation &Loc) override; ModRefResult getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) override; }; diff --git a/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/lib/Transforms/ObjCARC/ObjCARCContract.cpp index e7731ad..080dbc0 100644 --- a/lib/Transforms/ObjCARC/ObjCARCContract.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCContract.cpp @@ -101,7 +101,7 @@ namespace { initializeObjCARCContractPass(*PassRegistry::getPassRegistry()); } }; -} +} // namespace //===----------------------------------------------------------------------===// // Implementation @@ -200,7 +200,7 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load, bool SawRelease = false; // Get the location associated with Load. - AliasAnalysis::Location Loc = MemoryLocation::get(Load); + MemoryLocation Loc = MemoryLocation::get(Load); // Walk down to find the store and the release, which may be in either order. for (auto I = std::next(BasicBlock::iterator(Load)), @@ -212,7 +212,7 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load, break; // Now we know that we have not seen either the store or the release. If I - // is the the release, mark that we saw the release and continue. + // is the release, mark that we saw the release and continue. Instruction *Inst = &*I; if (Inst == Release) { SawRelease = true; diff --git a/lib/Transforms/ObjCARC/ObjCARCExpand.cpp b/lib/Transforms/ObjCARC/ObjCARCExpand.cpp index 53c19c3..4f2f7da 100644 --- a/lib/Transforms/ObjCARC/ObjCARCExpand.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCExpand.cpp @@ -63,7 +63,7 @@ namespace { initializeObjCARCExpandPass(*PassRegistry::getPassRegistry()); } }; -} +} // namespace char ObjCARCExpand::ID = 0; INITIALIZE_PASS(ObjCARCExpand, diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index dca3f1b..cdbbfac 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -313,7 +313,7 @@ namespace { }; const unsigned BBState::OverflowOccurredValue = 0xffffffff; -} +} // namespace namespace llvm { raw_ostream &operator<<(raw_ostream &OS, @@ -551,7 +551,7 @@ namespace { initializeObjCARCOptPass(*PassRegistry::getPassRegistry()); } }; -} +} // namespace char ObjCARCOpt::ID = 0; INITIALIZE_PASS_BEGIN(ObjCARCOpt, diff --git a/lib/Transforms/Scalar/ADCE.cpp b/lib/Transforms/Scalar/ADCE.cpp index d6fc916..fe0224b 100644 --- a/lib/Transforms/Scalar/ADCE.cpp +++ b/lib/Transforms/Scalar/ADCE.cpp @@ -44,7 +44,7 @@ struct ADCE : public FunctionPass { AU.setPreservesCFG(); } }; -} +} // namespace char ADCE::ID = 0; INITIALIZE_PASS(ADCE, "adce", "Aggressive Dead Code Elimination", false, false) diff --git a/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp index 8918909..a4e5446 100644 --- a/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ b/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -76,7 +76,7 @@ struct AlignmentFromAssumptions : public FunctionPass { const SCEV *&OffSCEV); bool processAssumption(CallInst *I); }; -} +} // namespace char AlignmentFromAssumptions::ID = 0; static const char aip_name[] = "Alignment from assumptions"; diff --git a/lib/Transforms/Scalar/BDCE.cpp b/lib/Transforms/Scalar/BDCE.cpp index 09c605e..8ffbacd 100644 --- a/lib/Transforms/Scalar/BDCE.cpp +++ b/lib/Transforms/Scalar/BDCE.cpp @@ -66,7 +66,7 @@ struct BDCE : public FunctionPass { AssumptionCache *AC; DominatorTree *DT; }; -} +} // namespace char BDCE::ID = 0; INITIALIZE_PASS_BEGIN(BDCE, "bdce", "Bit-Tracking Dead Code Elimination", diff --git a/lib/Transforms/Scalar/ConstantHoisting.cpp b/lib/Transforms/Scalar/ConstantHoisting.cpp index 4288742..cc1dc94 100644 --- a/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -171,7 +171,7 @@ private: void deleteDeadCastInst() const; bool optimizeConstants(Function &Fn); }; -} +} // namespace char ConstantHoisting::ID = 0; INITIALIZE_PASS_BEGIN(ConstantHoisting, "consthoist", "Constant Hoisting", diff --git a/lib/Transforms/Scalar/ConstantProp.cpp b/lib/Transforms/Scalar/ConstantProp.cpp index c974ebb..e3df86e 100644 --- a/lib/Transforms/Scalar/ConstantProp.cpp +++ b/lib/Transforms/Scalar/ConstantProp.cpp @@ -47,7 +47,7 @@ namespace { AU.addRequired<TargetLibraryInfoWrapperPass>(); } }; -} +} // namespace char ConstantPropagation::ID = 0; INITIALIZE_PASS_BEGIN(ConstantPropagation, "constprop", diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 79624b2..b1809b7 100644 --- a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -56,7 +56,7 @@ namespace { AU.addRequired<LazyValueInfo>(); } }; -} +} // namespace char CorrelatedValuePropagation::ID = 0; INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, "correlated-propagation", diff --git a/lib/Transforms/Scalar/DCE.cpp b/lib/Transforms/Scalar/DCE.cpp index 3b262a2..aa628e5 100644 --- a/lib/Transforms/Scalar/DCE.cpp +++ b/lib/Transforms/Scalar/DCE.cpp @@ -60,7 +60,7 @@ namespace { AU.setPreservesCFG(); } }; -} +} // namespace char DeadInstElimination::ID = 0; INITIALIZE_PASS(DeadInstElimination, "die", @@ -87,7 +87,7 @@ namespace { AU.setPreservesCFG(); } }; -} +} // namespace char DCE::ID = 0; INITIALIZE_PASS(DCE, "dce", "Dead Code Elimination", false, false) diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index eb48a76..c99dc5f 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -78,7 +78,7 @@ namespace { bool runOnBasicBlock(BasicBlock &BB); bool HandleFree(CallInst *F); bool handleEndBlock(BasicBlock &BB); - void RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc, + void RemoveAccessedObjects(const MemoryLocation &LoadedLoc, SmallSetVector<Value *, 16> &DeadStackObjects, const DataLayout &DL); @@ -92,7 +92,7 @@ namespace { AU.addPreserved<MemoryDependenceAnalysis>(); } }; -} +} // namespace char DSE::ID = 0; INITIALIZE_PASS_BEGIN(DSE, "dse", "Dead Store Elimination", false, false) @@ -194,37 +194,37 @@ static bool hasMemoryWrite(Instruction *I, const TargetLibraryInfo *TLI) { /// getLocForWrite - Return a Location stored to by the specified instruction. /// If isRemovable returns true, this function and getLocForRead completely /// describe the memory operations for this instruction. -static AliasAnalysis::Location -getLocForWrite(Instruction *Inst, AliasAnalysis &AA) { +static MemoryLocation getLocForWrite(Instruction *Inst, AliasAnalysis &AA) { if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) return MemoryLocation::get(SI); if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(Inst)) { // memcpy/memmove/memset. - AliasAnalysis::Location Loc = MemoryLocation::getForDest(MI); + MemoryLocation Loc = MemoryLocation::getForDest(MI); return Loc; } IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst); - if (!II) return AliasAnalysis::Location(); + if (!II) + return MemoryLocation(); switch (II->getIntrinsicID()) { - default: return AliasAnalysis::Location(); // Unhandled intrinsic. + default: + return MemoryLocation(); // Unhandled intrinsic. case Intrinsic::init_trampoline: // FIXME: We don't know the size of the trampoline, so we can't really // handle it here. - return AliasAnalysis::Location(II->getArgOperand(0)); + return MemoryLocation(II->getArgOperand(0)); case Intrinsic::lifetime_end: { uint64_t Len = cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(); - return AliasAnalysis::Location(II->getArgOperand(1), Len); + return MemoryLocation(II->getArgOperand(1), Len); } } } /// getLocForRead - Return the location read by the specified "hasMemoryWrite" /// instruction if any. -static AliasAnalysis::Location -getLocForRead(Instruction *Inst, AliasAnalysis &AA) { +static MemoryLocation getLocForRead(Instruction *Inst, AliasAnalysis &AA) { assert(hasMemoryWrite(Inst, AA.getTargetLibraryInfo()) && "Unknown instruction case"); @@ -232,7 +232,7 @@ getLocForRead(Instruction *Inst, AliasAnalysis &AA) { // instructions (memcpy/memmove). if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(Inst)) return MemoryLocation::getForSource(MTI); - return AliasAnalysis::Location(); + return MemoryLocation(); } @@ -317,7 +317,7 @@ static uint64_t getPointerSize(const Value *V, const DataLayout &DL, uint64_t Size; if (getObjectSize(V, Size, DL, TLI)) return Size; - return AliasAnalysis::UnknownSize; + return MemoryLocation::UnknownSize; } namespace { @@ -333,8 +333,8 @@ namespace { /// completely overwrites a store to the 'Earlier' location. /// 'OverwriteEnd' if the end of the 'Earlier' location is completely /// overwritten by 'Later', or 'OverwriteUnknown' if nothing can be determined -static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, - const AliasAnalysis::Location &Earlier, +static OverwriteResult isOverwrite(const MemoryLocation &Later, + const MemoryLocation &Earlier, const DataLayout &DL, const TargetLibraryInfo *TLI, int64_t &EarlierOff, int64_t &LaterOff) { @@ -346,8 +346,8 @@ static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, if (P1 == P2) { // If we don't know the sizes of either access, then we can't do a // comparison. - if (Later.Size == AliasAnalysis::UnknownSize || - Earlier.Size == AliasAnalysis::UnknownSize) + if (Later.Size == MemoryLocation::UnknownSize || + Earlier.Size == MemoryLocation::UnknownSize) return OverwriteUnknown; // Make sure that the Later size is >= the Earlier size. @@ -357,8 +357,8 @@ static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, // Otherwise, we have to have size information, and the later store has to be // larger than the earlier one. - if (Later.Size == AliasAnalysis::UnknownSize || - Earlier.Size == AliasAnalysis::UnknownSize) + if (Later.Size == MemoryLocation::UnknownSize || + Earlier.Size == MemoryLocation::UnknownSize) return OverwriteUnknown; // Check to see if the later store is to the entire object (either a global, @@ -374,7 +374,7 @@ static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, // If the "Later" store is to a recognizable object, get its size. uint64_t ObjectSize = getPointerSize(UO2, DL, TLI); - if (ObjectSize != AliasAnalysis::UnknownSize) + if (ObjectSize != MemoryLocation::UnknownSize) if (ObjectSize == Later.Size && ObjectSize >= Earlier.Size) return OverwriteComplete; @@ -441,11 +441,11 @@ static OverwriteResult isOverwrite(const AliasAnalysis::Location &Later, /// This function detects when it is unsafe to remove a dependent instruction /// because the DSE inducing instruction may be a self-read. static bool isPossibleSelfRead(Instruction *Inst, - const AliasAnalysis::Location &InstStoreLoc, + const MemoryLocation &InstStoreLoc, Instruction *DepWrite, AliasAnalysis &AA) { // Self reads can only happen for instructions that read memory. Get the // location read. - AliasAnalysis::Location InstReadLoc = getLocForRead(Inst, AA); + MemoryLocation InstReadLoc = getLocForRead(Inst, AA); if (!InstReadLoc.Ptr) return false; // Not a reading instruction. // If the read and written loc obviously don't alias, it isn't a read. @@ -459,7 +459,7 @@ static bool isPossibleSelfRead(Instruction *Inst, // Here we don't know if A/B may alias, but we do know that B/B are must // aliases, so removing the first memcpy is safe (assuming it writes <= # // bytes as the second one. - AliasAnalysis::Location DepReadLoc = getLocForRead(DepWrite, AA); + MemoryLocation DepReadLoc = getLocForRead(DepWrite, AA); if (DepReadLoc.Ptr && AA.isMustAlias(InstReadLoc.Ptr, DepReadLoc.Ptr)) return false; @@ -525,7 +525,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { } // Figure out what location is being stored to. - AliasAnalysis::Location Loc = getLocForWrite(Inst, *AA); + MemoryLocation Loc = getLocForWrite(Inst, *AA); // If we didn't get a useful location, fail. if (!Loc.Ptr) @@ -540,7 +540,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { // // Find out what memory location the dependent instruction stores. Instruction *DepWrite = InstDep.getInst(); - AliasAnalysis::Location DepLoc = getLocForWrite(DepWrite, *AA); + MemoryLocation DepLoc = getLocForWrite(DepWrite, *AA); // If we didn't get a useful location, or if it isn't a size, bail out. if (!DepLoc.Ptr) break; @@ -645,7 +645,7 @@ static void FindUnconditionalPreds(SmallVectorImpl<BasicBlock *> &Blocks, bool DSE::HandleFree(CallInst *F) { bool MadeChange = false; - AliasAnalysis::Location Loc = AliasAnalysis::Location(F->getOperand(0)); + MemoryLocation Loc = MemoryLocation(F->getOperand(0)); SmallVector<BasicBlock *, 16> Blocks; Blocks.push_back(F->getParent()); const DataLayout &DL = F->getModule()->getDataLayout(); @@ -809,7 +809,7 @@ bool DSE::handleEndBlock(BasicBlock &BB) { continue; } - AliasAnalysis::Location LoadedLoc; + MemoryLocation LoadedLoc; // If we encounter a use of the pointer, it is no longer considered dead if (LoadInst *L = dyn_cast<LoadInst>(BBI)) { @@ -845,7 +845,7 @@ bool DSE::handleEndBlock(BasicBlock &BB) { /// RemoveAccessedObjects - Check to see if the specified location may alias any /// of the stack objects in the DeadStackObjects set. If so, they become live /// because the location is being loaded. -void DSE::RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc, +void DSE::RemoveAccessedObjects(const MemoryLocation &LoadedLoc, SmallSetVector<Value *, 16> &DeadStackObjects, const DataLayout &DL) { const Value *UnderlyingPointer = GetUnderlyingObject(LoadedLoc.Ptr, DL); @@ -864,8 +864,8 @@ void DSE::RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc, // Remove objects that could alias LoadedLoc. DeadStackObjects.remove_if([&](Value *I) { // See if the loaded location could alias the stack location. - AliasAnalysis::Location StackLoc( - I, getPointerSize(I, DL, AA->getTargetLibraryInfo())); + MemoryLocation StackLoc(I, + getPointerSize(I, DL, AA->getTargetLibraryInfo())); return !AA->isNoAlias(StackLoc, LoadedLoc); }); } diff --git a/lib/Transforms/Scalar/EarlyCSE.cpp b/lib/Transforms/Scalar/EarlyCSE.cpp index d536a93..8b629ea 100644 --- a/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/lib/Transforms/Scalar/EarlyCSE.cpp @@ -72,7 +72,7 @@ struct SimpleValue { isa<ExtractValueInst>(Inst) || isa<InsertValueInst>(Inst); } }; -} +} // namespace namespace llvm { template <> struct DenseMapInfo<SimpleValue> { @@ -85,7 +85,7 @@ template <> struct DenseMapInfo<SimpleValue> { static unsigned getHashValue(SimpleValue Val); static bool isEqual(SimpleValue LHS, SimpleValue RHS); }; -} +} // namespace llvm unsigned DenseMapInfo<SimpleValue>::getHashValue(SimpleValue Val) { Instruction *Inst = Val.Inst; @@ -219,7 +219,7 @@ struct CallValue { return true; } }; -} +} // namespace namespace llvm { template <> struct DenseMapInfo<CallValue> { @@ -232,7 +232,7 @@ template <> struct DenseMapInfo<CallValue> { static unsigned getHashValue(CallValue Val); static bool isEqual(CallValue LHS, CallValue RHS); }; -} +} // namespace llvm unsigned DenseMapInfo<CallValue>::getHashValue(CallValue Val) { Instruction *Inst = Val.Inst; @@ -447,7 +447,7 @@ private: ExpectedType); } }; -} +} // namespace bool EarlyCSE::processNode(DomTreeNode *Node) { BasicBlock *BB = Node->getBlock(); @@ -764,7 +764,7 @@ public: AU.setPreservesCFG(); } }; -} +} // namespace char EarlyCSELegacyPass::ID = 0; diff --git a/lib/Transforms/Scalar/FlattenCFGPass.cpp b/lib/Transforms/Scalar/FlattenCFGPass.cpp index 0430c18..dd6ea8d 100644 --- a/lib/Transforms/Scalar/FlattenCFGPass.cpp +++ b/lib/Transforms/Scalar/FlattenCFGPass.cpp @@ -36,7 +36,7 @@ public: private: AliasAnalysis *AA; }; -} +} // namespace char FlattenCFGPass::ID = 0; INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, diff --git a/lib/Transforms/Scalar/Float2Int.cpp b/lib/Transforms/Scalar/Float2Int.cpp index c931422..bb90c5f 100644 --- a/lib/Transforms/Scalar/Float2Int.cpp +++ b/lib/Transforms/Scalar/Float2Int.cpp @@ -79,7 +79,7 @@ namespace { MapVector<Instruction*, Value*> ConvertedInsts; LLVMContext *Ctx; }; -} +} // namespace char Float2Int::ID = 0; INITIALIZE_PASS(Float2Int, "float2int", "Float to int", false, false) diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 7770ddc..d9308c4 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -138,7 +138,7 @@ namespace { uint32_t getNextUnusedValueNumber() { return nextValueNumber; } void verifyRemoved(const Value *) const; }; -} +} // namespace namespace llvm { template <> struct DenseMapInfo<Expression> { @@ -159,7 +159,7 @@ template <> struct DenseMapInfo<Expression> { } }; -} +} // namespace llvm //===----------------------------------------------------------------------===// // ValueTable Internal Functions @@ -723,7 +723,7 @@ namespace { }; char GVN::ID = 0; -} +} // namespace // The public interface to this file... FunctionPass *llvm::createGVNPass(bool NoLoads) { @@ -852,13 +852,12 @@ static bool CanCoerceMustAliasedValueToLoad(Value *StoredVal, /// If we saw a store of a value to memory, and /// then a load from a must-aliased pointer of a different type, try to coerce -/// the stored value. LoadedTy is the type of the load we want to replace and -/// InsertPt is the place to insert new instructions. +/// the stored value. LoadedTy is the type of the load we want to replace. +/// IRB is IRBuilder used to insert new instructions. /// /// If we can't do it, return null. -static Value *CoerceAvailableValueToLoadType(Value *StoredVal, - Type *LoadedTy, - Instruction *InsertPt, +static Value *CoerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy, + IRBuilder<> &IRB, const DataLayout &DL) { if (!CanCoerceMustAliasedValueToLoad(StoredVal, LoadedTy, DL)) return nullptr; @@ -874,12 +873,12 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, // Pointer to Pointer -> use bitcast. if (StoredValTy->getScalarType()->isPointerTy() && LoadedTy->getScalarType()->isPointerTy()) - return new BitCastInst(StoredVal, LoadedTy, "", InsertPt); + return IRB.CreateBitCast(StoredVal, LoadedTy); // Convert source pointers to integers, which can be bitcast. if (StoredValTy->getScalarType()->isPointerTy()) { StoredValTy = DL.getIntPtrType(StoredValTy); - StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt); + StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); } Type *TypeToCastTo = LoadedTy; @@ -887,11 +886,11 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, TypeToCastTo = DL.getIntPtrType(TypeToCastTo); if (StoredValTy != TypeToCastTo) - StoredVal = new BitCastInst(StoredVal, TypeToCastTo, "", InsertPt); + StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo); // Cast to pointer if the load needs a pointer type. if (LoadedTy->getScalarType()->isPointerTy()) - StoredVal = new IntToPtrInst(StoredVal, LoadedTy, "", InsertPt); + StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy); return StoredVal; } @@ -904,35 +903,34 @@ static Value *CoerceAvailableValueToLoadType(Value *StoredVal, // Convert source pointers to integers, which can be manipulated. if (StoredValTy->getScalarType()->isPointerTy()) { StoredValTy = DL.getIntPtrType(StoredValTy); - StoredVal = new PtrToIntInst(StoredVal, StoredValTy, "", InsertPt); + StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy); } // Convert vectors and fp to integer, which can be manipulated. if (!StoredValTy->isIntegerTy()) { StoredValTy = IntegerType::get(StoredValTy->getContext(), StoreSize); - StoredVal = new BitCastInst(StoredVal, StoredValTy, "", InsertPt); + StoredVal = IRB.CreateBitCast(StoredVal, StoredValTy); } // If this is a big-endian system, we need to shift the value down to the low // bits so that a truncate will work. if (DL.isBigEndian()) { - Constant *Val = ConstantInt::get(StoredVal->getType(), StoreSize-LoadSize); - StoredVal = BinaryOperator::CreateLShr(StoredVal, Val, "tmp", InsertPt); + StoredVal = IRB.CreateLShr(StoredVal, StoreSize - LoadSize, "tmp"); } // Truncate the integer to the right size now. Type *NewIntTy = IntegerType::get(StoredValTy->getContext(), LoadSize); - StoredVal = new TruncInst(StoredVal, NewIntTy, "trunc", InsertPt); + StoredVal = IRB.CreateTrunc(StoredVal, NewIntTy, "trunc"); if (LoadedTy == NewIntTy) return StoredVal; // If the result is a pointer, inttoptr. if (LoadedTy->getScalarType()->isPointerTy()) - return new IntToPtrInst(StoredVal, LoadedTy, "inttoptr", InsertPt); + return IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr"); // Otherwise, bitcast. - return new BitCastInst(StoredVal, LoadedTy, "bitcast", InsertPt); + return IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast"); } /// This function is called when we have a @@ -1122,7 +1120,7 @@ static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset, uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal->getType()) + 7) / 8; uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8; - IRBuilder<> Builder(InsertPt->getParent(), InsertPt); + IRBuilder<> Builder(InsertPt); // Compute which bits of the stored value are being used by the load. Convert // to an integer type to start with. @@ -1145,7 +1143,7 @@ static Value *GetStoreValueForLoad(Value *SrcVal, unsigned Offset, if (LoadSize != StoreSize) SrcVal = Builder.CreateTrunc(SrcVal, IntegerType::get(Ctx, LoadSize*8)); - return CoerceAvailableValueToLoadType(SrcVal, LoadTy, InsertPt, DL); + return CoerceAvailableValueToLoadType(SrcVal, LoadTy, Builder, DL); } /// This function is called when we have a @@ -1219,7 +1217,7 @@ static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, LLVMContext &Ctx = LoadTy->getContext(); uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy)/8; - IRBuilder<> Builder(InsertPt->getParent(), InsertPt); + IRBuilder<> Builder(InsertPt); // We know that this method is only called when the mem transfer fully // provides the bits for the load. @@ -1248,7 +1246,7 @@ static Value *GetMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, ++NumBytesSet; } - return CoerceAvailableValueToLoadType(Val, LoadTy, InsertPt, DL); + return CoerceAvailableValueToLoadType(Val, LoadTy, Builder, DL); } // Otherwise, this is a memcpy/memmove from a constant global. @@ -1695,6 +1693,8 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock, LI->replaceAllUsesWith(V); if (isa<PHINode>(V)) V->takeName(LI); + if (Instruction *I = dyn_cast<Instruction>(V)) + I->setDebugLoc(LI->getDebugLoc()); if (V->getType()->getScalarType()->isPointerTy()) MD->invalidateCachedPointerInfo(V); markInstructionForDeletion(LI); @@ -1761,6 +1761,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI) { if (isa<PHINode>(V)) V->takeName(LI); + if (Instruction *I = dyn_cast<Instruction>(V)) + I->setDebugLoc(LI->getDebugLoc()); if (V->getType()->getScalarType()->isPointerTy()) MD->invalidateCachedPointerInfo(V); markInstructionForDeletion(LI); @@ -1928,8 +1930,9 @@ bool GVN::processLoad(LoadInst *L) { // actually have the same type. See if we know how to reuse the stored // value (depending on its type). if (StoredVal->getType() != L->getType()) { + IRBuilder<> Builder(L); StoredVal = - CoerceAvailableValueToLoadType(StoredVal, L->getType(), L, DL); + CoerceAvailableValueToLoadType(StoredVal, L->getType(), Builder, DL); if (!StoredVal) return false; @@ -1953,7 +1956,9 @@ bool GVN::processLoad(LoadInst *L) { // the same type. See if we know how to reuse the previously loaded value // (depending on its type). if (DepLI->getType() != L->getType()) { - AvailableVal = CoerceAvailableValueToLoadType(DepLI, L->getType(), L, DL); + IRBuilder<> Builder(L); + AvailableVal = + CoerceAvailableValueToLoadType(DepLI, L->getType(), Builder, DL); if (!AvailableVal) return false; diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 359a616..e931382 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -136,7 +136,7 @@ namespace { void SinkUnusedInvariants(Loop *L); }; -} +} // namespace char IndVarSimplify::ID = 0; INITIALIZE_PASS_BEGIN(IndVarSimplify, "indvars", @@ -494,7 +494,7 @@ struct RewritePhi { RewritePhi(PHINode *P, unsigned I, Value *V, bool H, bool S) : PN(P), Ith(I), Val(V), HighCost(H), SafePhi(S) {} }; -} +} // namespace //===----------------------------------------------------------------------===// // RewriteLoopExitValues - Optimize IV users outside the loop. @@ -758,7 +758,7 @@ namespace { WideIVInfo() : NarrowIV(nullptr), WidestNativeType(nullptr), IsSigned(false) {} }; -} +} // namespace /// visitCast - Update information about the induction variable that is /// extended by this sign or zero extend operation. This is used to determine @@ -1321,7 +1321,7 @@ namespace { // Implement the interface used by simplifyUsersOfIV. void visitCast(CastInst *Cast) override { visitIVCast(Cast, WI, SE, TTI); } }; -} +} // namespace /// SimplifyAndExtend - Iteratively perform simplification on a worklist of IV /// users. Each successive simplification may push more users which may @@ -2013,10 +2013,11 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { // Now that we're done iterating through lists, clean up any instructions // which are now dead. - while (!DeadInsts.empty()) - if (Instruction *Inst = - dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val())) + while (!DeadInsts.empty()) { + Value *V = static_cast<Value *>(DeadInsts.pop_back_val()); + if (Instruction *Inst = dyn_cast_or_null<Instruction>(V)) RecursivelyDeleteTriviallyDeadInstructions(Inst, TLI); + } // The Rewriter may not be used from this point on. diff --git a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index cbdacad..ce1a0ca 100644 --- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -222,7 +222,7 @@ public: }; char InductiveRangeCheckElimination::ID = 0; -} +} // namespace INITIALIZE_PASS(InductiveRangeCheckElimination, "irce", "Inductive range check elimination", false, false) @@ -618,7 +618,7 @@ public: bool run(); }; -} +} // namespace void LoopConstrainer::replacePHIBlock(PHINode *PN, BasicBlock *Block, BasicBlock *ReplaceBy) { diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 711df41..7316db6 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -138,7 +138,7 @@ namespace { bool SimplifyPartiallyRedundantLoad(LoadInst *LI); bool TryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB); }; -} +} // namespace char JumpThreading::ID = 0; INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading", @@ -758,67 +758,33 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) { if (CmpInst *CondCmp = dyn_cast<CmpInst>(CondInst)) { - // For a comparison where the LHS is outside this block, it's possible - // that we've branched on it before. Used LVI to see if we can simplify - // the branch based on that. + // If we're branching on a conditional, LVI might be able to determine + // it's value at the branch instruction. We only handle comparisons + // against a constant at this time. + // TODO: This should be extended to handle switches as well. BranchInst *CondBr = dyn_cast<BranchInst>(BB->getTerminator()); Constant *CondConst = dyn_cast<Constant>(CondCmp->getOperand(1)); - pred_iterator PI = pred_begin(BB), PE = pred_end(BB); - if (CondBr && CondConst && CondBr->isConditional() && PI != PE && - (!isa<Instruction>(CondCmp->getOperand(0)) || - cast<Instruction>(CondCmp->getOperand(0))->getParent() != BB)) { - // For predecessor edge, determine if the comparison is true or false - // on that edge. If they're all true or all false, we can simplify the - // branch. - // FIXME: We could handle mixed true/false by duplicating code. - LazyValueInfo::Tristate Baseline = - LVI->getPredicateOnEdge(CondCmp->getPredicate(), CondCmp->getOperand(0), - CondConst, *PI, BB, CondCmp); - if (Baseline != LazyValueInfo::Unknown) { - // Check that all remaining incoming values match the first one. - while (++PI != PE) { - LazyValueInfo::Tristate Ret = - LVI->getPredicateOnEdge(CondCmp->getPredicate(), - CondCmp->getOperand(0), CondConst, *PI, BB, - CondCmp); - if (Ret != Baseline) break; - } - - // If we terminated early, then one of the values didn't match. - if (PI == PE) { - unsigned ToRemove = Baseline == LazyValueInfo::True ? 1 : 0; - unsigned ToKeep = Baseline == LazyValueInfo::True ? 0 : 1; - CondBr->getSuccessor(ToRemove)->removePredecessor(BB, true); - BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr); - CondBr->eraseFromParent(); - if (CondCmp->use_empty()) - CondCmp->eraseFromParent(); - else if (CondCmp->getParent() == BB) { - // If the fact we just learned is true for all uses of the - // condition, replace it with a constant value - auto *CI = Baseline == LazyValueInfo::True ? - ConstantInt::getTrue(CondCmp->getType()) : - ConstantInt::getFalse(CondCmp->getType()); - CondCmp->replaceAllUsesWith(CI); - CondCmp->eraseFromParent(); - } - return true; - } - } - - } else if (CondBr && CondConst && CondBr->isConditional()) { - // There might be an invariant in the same block with the conditional - // that can determine the predicate. - + if (CondBr && CondConst && CondBr->isConditional()) { LazyValueInfo::Tristate Ret = LVI->getPredicateAt(CondCmp->getPredicate(), CondCmp->getOperand(0), - CondConst, CondCmp); + CondConst, CondBr); if (Ret != LazyValueInfo::Unknown) { unsigned ToRemove = Ret == LazyValueInfo::True ? 1 : 0; unsigned ToKeep = Ret == LazyValueInfo::True ? 0 : 1; CondBr->getSuccessor(ToRemove)->removePredecessor(BB, true); BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr); CondBr->eraseFromParent(); + if (CondCmp->use_empty()) + CondCmp->eraseFromParent(); + else if (CondCmp->getParent() == BB) { + // If the fact we just learned is true for all uses of the + // condition, replace it with a constant value + auto *CI = Ret == LazyValueInfo::True ? + ConstantInt::getTrue(CondCmp->getType()) : + ConstantInt::getFalse(CondCmp->getType()); + CondCmp->replaceAllUsesWith(CI); + CondCmp->eraseFromParent(); + } return true; } } diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index f0e6d64..e501946 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -156,7 +156,7 @@ namespace { /// Simple Analysis hook. Delete loop L from alias set map. void deleteAnalysisLoop(Loop *L) override; }; -} +} // namespace char LICM::ID = 0; INITIALIZE_PASS_BEGIN(LICM, "licm", "Loop Invariant Code Motion", false, false) @@ -777,7 +777,7 @@ namespace { AST.deleteValue(I); } }; -} // end anon namespace +} // namespace /// Try to promote memory values to scalars by sinking stores out of the /// loop and moving loads to before the loop. We do this by looping over diff --git a/lib/Transforms/Scalar/LoadCombine.cpp b/lib/Transforms/Scalar/LoadCombine.cpp index c19cd19..3dbf6ac 100644 --- a/lib/Transforms/Scalar/LoadCombine.cpp +++ b/lib/Transforms/Scalar/LoadCombine.cpp @@ -77,7 +77,7 @@ private: bool aggregateLoads(SmallVectorImpl<LoadPOPPair> &); bool combineLoads(SmallVectorImpl<LoadPOPPair> &); }; -} +} // namespace bool LoadCombine::doInitialization(Function &F) { DEBUG(dbgs() << "LoadCombine function: " << F.getName() << "\n"); diff --git a/lib/Transforms/Scalar/LoopDeletion.cpp b/lib/Transforms/Scalar/LoopDeletion.cpp index 98b068e..02760ff 100644 --- a/lib/Transforms/Scalar/LoopDeletion.cpp +++ b/lib/Transforms/Scalar/LoopDeletion.cpp @@ -57,7 +57,7 @@ namespace { bool &Changed, BasicBlock *Preheader); }; -} +} // namespace char LoopDeletion::ID = 0; INITIALIZE_PASS_BEGIN(LoopDeletion, "loop-deletion", diff --git a/lib/Transforms/Scalar/LoopDistribute.cpp b/lib/Transforms/Scalar/LoopDistribute.cpp index a907d59..d21a7db 100644 --- a/lib/Transforms/Scalar/LoopDistribute.cpp +++ b/lib/Transforms/Scalar/LoopDistribute.cpp @@ -630,26 +630,17 @@ private: }; /// \brief Handles the loop versioning based on memchecks. -class RuntimeCheckEmitter { +class LoopVersioning { public: - RuntimeCheckEmitter(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI, - DominatorTree *DT) - : OrigLoop(L), NonDistributedLoop(nullptr), LAI(LAI), LI(LI), DT(DT) {} - - /// \brief Given the \p Partitions formed by Loop Distribution, it determines - /// in which partition each pointer is used. - void partitionPointers(InstPartitionContainer &Partitions) { - // Set up partition id in PtrRtChecks. Ptr -> Access -> Intruction -> - // Partition. - PtrToPartition = Partitions.computePartitionSetForPointers(LAI); - - DEBUG(dbgs() << "\nPointers:\n"); - DEBUG(LAI.getRuntimePointerCheck()->print(dbgs(), 0, &PtrToPartition)); - } + LoopVersioning(const LoopAccessInfo &LAI, Loop *L, LoopInfo *LI, + DominatorTree *DT, + const SmallVector<int, 8> *PtrToPartition = nullptr) + : OrigLoop(L), NonDistributedLoop(nullptr), + PtrToPartition(PtrToPartition), LAI(LAI), LI(LI), DT(DT) {} /// \brief Returns true if we need memchecks to distribute the loop. bool needsRuntimeChecks() const { - return LAI.getRuntimePointerCheck()->needsAnyChecking(&PtrToPartition); + return LAI.getRuntimePointerCheck()->needsAnyChecking(PtrToPartition); } /// \brief Performs the CFG manipulation part of versioning the loop including @@ -660,7 +651,7 @@ public: // Add the memcheck in the original preheader (this is empty initially). BasicBlock *MemCheckBB = OrigLoop->getLoopPreheader(); std::tie(FirstCheckInst, MemRuntimeCheck) = - LAI.addRuntimeCheck(MemCheckBB->getTerminator(), &PtrToPartition); + LAI.addRuntimeCheck(MemCheckBB->getTerminator(), PtrToPartition); assert(MemRuntimeCheck && "called even though needsAnyChecking = false"); // Rename the block to make the IR more readable. @@ -733,10 +724,11 @@ private: Loop *NonDistributedLoop; /// \brief For each memory pointer it contains the partitionId it is used in. + /// If nullptr, no partitioning is used. /// /// The I-th entry corresponds to I-th entry in LAI.getRuntimePointerCheck(). /// If the pointer is used in multiple partitions the entry is set to -1. - SmallVector<int, 8> PtrToPartition; + const SmallVector<int, 8> *PtrToPartition; /// \brief This maps the instructions from OrigLoop to their counterpart in /// NonDistributedLoop. @@ -929,11 +921,13 @@ private: // If we need run-time checks to disambiguate pointers are run-time, version // the loop now. - RuntimeCheckEmitter RtCheckEmitter(LAI, L, LI, DT); - RtCheckEmitter.partitionPointers(Partitions); - if (RtCheckEmitter.needsRuntimeChecks()) { - RtCheckEmitter.versionLoop(this); - RtCheckEmitter.addPHINodes(DefsUsedOutside); + auto PtrToPartition = Partitions.computePartitionSetForPointers(LAI); + LoopVersioning LVer(LAI, L, LI, DT, &PtrToPartition); + if (LVer.needsRuntimeChecks()) { + DEBUG(dbgs() << "\nPointers:\n"); + DEBUG(LAI.getRuntimePointerCheck()->print(dbgs(), 0, &PtrToPartition)); + LVer.versionLoop(this); + LVer.addPHINodes(DefsUsedOutside); } // Create identical copies of the original loop for each partition and hook diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index f92ecd4..3de1333 100644 --- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -209,7 +209,7 @@ namespace { bool runOnNoncountableLoop(); bool runOnCountableLoop(); }; -} +} // namespace char LoopIdiomRecognize::ID = 0; INITIALIZE_PASS_BEGIN(LoopIdiomRecognize, "loop-idiom", "Recognize loop idioms", @@ -833,7 +833,7 @@ static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access, // Get the location that may be stored across the loop. Since the access is // strided positively through memory, we say that the modified location starts // at the pointer and has infinite size. - uint64_t AccessSize = AliasAnalysis::UnknownSize; + uint64_t AccessSize = MemoryLocation::UnknownSize; // If the loop iterates a fixed number of times, we can refine the access size // to be exactly the size of the memset, which is (BECount+1)*StoreSize @@ -844,7 +844,7 @@ static bool mayLoopAccessLocation(Value *Ptr,AliasAnalysis::ModRefResult Access, // operand in the store. Store to &A[i] of 100 will always return may alias // with store of &A[100], we need to StoreLoc to be "A" with size of 100, // which will then no-alias a store to &A[100]. - AliasAnalysis::Location StoreLoc(Ptr, AccessSize); + MemoryLocation StoreLoc(Ptr, AccessSize); for (Loop::block_iterator BI = L->block_begin(), E = L->block_end(); BI != E; ++BI) diff --git a/lib/Transforms/Scalar/LoopInstSimplify.cpp b/lib/Transforms/Scalar/LoopInstSimplify.cpp index e125026..4c40f24 100644 --- a/lib/Transforms/Scalar/LoopInstSimplify.cpp +++ b/lib/Transforms/Scalar/LoopInstSimplify.cpp @@ -52,7 +52,7 @@ namespace { AU.addRequired<TargetLibraryInfoWrapperPass>(); } }; -} +} // namespace char LoopInstSimplify::ID = 0; INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify", diff --git a/lib/Transforms/Scalar/LoopInterchange.cpp b/lib/Transforms/Scalar/LoopInterchange.cpp index f584018..2554655 100644 --- a/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/lib/Transforms/Scalar/LoopInterchange.cpp @@ -598,8 +598,8 @@ struct LoopInterchange : public FunctionPass { bool LoopInterchangeLegality::areAllUsesReductions(Instruction *Ins, Loop *L) { return !std::any_of(Ins->user_begin(), Ins->user_end(), [=](User *U) -> bool { PHINode *UserIns = dyn_cast<PHINode>(U); - ReductionDescriptor RD; - return !UserIns || !ReductionDescriptor::isReductionPHI(UserIns, L, RD); + RecurrenceDescriptor RD; + return !UserIns || !RecurrenceDescriptor::isReductionPHI(UserIns, L, RD); }); } @@ -697,12 +697,12 @@ bool LoopInterchangeLegality::findInductionAndReductions( if (!L->getLoopLatch() || !L->getLoopPredecessor()) return false; for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) { - ReductionDescriptor RD; + RecurrenceDescriptor RD; PHINode *PHI = cast<PHINode>(I); ConstantInt *StepValue = nullptr; if (isInductionPHI(PHI, SE, StepValue)) Inductions.push_back(PHI); - else if (ReductionDescriptor::isReductionPHI(PHI, L, RD)) + else if (RecurrenceDescriptor::isReductionPHI(PHI, L, RD)) Reductions.push_back(PHI); else { DEBUG( diff --git a/lib/Transforms/Scalar/LoopRerollPass.cpp b/lib/Transforms/Scalar/LoopRerollPass.cpp index ed103e6..f6db9b1 100644 --- a/lib/Transforms/Scalar/LoopRerollPass.cpp +++ b/lib/Transforms/Scalar/LoopRerollPass.cpp @@ -438,7 +438,7 @@ namespace { bool reroll(Instruction *IV, Loop *L, BasicBlock *Header, const SCEV *IterCount, ReductionTracker &Reductions); }; -} +} // namespace char LoopReroll::ID = 0; INITIALIZE_PASS_BEGIN(LoopReroll, "loop-reroll", "Reroll loops", false, false) diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index a675e12..2ba70ad 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -79,7 +79,7 @@ namespace { AssumptionCache *AC; DominatorTree *DT; }; -} +} // namespace char LoopRotate::ID = 0; INITIALIZE_PASS_BEGIN(LoopRotate, "loop-rotate", "Rotate Loops", false, false) diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 4b59f3d..ee72486 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -116,7 +116,7 @@ public: void dump() const; }; -} +} // namespace void RegSortData::print(raw_ostream &OS) const { OS << "[NumUses=" << UsedByIndices.count() << ']'; @@ -157,7 +157,7 @@ public: const_iterator end() const { return RegSequence.end(); } }; -} +} // namespace void RegUseTracker::CountRegister(const SCEV *Reg, size_t LUIdx) { @@ -281,7 +281,7 @@ struct Formula { void dump() const; }; -} +} // namespace /// DoInitialMatch - Recursion helper for InitialMatch. static void DoInitialMatch(const SCEV *S, Loop *L, @@ -903,7 +903,7 @@ private: SmallPtrSetImpl<const SCEV *> *LoserRegs); }; -} +} // namespace /// RateRegister - Tally up interesting quantities from the given register. void Cost::RateRegister(const SCEV *Reg, @@ -1102,7 +1102,7 @@ struct LSRFixup { void dump() const; }; -} +} // namespace LSRFixup::LSRFixup() : UserInst(nullptr), OperandValToReplace(nullptr), LUIdx(~size_t(0)), @@ -1252,7 +1252,7 @@ public: void dump() const; }; -} +} // namespace /// HasFormula - Test whether this use as a formula which has the same /// registers as the given formula. @@ -1791,7 +1791,7 @@ public: void dump() const; }; -} +} // namespace /// OptimizeShadowIV - If IV is used in a int-to-float cast /// inside the loop then try to eliminate the cast operation. @@ -3644,7 +3644,7 @@ struct WorkItem { void dump() const; }; -} +} // namespace void WorkItem::print(raw_ostream &OS) const { OS << "in formulae referencing " << *OrigReg << " in use " << LUIdx @@ -4949,7 +4949,7 @@ private: void getAnalysisUsage(AnalysisUsage &AU) const override; }; -} +} // namespace char LoopStrengthReduce::ID = 0; INITIALIZE_PASS_BEGIN(LoopStrengthReduce, "loop-reduce", diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index 4ccbfc9..d702dc0 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -229,7 +229,7 @@ namespace { unsigned DynamicCostSavingsDiscount, uint64_t UnrolledCost, uint64_t RolledDynamicCost); }; -} +} // namespace char LoopUnroll::ID = 0; INITIALIZE_PASS_BEGIN(LoopUnroll, "loop-unroll", "Unroll loops", false, false) @@ -455,13 +455,15 @@ struct EstimatedUnrollCost { /// /// Complete loop unrolling can make some loads constant, and we need to know /// if that would expose any further optimization opportunities. This routine -/// estimates this optimization. It assigns computed number of instructions, -/// that potentially might be optimized away, to -/// NumberOfOptimizedInstructions, and total number of instructions to -/// UnrolledLoopSize (not counting blocks that won't be reached, if we were -/// able to compute the condition). -/// \returns false if we can't analyze the loop, or if we discovered that -/// unrolling won't give anything. Otherwise, returns true. +/// estimates this optimization. It computes cost of unrolled loop +/// (UnrolledCost) and dynamic cost of the original loop (RolledDynamicCost). By +/// dynamic cost we mean that we won't count costs of blocks that are known not +/// to be executed (i.e. if we have a branch in the loop and we know that at the +/// given iteration its condition would be resolved to true, we won't add up the +/// cost of the 'false'-block). +/// \returns Optional value, holding the RolledDynamicCost and UnrolledCost. If +/// the analysis failed (no benefits expected from the unrolling, or the loop is +/// too big to analyze), the returned value is None. Optional<EstimatedUnrollCost> analyzeLoopUnrollCost(const Loop *L, unsigned TripCount, ScalarEvolution &SE, const TargetTransformInfo &TTI, diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 988d2af..5bdc2ec 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -213,7 +213,7 @@ namespace { BasicBlock **LoopExit = nullptr); }; -} +} // namespace // Analyze loop. Check its size, calculate is it possible to unswitch // it. Returns true if we can unswitch this loop. diff --git a/lib/Transforms/Scalar/LowerAtomic.cpp b/lib/Transforms/Scalar/LowerAtomic.cpp index 3314e1e..b8b35d4 100644 --- a/lib/Transforms/Scalar/LowerAtomic.cpp +++ b/lib/Transforms/Scalar/LowerAtomic.cpp @@ -138,7 +138,7 @@ namespace { return Changed; } }; -} +} // namespace char LowerAtomic::ID = 0; INITIALIZE_PASS(LowerAtomic, "loweratomic", diff --git a/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp index 0c47cbd..b845c03 100644 --- a/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -181,7 +181,7 @@ public: bool runOnFunction(Function &F) override { return lowerExpectIntrinsic(F); } }; -} +} // namespace char LowerExpectIntrinsic::ID = 0; INITIALIZE_PASS(LowerExpectIntrinsic, "lower-expect", diff --git a/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 2bdf670..2c9f935 100644 --- a/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -153,7 +153,7 @@ struct MemsetRange { bool isProfitableToUseMemset(const DataLayout &DL) const; }; -} // end anon namespace +} // namespace bool MemsetRange::isProfitableToUseMemset(const DataLayout &DL) const { // If we found more than 4 stores to merge or 16 bytes, use memset. @@ -237,7 +237,7 @@ public: }; -} // end anon namespace +} // namespace /// addRange - Add a new store to the MemsetRanges data structure. This adds a @@ -337,7 +337,7 @@ namespace { AU.addPreserved<MemoryDependenceAnalysis>(); } - // Helper fuctions + // Helper functions bool processStore(StoreInst *SI, BasicBlock::iterator &BBI); bool processMemSet(MemSetInst *SI, BasicBlock::iterator &BBI); bool processMemCpy(MemCpyInst *M); @@ -355,7 +355,7 @@ namespace { }; char MemCpyOpt::ID = 0; -} +} // namespace // createMemCpyOptPass - The public interface to this file... FunctionPass *llvm::createMemCpyOptPass() { return new MemCpyOpt(); } @@ -510,7 +510,7 @@ bool MemCpyOpt::processStore(StoreInst *SI, BasicBlock::iterator &BBI) { // Check that nothing touches the dest of the "copy" between // the call and the store. AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); - AliasAnalysis::Location StoreLoc = MemoryLocation::get(SI); + MemoryLocation StoreLoc = MemoryLocation::get(SI); for (BasicBlock::iterator I = --BasicBlock::iterator(SI), E = C; I != E; --I) { if (AA.getModRefInfo(&*I, StoreLoc) != AliasAnalysis::NoModRef) { @@ -997,7 +997,7 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) { } } - AliasAnalysis::Location SrcLoc = MemoryLocation::getForSource(M); + MemoryLocation SrcLoc = MemoryLocation::getForSource(M); MemDepResult SrcDepInfo = MD->getPointerDependencyFrom(SrcLoc, true, M, M->getParent()); @@ -1075,10 +1075,9 @@ bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) { Value *ByValArg = CS.getArgument(ArgNo); Type *ByValTy = cast<PointerType>(ByValArg->getType())->getElementType(); uint64_t ByValSize = DL.getTypeAllocSize(ByValTy); - MemDepResult DepInfo = - MD->getPointerDependencyFrom(AliasAnalysis::Location(ByValArg, ByValSize), - true, CS.getInstruction(), - CS.getInstruction()->getParent()); + MemDepResult DepInfo = MD->getPointerDependencyFrom( + MemoryLocation(ByValArg, ByValSize), true, CS.getInstruction(), + CS.getInstruction()->getParent()); if (!DepInfo.isClobber()) return false; diff --git a/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp b/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp index 776dfb4..886b6f5 100644 --- a/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp +++ b/lib/Transforms/Scalar/MergedLoadStoreMotion.cpp @@ -144,9 +144,8 @@ private: // Routines for sinking stores StoreInst *canSinkFromBlock(BasicBlock *BB, StoreInst *SI); PHINode *getPHIOperand(BasicBlock *BB, StoreInst *S0, StoreInst *S1); - bool isStoreSinkBarrierInRange(const Instruction& Start, - const Instruction& End, - AliasAnalysis::Location Loc); + bool isStoreSinkBarrierInRange(const Instruction &Start, + const Instruction &End, MemoryLocation Loc); bool sinkStore(BasicBlock *BB, StoreInst *SinkCand, StoreInst *ElseInst); bool mergeStores(BasicBlock *BB); // The mergeLoad/Store algorithms could have Size0 * Size1 complexity, @@ -157,7 +156,7 @@ private: }; char MergedLoadStoreMotion::ID = 0; -} +} // namespace /// /// \brief createMergedLoadStoreMotionPass - The public interface to this file. @@ -241,7 +240,7 @@ bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) { bool MergedLoadStoreMotion::isLoadHoistBarrierInRange(const Instruction& Start, const Instruction& End, LoadInst* LI) { - AliasAnalysis::Location Loc = MemoryLocation::get(LI); + MemoryLocation Loc = MemoryLocation::get(LI); return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::Mod); } @@ -266,8 +265,8 @@ LoadInst *MergedLoadStoreMotion::canHoistFromBlock(BasicBlock *BB1, LoadInst *Load1 = dyn_cast<LoadInst>(Inst); BasicBlock *BB0 = Load0->getParent(); - AliasAnalysis::Location Loc0 = MemoryLocation::get(Load0); - AliasAnalysis::Location Loc1 = MemoryLocation::get(Load1); + MemoryLocation Loc0 = MemoryLocation::get(Load0); + MemoryLocation Loc1 = MemoryLocation::get(Load1); if (AA->isMustAlias(Loc0, Loc1) && Load0->isSameOperationAs(Load1) && !isLoadHoistBarrierInRange(BB1->front(), *Load1, Load1) && !isLoadHoistBarrierInRange(BB0->front(), *Load0, Load0)) { @@ -400,10 +399,9 @@ bool MergedLoadStoreMotion::mergeLoads(BasicBlock *BB) { /// happening it is considered a sink barrier. /// -bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction& Start, - const Instruction& End, - AliasAnalysis::Location - Loc) { +bool MergedLoadStoreMotion::isStoreSinkBarrierInRange(const Instruction &Start, + const Instruction &End, + MemoryLocation Loc) { return AA->canInstructionRangeModRef(Start, End, Loc, AliasAnalysis::ModRef); } @@ -425,8 +423,8 @@ StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1, StoreInst *Store1 = cast<StoreInst>(Inst); - AliasAnalysis::Location Loc0 = MemoryLocation::get(Store0); - AliasAnalysis::Location Loc1 = MemoryLocation::get(Store1); + MemoryLocation Loc0 = MemoryLocation::get(Store0); + MemoryLocation Loc1 = MemoryLocation::get(Store1); if (AA->isMustAlias(Loc0, Loc1) && Store0->isSameOperationAs(Store1) && !isStoreSinkBarrierInRange(*(std::next(BasicBlock::iterator(Store1))), BB1->back(), Loc1) && diff --git a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp index 31d7df3..5423499 100644 --- a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp +++ b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp @@ -46,7 +46,7 @@ namespace { }; char PartiallyInlineLibCalls::ID = 0; -} +} // namespace INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls", "Partially inline calls to library functions", false, false) diff --git a/lib/Transforms/Scalar/PlaceSafepoints.cpp b/lib/Transforms/Scalar/PlaceSafepoints.cpp index 9ecaf10..670dcd2 100644 --- a/lib/Transforms/Scalar/PlaceSafepoints.cpp +++ b/lib/Transforms/Scalar/PlaceSafepoints.cpp @@ -160,7 +160,7 @@ struct PlaceBackedgeSafepointsImpl : public FunctionPass { AU.setPreservesAll(); } }; -} +} // namespace static cl::opt<bool> NoEntry("spp-no-entry", cl::Hidden, cl::init(false)); static cl::opt<bool> NoCall("spp-no-call", cl::Hidden, cl::init(false)); @@ -181,7 +181,7 @@ struct PlaceSafepoints : public FunctionPass { // if that was worth doing } }; -} +} // namespace // Insert a safepoint poll immediately before the given instruction. Does // not handle the parsability of state at the runtime call, that's the diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 6c66b58..9842fd7 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -154,7 +154,7 @@ namespace { unsigned SymbolicRank; bool isOr; }; -} +} // namespace namespace { class Reassociate : public FunctionPass { @@ -197,7 +197,7 @@ namespace { void OptimizeInst(Instruction *I); Instruction *canonicalizeNegConstExpr(Instruction *I); }; -} +} // namespace XorOpnd::XorOpnd(Value *V) { assert(!isa<ConstantInt>(V) && "No ConstantInt"); diff --git a/lib/Transforms/Scalar/Reg2Mem.cpp b/lib/Transforms/Scalar/Reg2Mem.cpp index 1b46727..2ff56e6 100644 --- a/lib/Transforms/Scalar/Reg2Mem.cpp +++ b/lib/Transforms/Scalar/Reg2Mem.cpp @@ -58,7 +58,7 @@ namespace { bool runOnFunction(Function &F) override; }; -} +} // namespace char RegToMem::ID = 0; INITIALIZE_PASS_BEGIN(RegToMem, "reg2mem", "Demote all values to stack slots", diff --git a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index 6f6ba72..c15bc1b 100644 --- a/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -183,7 +183,7 @@ struct PartiallyConstructedSafepointRecord { /// Maps rematerialized copy to it's original value. RematerializedValueMapTy RematerializedValues; }; -} +} // namespace /// Compute the live-in set for every basic block in the function static void computeLiveInValues(DominatorTree &DT, Function &F, @@ -646,7 +646,7 @@ private: llvm_unreachable("only three states!"); } }; -} +} // namespace /// For a given value or instruction, figure out what base ptr it's derived /// from. For gc objects, this is simply itself. On success, returns a value /// which is the base pointer. (This is reliable and can be used for @@ -1659,17 +1659,10 @@ static void relocationViaAlloca( /// vector. Doing so has the effect of changing the output of a couple of /// tests in ways which make them less useful in testing fused safepoints. template <typename T> static void unique_unsorted(SmallVectorImpl<T> &Vec) { - DenseSet<T> Seen; - SmallVector<T, 128> TempVec; - TempVec.reserve(Vec.size()); - for (auto Element : Vec) - TempVec.push_back(Element); - Vec.clear(); - for (auto V : TempVec) { - if (Seen.insert(V).second) { - Vec.push_back(V); - } - } + SmallSet<T, 8> Seen; + Vec.erase(std::remove_if(Vec.begin(), Vec.end(), [&](const T &V) { + return !Seen.insert(V).second; + }), Vec.end()); } /// Insert holders so that each Value is obviously live through the entire diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index 056dd11..f38b2b1 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -127,7 +127,7 @@ typedef llvm::IRBuilder<true, ConstantFolder, IRBuilderPrefixedInserter<true>> typedef llvm::IRBuilder<false, ConstantFolder, IRBuilderPrefixedInserter<false>> IRBuilderTy; #endif -} +} // namespace namespace { /// \brief A used slice of an alloca. @@ -595,7 +595,7 @@ private: /// the alloca. SmallVector<Use *, 8> DeadOperands; }; -} +} // namespace static Value *foldSelectInst(SelectInst &SI) { // If the condition being selected on is a constant or the same value is @@ -1173,7 +1173,7 @@ public: } } }; -} // end anon namespace +} // namespace namespace { /// \brief An optimization pass providing Scalar Replacement of Aggregates. @@ -1268,7 +1268,7 @@ private: void deleteDeadInstructions(SmallPtrSetImpl<AllocaInst *> &DeletedAllocas); bool promoteAllocas(Function &F); }; -} +} // namespace char SROA::ID = 0; @@ -3119,7 +3119,7 @@ private: return true; } }; -} +} // namespace namespace { /// \brief Visitor to rewrite aggregate loads and stores as scalar. @@ -3327,7 +3327,7 @@ private: return false; } }; -} +} // namespace /// \brief Strip aggregate type wrapping. /// diff --git a/lib/Transforms/Scalar/SampleProfile.cpp b/lib/Transforms/Scalar/SampleProfile.cpp index 3480cd4..69e3a67 100644 --- a/lib/Transforms/Scalar/SampleProfile.cpp +++ b/lib/Transforms/Scalar/SampleProfile.cpp @@ -174,7 +174,7 @@ protected: /// \brief Flag indicating whether the profile input loaded successfully. bool ProfileIsValid; }; -} +} // namespace /// \brief Print the weight of edge \p E on stream \p OS. /// @@ -282,7 +282,7 @@ bool SampleProfileLoader::computeBlockWeights(Function &F) { /// \brief Find equivalence classes for the given block. /// /// This finds all the blocks that are guaranteed to execute the same -/// number of times as \p BB1. To do this, it traverses all the the +/// number of times as \p BB1. To do this, it traverses all the /// descendants of \p BB1 in the dominator or post-dominator tree. /// /// A block BB2 will be in the same equivalence class as \p BB1 if diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index d955da7..e42c3da 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -221,7 +221,7 @@ namespace { } }; -} +} // namespace char SROA_DT::ID = 0; char SROA_SSAUp::ID = 0; @@ -1123,7 +1123,7 @@ public: } } }; -} // end anon namespace +} // namespace /// isSafeSelectToSpeculate - Select instructions that use an alloca and are /// subsequently loaded can be rewritten to load both input pointers and then diff --git a/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/lib/Transforms/Scalar/SimplifyCFGPass.cpp index f0e3ffd..0733daf 100644 --- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -220,7 +220,7 @@ struct CFGSimplifyPass : public FunctionPass { AU.addRequired<TargetTransformInfoWrapperPass>(); } }; -} +} // namespace char CFGSimplifyPass::ID = 0; INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false, diff --git a/lib/Transforms/Scalar/Sink.cpp b/lib/Transforms/Scalar/Sink.cpp index 078c6a9..f49f4ea 100644 --- a/lib/Transforms/Scalar/Sink.cpp +++ b/lib/Transforms/Scalar/Sink.cpp @@ -163,7 +163,7 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis *AA, } if (LoadInst *L = dyn_cast<LoadInst>(Inst)) { - AliasAnalysis::Location Loc = MemoryLocation::get(L); + MemoryLocation Loc = MemoryLocation::get(L); for (Instruction *S : Stores) if (AA->getModRefInfo(S, Loc) & AliasAnalysis::Mod) return false; diff --git a/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp b/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp index 453503a..f32769c 100644 --- a/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp +++ b/lib/Transforms/Scalar/StraightLineStrengthReduce.cpp @@ -265,8 +265,10 @@ static bool isGEPFoldable(GetElementPtrInst *GEP, BaseOffset += DL->getStructLayout(STy)->getElementOffset(Field); } } + + unsigned AddrSpace = GEP->getPointerAddressSpace(); return TTI->isLegalAddressingMode(GEP->getType()->getElementType(), BaseGV, - BaseOffset, HasBaseReg, Scale); + BaseOffset, HasBaseReg, Scale, AddrSpace); } // Returns whether (Base + Index * Stride) can be folded to an addressing mode. @@ -630,6 +632,15 @@ void StraightLineStrengthReduce::rewriteCandidateWithBasis( // trivially dead. RecursivelyDeleteTriviallyDeadInstructions(Bump); } else { + // It's tempting to preserve nsw on Bump and/or Reduced. However, it's + // usually unsound, e.g., + // + // X = (-2 +nsw 1) *nsw INT_MAX + // Y = (-2 +nsw 3) *nsw INT_MAX + // => + // Y = X + 2 * INT_MAX + // + // Neither + and * in the resultant expression are nsw. Reduced = Builder.CreateAdd(Basis.Ins, Bump); } break; diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index 9eef132..d23f515 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -120,7 +120,7 @@ namespace { bool CanMoveAboveCall(Instruction *I, CallInst *CI); Value *CanTransformAccumulatorRecursion(Instruction *I, CallInst *CI); }; -} +} // namespace char TailCallElim::ID = 0; INITIALIZE_PASS_BEGIN(TailCallElim, "tailcallelim", @@ -158,6 +158,9 @@ bool TailCallElim::runOnFunction(Function &F) { if (skipOptnoneFunction(F)) return false; + if (F.getFnAttribute("disable-tail-calls").getValueAsString() == "true") + return false; + bool AllCallsAreTailCalls = false; bool Modified = markTails(F, AllCallsAreTailCalls); if (AllCallsAreTailCalls) @@ -243,7 +246,7 @@ struct AllocaDerivedValueTracker { SmallPtrSet<Instruction *, 32> AllocaUsers; SmallPtrSet<Instruction *, 32> EscapePoints; }; -} +} // namespace bool TailCallElim::markTails(Function &F, bool &AllCallsAreTailCalls) { if (F.callsFunctionThatReturnsTwice()) diff --git a/lib/Transforms/Utils/ASanStackFrameLayout.cpp b/lib/Transforms/Utils/ASanStackFrameLayout.cpp index 03c3a80..72cdfa4 100644 --- a/lib/Transforms/Utils/ASanStackFrameLayout.cpp +++ b/lib/Transforms/Utils/ASanStackFrameLayout.cpp @@ -107,4 +107,4 @@ ComputeASanStackFrameLayout(SmallVectorImpl<ASanStackVariableDescription> &Vars, assert(Layout->FrameSize / Granularity == Layout->ShadowBytes.size()); } -} // llvm namespace +} // namespace llvm diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index f3c8013..798376e 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -486,11 +486,12 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB, } // Create new basic block, insert right before the original block. - BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), BB->getName()+Suffix, - BB->getParent(), BB); + BasicBlock *NewBB = BasicBlock::Create( + BB->getContext(), BB->getName() + Suffix, BB->getParent(), BB); // The new block unconditionally branches to the old block. BranchInst *BI = BranchInst::Create(BB, NewBB); + BI->setDebugLoc(BB->getFirstNonPHI()->getDebugLoc()); // Move the edges from Preds to point to NewBB instead of BB. for (unsigned i = 0, e = Preds.size(); i != e; ++i) { @@ -553,6 +554,7 @@ void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB, // The new block unconditionally branches to the old block. BranchInst *BI1 = BranchInst::Create(OrigBB, NewBB1); + BI1->setDebugLoc(OrigBB->getFirstNonPHI()->getDebugLoc()); // Move the edges from Preds to point to NewBB1 instead of OrigBB. for (unsigned i = 0, e = Preds.size(); i != e; ++i) { @@ -593,6 +595,7 @@ void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB, // The new block unconditionally branches to the old block. BranchInst *BI2 = BranchInst::Create(OrigBB, NewBB2); + BI2->setDebugLoc(OrigBB->getFirstNonPHI()->getDebugLoc()); // Move the remaining edges from OrigBB to point to NewBB2. for (SmallVectorImpl<BasicBlock*>::iterator diff --git a/lib/Transforms/Utils/BreakCriticalEdges.cpp b/lib/Transforms/Utils/BreakCriticalEdges.cpp index 7e83c9e..362cd9b 100644 --- a/lib/Transforms/Utils/BreakCriticalEdges.cpp +++ b/lib/Transforms/Utils/BreakCriticalEdges.cpp @@ -60,7 +60,7 @@ namespace { AU.addPreservedID(LoopSimplifyID); } }; -} +} // namespace char BreakCriticalEdges::ID = 0; INITIALIZE_PASS(BreakCriticalEdges, "break-crit-edges", diff --git a/lib/Transforms/Utils/BypassSlowDivision.cpp b/lib/Transforms/Utils/BypassSlowDivision.cpp index f2d5e07..0771b29 100644 --- a/lib/Transforms/Utils/BypassSlowDivision.cpp +++ b/lib/Transforms/Utils/BypassSlowDivision.cpp @@ -42,7 +42,7 @@ namespace { DivPhiNodes(PHINode *InQuotient, PHINode *InRemainder) : Quotient(InQuotient), Remainder(InRemainder) {} }; -} +} // namespace namespace llvm { template<> @@ -69,7 +69,7 @@ namespace llvm { }; typedef DenseMap<DivOpInfo, DivPhiNodes> DivCacheTy; -} +} // namespace llvm // insertFastDiv - Substitutes the div/rem instruction with code that checks the // value of the operands and uses a shorter-faster div/rem instruction when diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index 4f8d1df..e623445 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -289,7 +289,7 @@ namespace { BasicBlock::const_iterator StartingInst, std::vector<const BasicBlock*> &ToClone); }; -} +} // namespace /// The specified block is found to be reachable, clone it and /// anything that it can reach. diff --git a/lib/Transforms/Utils/CtorUtils.cpp b/lib/Transforms/Utils/CtorUtils.cpp index dc95089..4bbded8 100644 --- a/lib/Transforms/Utils/CtorUtils.cpp +++ b/lib/Transforms/Utils/CtorUtils.cpp @@ -162,4 +162,4 @@ bool optimizeGlobalCtorsList(Module &M, return true; } -} // End llvm namespace +} // namespace llvm diff --git a/lib/Transforms/Utils/FlattenCFG.cpp b/lib/Transforms/Utils/FlattenCFG.cpp index 4eb3e3d..40a48c0 100644 --- a/lib/Transforms/Utils/FlattenCFG.cpp +++ b/lib/Transforms/Utils/FlattenCFG.cpp @@ -46,7 +46,7 @@ public: FlattenCFGOpt(AliasAnalysis *AA) : AA(AA) {} bool run(BasicBlock *BB); }; -} +} // namespace /// If \param [in] BB has more than one predecessor that is a conditional /// branch, attempt to use parallel and/or for the branch condition. \returns diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index ddeaff0..ea84e7c 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -121,7 +121,7 @@ namespace { } } }; -} +} // namespace /// Get or create a target for the branch from ResumeInsts. BasicBlock *InvokeInliningInfo::getInnerResumeDest() { @@ -949,35 +949,23 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, } // Get the personality function from the callee if it contains a landing pad. - Value *CalleePersonality = nullptr; - for (Function::const_iterator I = CalledFunc->begin(), E = CalledFunc->end(); - I != E; ++I) - if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { - const BasicBlock *BB = II->getUnwindDest(); - const LandingPadInst *LP = BB->getLandingPadInst(); - CalleePersonality = LP->getPersonalityFn(); - break; - } + Constant *CalledPersonality = + CalledFunc->hasPersonalityFn() ? CalledFunc->getPersonalityFn() : nullptr; // Find the personality function used by the landing pads of the caller. If it // exists, then check to see that it matches the personality function used in // the callee. - if (CalleePersonality) { - for (Function::const_iterator I = Caller->begin(), E = Caller->end(); - I != E; ++I) - if (const InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator())) { - const BasicBlock *BB = II->getUnwindDest(); - const LandingPadInst *LP = BB->getLandingPadInst(); - - // If the personality functions match, then we can perform the - // inlining. Otherwise, we can't inline. - // TODO: This isn't 100% true. Some personality functions are proper - // supersets of others and can be used in place of the other. - if (LP->getPersonalityFn() != CalleePersonality) - return false; - - break; - } + Constant *CallerPersonality = + Caller->hasPersonalityFn() ? Caller->getPersonalityFn() : nullptr; + if (CalledPersonality) { + if (!CallerPersonality) + Caller->setPersonalityFn(CalledPersonality); + // If the personality functions match, then we can perform the + // inlining. Otherwise, we can't inline. + // TODO: This isn't 100% true. Some personality functions are proper + // supersets of others and can be used in place of the other. + else if (CalledPersonality != CallerPersonality) + return false; } // Get an iterator to the last basic block in the function, which will have diff --git a/lib/Transforms/Utils/InstructionNamer.cpp b/lib/Transforms/Utils/InstructionNamer.cpp index da890a2..c9bec9a 100644 --- a/lib/Transforms/Utils/InstructionNamer.cpp +++ b/lib/Transforms/Utils/InstructionNamer.cpp @@ -50,7 +50,7 @@ namespace { }; char InstNamer::ID = 0; -} +} // namespace INITIALIZE_PASS(InstNamer, "instnamer", "Assign names to anonymous instructions", false, false) diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index 9d40b69..fcc7986 100644 --- a/lib/Transforms/Utils/LCSSA.cpp +++ b/lib/Transforms/Utils/LCSSA.cpp @@ -300,7 +300,7 @@ struct LCSSA : public FunctionPass { AU.addPreserved<ScalarEvolution>(); } }; -} +} // namespace char LCSSA::ID = 0; INITIALIZE_PASS_BEGIN(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 70c77b0..5608557 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -14,6 +14,8 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" @@ -828,64 +830,45 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) { /// orders them so it usually won't matter. /// bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) { - bool Changed = false; - // This implementation doesn't currently consider undef operands // specially. Theoretically, two phis which are identical except for // one having an undef where the other doesn't could be collapsed. - // Map from PHI hash values to PHI nodes. If multiple PHIs have - // the same hash value, the element is the first PHI in the - // linked list in CollisionMap. - DenseMap<uintptr_t, PHINode *> HashMap; + struct PHIDenseMapInfo { + static PHINode *getEmptyKey() { + return DenseMapInfo<PHINode *>::getEmptyKey(); + } + static PHINode *getTombstoneKey() { + return DenseMapInfo<PHINode *>::getTombstoneKey(); + } + static unsigned getHashValue(PHINode *PN) { + // Compute a hash value on the operands. Instcombine will likely have + // sorted them, which helps expose duplicates, but we have to check all + // the operands to be safe in case instcombine hasn't run. + return static_cast<unsigned>(hash_combine( + hash_combine_range(PN->value_op_begin(), PN->value_op_end()), + hash_combine_range(PN->block_begin(), PN->block_end()))); + } + static bool isEqual(PHINode *LHS, PHINode *RHS) { + if (LHS == getEmptyKey() || LHS == getTombstoneKey() || + RHS == getEmptyKey() || RHS == getTombstoneKey()) + return LHS == RHS; + return LHS->isIdenticalTo(RHS); + } + }; - // Maintain linked lists of PHI nodes with common hash values. - DenseMap<PHINode *, PHINode *> CollisionMap; + // Set of unique PHINodes. + DenseSet<PHINode *, PHIDenseMapInfo> PHISet; // Examine each PHI. - for (BasicBlock::iterator I = BB->begin(); - PHINode *PN = dyn_cast<PHINode>(I++); ) { - // Compute a hash value on the operands. Instcombine will likely have sorted - // them, which helps expose duplicates, but we have to check all the - // operands to be safe in case instcombine hasn't run. - uintptr_t Hash = 0; - // This hash algorithm is quite weak as hash functions go, but it seems - // to do a good enough job for this particular purpose, and is very quick. - for (User::op_iterator I = PN->op_begin(), E = PN->op_end(); I != E; ++I) { - Hash ^= reinterpret_cast<uintptr_t>(static_cast<Value *>(*I)); - Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); - } - for (PHINode::block_iterator I = PN->block_begin(), E = PN->block_end(); - I != E; ++I) { - Hash ^= reinterpret_cast<uintptr_t>(static_cast<BasicBlock *>(*I)); - Hash = (Hash << 7) | (Hash >> (sizeof(uintptr_t) * CHAR_BIT - 7)); - } - // Avoid colliding with the DenseMap sentinels ~0 and ~0-1. - Hash >>= 1; - // If we've never seen this hash value before, it's a unique PHI. - std::pair<DenseMap<uintptr_t, PHINode *>::iterator, bool> Pair = - HashMap.insert(std::make_pair(Hash, PN)); - if (Pair.second) continue; - // Otherwise it's either a duplicate or a hash collision. - for (PHINode *OtherPN = Pair.first->second; ; ) { - if (OtherPN->isIdenticalTo(PN)) { - // A duplicate. Replace this PHI with its duplicate. - PN->replaceAllUsesWith(OtherPN); - PN->eraseFromParent(); - Changed = true; - break; - } - // A non-duplicate hash collision. - DenseMap<PHINode *, PHINode *>::iterator I = CollisionMap.find(OtherPN); - if (I == CollisionMap.end()) { - // Set this PHI to be the head of the linked list of colliding PHIs. - PHINode *Old = Pair.first->second; - Pair.first->second = PN; - CollisionMap[PN] = Old; - break; - } - // Proceed to the next PHI in the list. - OtherPN = I->second; + bool Changed = false; + for (auto I = BB->begin(); PHINode *PN = dyn_cast<PHINode>(I++);) { + auto Inserted = PHISet.insert(PN); + if (!Inserted.second) { + // A duplicate. Replace this PHI with its duplicate. + PN->replaceAllUsesWith(*Inserted.first); + PN->eraseFromParent(); + Changed = true; } } @@ -1173,10 +1156,11 @@ static void changeToCall(InvokeInst *II) { II->eraseFromParent(); } -static bool markAliveBlocks(BasicBlock *BB, +static bool markAliveBlocks(Function &F, SmallPtrSetImpl<BasicBlock*> &Reachable) { SmallVector<BasicBlock*, 128> Worklist; + BasicBlock *BB = F.begin(); Worklist.push_back(BB); Reachable.insert(BB); bool Changed = false; @@ -1247,7 +1231,7 @@ static bool markAliveBlocks(BasicBlock *BB, if (isa<ConstantPointerNull>(Callee) || isa<UndefValue>(Callee)) { changeToUnreachable(II, true); Changed = true; - } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(II)) { + } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) { if (II->use_empty() && II->onlyReadsMemory()) { // jump to the normal destination branch. BranchInst::Create(II->getNormalDest(), II); @@ -1272,7 +1256,7 @@ static bool markAliveBlocks(BasicBlock *BB, /// otherwise. bool llvm::removeUnreachableBlocks(Function &F) { SmallPtrSet<BasicBlock*, 128> Reachable; - bool Changed = markAliveBlocks(F.begin(), Reachable); + bool Changed = markAliveBlocks(F, Reachable); // If there are unreachable blocks in the CFG... if (Reachable.size() == F.size()) diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index 90dfaba..8b0afa6 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/lib/Transforms/Utils/LoopSimplify.cpp @@ -144,8 +144,6 @@ BasicBlock *llvm::InsertPreheaderForLoop(Loop *L, Pass *PP) { PreheaderBB = SplitBlockPredecessors(Header, OutsideBlocks, ".preheader", AA, DT, LI, PreserveLCSSA); - PreheaderBB->getTerminator()->setDebugLoc( - Header->getFirstNonPHI()->getDebugLoc()); DEBUG(dbgs() << "LoopSimplify: Creating pre-header " << PreheaderBB->getName() << "\n"); @@ -778,7 +776,7 @@ namespace { /// verifyAnalysis() - Verify LoopSimplifyForm's guarantees. void verifyAnalysis() const override; }; -} +} // namespace char LoopSimplify::ID = 0; INITIALIZE_PASS_BEGIN(LoopSimplify, "loop-simplify", diff --git a/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/lib/Transforms/Utils/LoopUnrollRuntime.cpp index d1774df..919b45d 100644 --- a/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -113,6 +113,7 @@ static void ConnectProlog(Loop *L, Value *BECount, unsigned Count, // Create a branch around the orignal loop, which is taken if there are no // iterations remaining to be executed after running the prologue. Instruction *InsertPt = PrologEnd->getTerminator(); + IRBuilder<> B(InsertPt); assert(Count != 0 && "nonsensical Count!"); @@ -120,9 +121,8 @@ static void ConnectProlog(Loop *L, Value *BECount, unsigned Count, // (since Count is a power of 2). This means %xtraiter is (BECount + 1) and // and all of the iterations of this loop were executed by the prologue. Note // that if BECount <u (Count - 1) then (BECount + 1) cannot unsigned-overflow. - Instruction *BrLoopExit = - new ICmpInst(InsertPt, ICmpInst::ICMP_ULT, BECount, - ConstantInt::get(BECount->getType(), Count - 1)); + Value *BrLoopExit = + B.CreateICmpULT(BECount, ConstantInt::get(BECount->getType(), Count - 1)); BasicBlock *Exit = L->getUniqueExitBlock(); assert(Exit && "Loop must have a single exit block only"); // Split the exit to maintain loop canonicalization guarantees @@ -130,7 +130,7 @@ static void ConnectProlog(Loop *L, Value *BECount, unsigned Count, SplitBlockPredecessors(Exit, Preds, ".unr-lcssa", AA, DT, LI, P->mustPreserveAnalysisID(LCSSAID)); // Add the branch to the exit block (around the unrolled loop) - BranchInst::Create(Exit, NewPH, BrLoopExit, InsertPt); + B.CreateCondBr(BrLoopExit, Exit, NewPH); InsertPt->eraseFromParent(); } @@ -184,23 +184,22 @@ static void CloneLoopBlocks(Loop *L, Value *NewIter, const bool UnrollProlog, VMap.erase((*BB)->getTerminator()); BasicBlock *FirstLoopBB = cast<BasicBlock>(VMap[Header]); BranchInst *LatchBR = cast<BranchInst>(NewBB->getTerminator()); + IRBuilder<> Builder(LatchBR); if (UnrollProlog) { - LatchBR->eraseFromParent(); - BranchInst::Create(InsertBot, NewBB); + Builder.CreateBr(InsertBot); } else { PHINode *NewIdx = PHINode::Create(NewIter->getType(), 2, "prol.iter", FirstLoopBB->getFirstNonPHI()); - IRBuilder<> Builder(LatchBR); Value *IdxSub = Builder.CreateSub(NewIdx, ConstantInt::get(NewIdx->getType(), 1), NewIdx->getName() + ".sub"); Value *IdxCmp = Builder.CreateIsNotNull(IdxSub, NewIdx->getName() + ".cmp"); - BranchInst::Create(FirstLoopBB, InsertBot, IdxCmp, NewBB); + Builder.CreateCondBr(IdxCmp, FirstLoopBB, InsertBot); NewIdx->addIncoming(NewIter, InsertTop); NewIdx->addIncoming(IdxSub, NewBB); - LatchBR->eraseFromParent(); } + LatchBR->eraseFromParent(); } } @@ -370,7 +369,7 @@ bool llvm::UnrollRuntimeLoopProlog(Loop *L, unsigned Count, // Branch to either the extra iterations or the cloned/unrolled loop // We will fix up the true branch label when adding loop body copies - BranchInst::Create(PEnd, PEnd, BranchVal, PreHeaderBR); + B.CreateCondBr(BranchVal, PEnd, PEnd); assert(PreHeaderBR->isUnconditional() && PreHeaderBR->getSuccessor(0) == PEnd && "CFG edges in Preheader are not correct"); diff --git a/lib/Transforms/Utils/LoopUtils.cpp b/lib/Transforms/Utils/LoopUtils.cpp index 5f25e6b..5cbde94 100644 --- a/lib/Transforms/Utils/LoopUtils.cpp +++ b/lib/Transforms/Utils/LoopUtils.cpp @@ -26,17 +26,17 @@ using namespace llvm::PatternMatch; #define DEBUG_TYPE "loop-utils" -bool ReductionDescriptor::areAllUsesIn(Instruction *I, - SmallPtrSetImpl<Instruction *> &Set) { +bool RecurrenceDescriptor::areAllUsesIn(Instruction *I, + SmallPtrSetImpl<Instruction *> &Set) { for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; ++Use) if (!Set.count(dyn_cast<Instruction>(*Use))) return false; return true; } -bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, - Loop *TheLoop, bool HasFunNoNaNAttr, - ReductionDescriptor &RedDes) { +bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurrenceKind Kind, + Loop *TheLoop, bool HasFunNoNaNAttr, + RecurrenceDescriptor &RedDes) { if (Phi->getNumIncomingValues() != 2) return false; @@ -66,7 +66,7 @@ bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, // the number of instruction we saw from the recognized min/max pattern, // to make sure we only see exactly the two instructions. unsigned NumCmpSelectPatternInst = 0; - ReductionInstDesc ReduxDesc(false, nullptr); + InstDesc ReduxDesc(false, nullptr); SmallPtrSet<Instruction *, 8> VisitedInsts; SmallVector<Instruction *, 8> Worklist; @@ -111,8 +111,8 @@ bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, return false; // Any reduction instruction must be of one of the allowed kinds. - ReduxDesc = isReductionInstr(Cur, Kind, ReduxDesc, HasFunNoNaNAttr); - if (!ReduxDesc.isReduction()) + ReduxDesc = isRecurrenceInstr(Cur, Kind, ReduxDesc, HasFunNoNaNAttr); + if (!ReduxDesc.isRecurrence()) return false; // A reduction operation must only have one use of the reduction value. @@ -164,7 +164,7 @@ bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, // Process instructions only once (termination). Each reduction cycle // value must only be used once, except by phi nodes and min/max // reductions which are represented as a cmp followed by a select. - ReductionInstDesc IgnoredVal(false, nullptr); + InstDesc IgnoredVal(false, nullptr); if (VisitedInsts.insert(UI).second) { if (isa<PHINode>(UI)) PHIs.push_back(UI); @@ -173,7 +173,7 @@ bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, } else if (!isa<PHINode>(UI) && ((!isa<FCmpInst>(UI) && !isa<ICmpInst>(UI) && !isa<SelectInst>(UI)) || - !isMinMaxSelectCmpPattern(UI, IgnoredVal).isReduction())) + !isMinMaxSelectCmpPattern(UI, IgnoredVal).isRecurrence())) return false; // Remember that we completed the cycle. @@ -197,11 +197,11 @@ bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, // only have a single instruction with out-of-loop users. // The ExitInstruction(Instruction which is allowed to have out-of-loop users) - // is saved as part of the ReductionDescriptor. + // is saved as part of the RecurrenceDescriptor. // Save the description of this reduction variable. - ReductionDescriptor RD(RdxStart, ExitInstruction, Kind, - ReduxDesc.getMinMaxKind()); + RecurrenceDescriptor RD(RdxStart, ExitInstruction, Kind, + ReduxDesc.getMinMaxKind()); RedDes = RD; @@ -210,9 +210,8 @@ bool ReductionDescriptor::AddReductionVar(PHINode *Phi, ReductionKind Kind, /// Returns true if the instruction is a Select(ICmp(X, Y), X, Y) instruction /// pattern corresponding to a min(X, Y) or max(X, Y). -ReductionInstDesc -ReductionDescriptor::isMinMaxSelectCmpPattern(Instruction *I, - ReductionInstDesc &Prev) { +RecurrenceDescriptor::InstDesc +RecurrenceDescriptor::isMinMaxSelectCmpPattern(Instruction *I, InstDesc &Prev) { assert((isa<ICmpInst>(I) || isa<FCmpInst>(I) || isa<SelectInst>(I)) && "Expect a select instruction"); @@ -223,84 +222,83 @@ ReductionDescriptor::isMinMaxSelectCmpPattern(Instruction *I, // select. if ((Cmp = dyn_cast<ICmpInst>(I)) || (Cmp = dyn_cast<FCmpInst>(I))) { if (!Cmp->hasOneUse() || !(Select = dyn_cast<SelectInst>(*I->user_begin()))) - return ReductionInstDesc(false, I); - return ReductionInstDesc(Select, Prev.getMinMaxKind()); + return InstDesc(false, I); + return InstDesc(Select, Prev.getMinMaxKind()); } // Only handle single use cases for now. if (!(Select = dyn_cast<SelectInst>(I))) - return ReductionInstDesc(false, I); + return InstDesc(false, I); if (!(Cmp = dyn_cast<ICmpInst>(I->getOperand(0))) && !(Cmp = dyn_cast<FCmpInst>(I->getOperand(0)))) - return ReductionInstDesc(false, I); + return InstDesc(false, I); if (!Cmp->hasOneUse()) - return ReductionInstDesc(false, I); + return InstDesc(false, I); Value *CmpLeft; Value *CmpRight; // Look for a min/max pattern. if (m_UMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_UIntMin); + return InstDesc(Select, MRK_UIntMin); else if (m_UMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_UIntMax); + return InstDesc(Select, MRK_UIntMax); else if (m_SMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_SIntMax); + return InstDesc(Select, MRK_SIntMax); else if (m_SMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_SIntMin); + return InstDesc(Select, MRK_SIntMin); else if (m_OrdFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMin); + return InstDesc(Select, MRK_FloatMin); else if (m_OrdFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMax); + return InstDesc(Select, MRK_FloatMax); else if (m_UnordFMin(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMin); + return InstDesc(Select, MRK_FloatMin); else if (m_UnordFMax(m_Value(CmpLeft), m_Value(CmpRight)).match(Select)) - return ReductionInstDesc(Select, ReductionInstDesc::MRK_FloatMax); + return InstDesc(Select, MRK_FloatMax); - return ReductionInstDesc(false, I); + return InstDesc(false, I); } -ReductionInstDesc ReductionDescriptor::isReductionInstr(Instruction *I, - ReductionKind Kind, - ReductionInstDesc &Prev, - bool HasFunNoNaNAttr) { +RecurrenceDescriptor::InstDesc +RecurrenceDescriptor::isRecurrenceInstr(Instruction *I, RecurrenceKind Kind, + InstDesc &Prev, bool HasFunNoNaNAttr) { bool FP = I->getType()->isFloatingPointTy(); bool FastMath = FP && I->hasUnsafeAlgebra(); switch (I->getOpcode()) { default: - return ReductionInstDesc(false, I); + return InstDesc(false, I); case Instruction::PHI: if (FP && (Kind != RK_FloatMult && Kind != RK_FloatAdd && Kind != RK_FloatMinMax)) - return ReductionInstDesc(false, I); - return ReductionInstDesc(I, Prev.getMinMaxKind()); + return InstDesc(false, I); + return InstDesc(I, Prev.getMinMaxKind()); case Instruction::Sub: case Instruction::Add: - return ReductionInstDesc(Kind == RK_IntegerAdd, I); + return InstDesc(Kind == RK_IntegerAdd, I); case Instruction::Mul: - return ReductionInstDesc(Kind == RK_IntegerMult, I); + return InstDesc(Kind == RK_IntegerMult, I); case Instruction::And: - return ReductionInstDesc(Kind == RK_IntegerAnd, I); + return InstDesc(Kind == RK_IntegerAnd, I); case Instruction::Or: - return ReductionInstDesc(Kind == RK_IntegerOr, I); + return InstDesc(Kind == RK_IntegerOr, I); case Instruction::Xor: - return ReductionInstDesc(Kind == RK_IntegerXor, I); + return InstDesc(Kind == RK_IntegerXor, I); case Instruction::FMul: - return ReductionInstDesc(Kind == RK_FloatMult && FastMath, I); + return InstDesc(Kind == RK_FloatMult && FastMath, I); case Instruction::FSub: case Instruction::FAdd: - return ReductionInstDesc(Kind == RK_FloatAdd && FastMath, I); + return InstDesc(Kind == RK_FloatAdd && FastMath, I); case Instruction::FCmp: case Instruction::ICmp: case Instruction::Select: if (Kind != RK_IntegerMinMax && (!HasFunNoNaNAttr || Kind != RK_FloatMinMax)) - return ReductionInstDesc(false, I); + return InstDesc(false, I); return isMinMaxSelectCmpPattern(I, Prev); } } -bool ReductionDescriptor::hasMultipleUsesOf( +bool RecurrenceDescriptor::hasMultipleUsesOf( Instruction *I, SmallPtrSetImpl<Instruction *> &Insts) { unsigned NumUses = 0; for (User::op_iterator Use = I->op_begin(), E = I->op_end(); Use != E; @@ -313,8 +311,8 @@ bool ReductionDescriptor::hasMultipleUsesOf( return false; } -bool ReductionDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, - ReductionDescriptor &RedDes) { +bool RecurrenceDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, + RecurrenceDescriptor &RedDes) { bool HasFunNoNaNAttr = false; BasicBlock *Header = TheLoop->getHeader(); @@ -366,7 +364,8 @@ bool ReductionDescriptor::isReductionPHI(PHINode *Phi, Loop *TheLoop, /// This function returns the identity element (or neutral element) for /// the operation K. -Constant *ReductionDescriptor::getReductionIdentity(ReductionKind K, Type *Tp) { +Constant *RecurrenceDescriptor::getRecurrenceIdentity(RecurrenceKind K, + Type *Tp) { switch (K) { case RK_IntegerXor: case RK_IntegerAdd: @@ -386,12 +385,12 @@ Constant *ReductionDescriptor::getReductionIdentity(ReductionKind K, Type *Tp) { // Adding zero to a number does not change it. return ConstantFP::get(Tp, 0.0L); default: - llvm_unreachable("Unknown reduction kind"); + llvm_unreachable("Unknown recurrence kind"); } } -/// This function translates the reduction kind to an LLVM binary operator. -unsigned ReductionDescriptor::getReductionBinOp(ReductionKind Kind) { +/// This function translates the recurrence kind to an LLVM binary operator. +unsigned RecurrenceDescriptor::getRecurrenceBinOp(RecurrenceKind Kind) { switch (Kind) { case RK_IntegerAdd: return Instruction::Add; @@ -412,41 +411,39 @@ unsigned ReductionDescriptor::getReductionBinOp(ReductionKind Kind) { case RK_FloatMinMax: return Instruction::FCmp; default: - llvm_unreachable("Unknown reduction operation"); + llvm_unreachable("Unknown recurrence operation"); } } -Value * -ReductionDescriptor::createMinMaxOp(IRBuilder<> &Builder, - ReductionInstDesc::MinMaxReductionKind RK, - Value *Left, Value *Right) { +Value *RecurrenceDescriptor::createMinMaxOp(IRBuilder<> &Builder, + MinMaxRecurrenceKind RK, + Value *Left, Value *Right) { CmpInst::Predicate P = CmpInst::ICMP_NE; switch (RK) { default: - llvm_unreachable("Unknown min/max reduction kind"); - case ReductionInstDesc::MRK_UIntMin: + llvm_unreachable("Unknown min/max recurrence kind"); + case MRK_UIntMin: P = CmpInst::ICMP_ULT; break; - case ReductionInstDesc::MRK_UIntMax: + case MRK_UIntMax: P = CmpInst::ICMP_UGT; break; - case ReductionInstDesc::MRK_SIntMin: + case MRK_SIntMin: P = CmpInst::ICMP_SLT; break; - case ReductionInstDesc::MRK_SIntMax: + case MRK_SIntMax: P = CmpInst::ICMP_SGT; break; - case ReductionInstDesc::MRK_FloatMin: + case MRK_FloatMin: P = CmpInst::FCMP_OLT; break; - case ReductionInstDesc::MRK_FloatMax: + case MRK_FloatMax: P = CmpInst::FCMP_OGT; break; } Value *Cmp; - if (RK == ReductionInstDesc::MRK_FloatMin || - RK == ReductionInstDesc::MRK_FloatMax) + if (RK == MRK_FloatMin || RK == MRK_FloatMax) Cmp = Builder.CreateFCmp(P, Left, Right, "rdx.minmax.cmp"); else Cmp = Builder.CreateICmp(P, Left, Right, "rdx.minmax.cmp"); diff --git a/lib/Transforms/Utils/LowerSwitch.cpp b/lib/Transforms/Utils/LowerSwitch.cpp index e0e0e90..c1b0645 100644 --- a/lib/Transforms/Utils/LowerSwitch.cpp +++ b/lib/Transforms/Utils/LowerSwitch.cpp @@ -101,7 +101,7 @@ namespace { return CI1->getValue().slt(CI2->getValue()); } }; -} +} // namespace char LowerSwitch::ID = 0; INITIALIZE_PASS(LowerSwitch, "lowerswitch", @@ -364,9 +364,9 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) { std::sort(Cases.begin(), Cases.end(), CaseCmp()); // Merge case into clusters - if (Cases.size()>=2) - for (CaseItr I = Cases.begin(), J = std::next(Cases.begin()); - J != Cases.end();) { + if (Cases.size() >= 2) { + CaseItr I = Cases.begin(); + for (CaseItr J = std::next(I), E = Cases.end(); J != E; ++J) { int64_t nextValue = J->Low->getSExtValue(); int64_t currentValue = I->High->getSExtValue(); BasicBlock* nextBB = J->BB; @@ -374,13 +374,16 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) { // If the two neighboring cases go to the same destination, merge them // into a single case. - if ((nextValue-currentValue==1) && (currentBB == nextBB)) { + assert(nextValue > currentValue && "Cases should be strictly ascending"); + if ((nextValue == currentValue + 1) && (currentBB == nextBB)) { I->High = J->High; - J = Cases.erase(J); - } else { - I = J++; + // FIXME: Combine branch weights. + } else if (++I != J) { + *I = *J; } } + Cases.erase(std::next(I), Cases.end()); + } for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) { if (I->Low != I->High) @@ -476,12 +479,10 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI) { // cases. assert(MaxPop > 0 && PopSucc); Default = PopSucc; - for (CaseItr I = Cases.begin(); I != Cases.end();) { - if (I->BB == PopSucc) - I = Cases.erase(I); - else - ++I; - } + Cases.erase(std::remove_if( + Cases.begin(), Cases.end(), + [PopSucc](const CaseRange &R) { return R.BB == PopSucc; }), + Cases.end()); // If there are no cases left, just branch. if (Cases.empty()) { diff --git a/lib/Transforms/Utils/MetaRenamer.cpp b/lib/Transforms/Utils/MetaRenamer.cpp index 395a46b..46dd65e 100644 --- a/lib/Transforms/Utils/MetaRenamer.cpp +++ b/lib/Transforms/Utils/MetaRenamer.cpp @@ -131,7 +131,7 @@ namespace { return true; } }; -} +} // namespace char MetaRenamer::ID = 0; INITIALIZE_PASS(MetaRenamer, "metarenamer", diff --git a/lib/Transforms/Utils/SSAUpdater.cpp b/lib/Transforms/Utils/SSAUpdater.cpp index 88b39dd..c0988987 100644 --- a/lib/Transforms/Utils/SSAUpdater.cpp +++ b/lib/Transforms/Utils/SSAUpdater.cpp @@ -303,7 +303,7 @@ public: } }; -} // End llvm namespace +} // namespace llvm /// Check to see if AvailableVals has an entry for the specified BB and if so, /// return it. If not, construct SSA form by first calculating the required diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 60ac271..3d7ab0f 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -136,7 +136,7 @@ public: : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC) {} bool run(BasicBlock *BB); }; -} +} // namespace /// SafeToMergeTerminators - Return true if it is safe to merge these two /// terminator instructions together. @@ -502,7 +502,7 @@ private: } }; -} +} // namespace static void EraseTerminatorInstAndDCECond(TerminatorInst *TI) { Instruction *Cond = nullptr; @@ -3717,7 +3717,7 @@ namespace { // For ArrayKind, this is the array. GlobalVariable *Array; }; -} +} // namespace SwitchLookupTable::SwitchLookupTable( Module &M, uint64_t TableSize, ConstantInt *Offset, @@ -4058,7 +4058,7 @@ static bool SwitchToLookupTable(SwitchInst *SI, IRBuilder<> &Builder, return false; // Figure out the corresponding result for each case value and phi node in the - // common destination, as well as the the min and max case values. + // common destination, as well as the min and max case values. assert(SI->case_begin() != SI->case_end()); SwitchInst::CaseIt CI = SI->case_begin(); ConstantInt *MinCaseVal = CI.getCaseValue(); diff --git a/lib/Transforms/Utils/SimplifyIndVar.cpp b/lib/Transforms/Utils/SimplifyIndVar.cpp index ab30aa1..68986ac 100644 --- a/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -77,7 +77,7 @@ namespace { Instruction *splitOverflowIntrinsic(Instruction *IVUser, const DominatorTree *DT); }; -} +} // namespace /// Fold an IV operand into its use. This removes increments of an /// aligned IV when used by a instruction that ignores the low bits. diff --git a/lib/Transforms/Utils/SimplifyInstructions.cpp b/lib/Transforms/Utils/SimplifyInstructions.cpp index c499c87..0a583a5 100644 --- a/lib/Transforms/Utils/SimplifyInstructions.cpp +++ b/lib/Transforms/Utils/SimplifyInstructions.cpp @@ -100,7 +100,7 @@ namespace { return Changed; } }; -} +} // namespace char InstSimplifier::ID = 0; INITIALIZE_PASS_BEGIN(InstSimplifier, "instsimplify", diff --git a/lib/Transforms/Utils/SymbolRewriter.cpp b/lib/Transforms/Utils/SymbolRewriter.cpp index a2a54da..4cc278f 100644 --- a/lib/Transforms/Utils/SymbolRewriter.cpp +++ b/lib/Transforms/Utils/SymbolRewriter.cpp @@ -538,7 +538,7 @@ void RewriteSymbols::loadAndParseMapFiles() { for (const auto &MapFile : MapFiles) parser.parse(MapFile, &Descriptors); } -} +} // namespace INITIALIZE_PASS(RewriteSymbols, "rewrite-symbols", "Rewrite Symbols", false, false) diff --git a/lib/Transforms/Vectorize/BBVectorize.cpp b/lib/Transforms/Vectorize/BBVectorize.cpp index 215d6f9..fd7661f 100644 --- a/lib/Transforms/Vectorize/BBVectorize.cpp +++ b/lib/Transforms/Vectorize/BBVectorize.cpp @@ -3192,7 +3192,7 @@ namespace { DEBUG(dbgs() << "BBV: final: \n" << BB << "\n"); } -} +} // namespace char BBVectorize::ID = 0; static const char bb_vectorize_name[] = "Basic-Block Vectorization"; diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 95c9381..b7faa20 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -872,7 +872,7 @@ public: /// ReductionList contains the reduction descriptors for all /// of the reductions that were found in the loop. - typedef DenseMap<PHINode*, ReductionDescriptor> ReductionList; + typedef DenseMap<PHINode *, RecurrenceDescriptor> ReductionList; /// InductionList saves induction variables and maps them to the /// induction descriptor. @@ -2906,7 +2906,7 @@ struct CSEDenseMapInfo { return LHS->isIdenticalTo(RHS); } }; -} +} // namespace /// \brief Check whether this block is a predicated block. /// Due to if predication of stores we might create a sequence of "if(pred) a[i] @@ -3093,13 +3093,13 @@ void InnerLoopVectorizer::vectorizeLoop() { // Find the reduction variable descriptor. assert(Legal->getReductionVars()->count(RdxPhi) && "Unable to find the reduction variable"); - ReductionDescriptor RdxDesc = (*Legal->getReductionVars())[RdxPhi]; + RecurrenceDescriptor RdxDesc = (*Legal->getReductionVars())[RdxPhi]; - ReductionDescriptor::ReductionKind RK = RdxDesc.getReductionKind(); - TrackingVH<Value> ReductionStartValue = RdxDesc.getReductionStartValue(); + RecurrenceDescriptor::RecurrenceKind RK = RdxDesc.getRecurrenceKind(); + TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue(); Instruction *LoopExitInst = RdxDesc.getLoopExitInstr(); - ReductionInstDesc::MinMaxReductionKind MinMaxKind = - RdxDesc.getMinMaxReductionKind(); + RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind = + RdxDesc.getMinMaxRecurrenceKind(); setDebugLocFromInst(Builder, ReductionStartValue); // We need to generate a reduction vector from the incoming scalar. @@ -3116,8 +3116,8 @@ void InnerLoopVectorizer::vectorizeLoop() { // one for multiplication, -1 for And. Value *Identity; Value *VectorStart; - if (RK == ReductionDescriptor::RK_IntegerMinMax || - RK == ReductionDescriptor::RK_FloatMinMax) { + if (RK == RecurrenceDescriptor::RK_IntegerMinMax || + RK == RecurrenceDescriptor::RK_FloatMinMax) { // MinMax reduction have the start value as their identify. if (VF == 1) { VectorStart = Identity = ReductionStartValue; @@ -3127,8 +3127,8 @@ void InnerLoopVectorizer::vectorizeLoop() { } } else { // Handle other reduction kinds: - Constant *Iden = - ReductionDescriptor::getReductionIdentity(RK, VecTy->getScalarType()); + Constant *Iden = RecurrenceDescriptor::getRecurrenceIdentity( + RK, VecTy->getScalarType()); if (VF == 1) { Identity = Iden; // This vector is the Identity vector where the first element is the @@ -3185,7 +3185,7 @@ void InnerLoopVectorizer::vectorizeLoop() { // Reduce all of the unrolled parts into a single vector. Value *ReducedPartRdx = RdxParts[0]; - unsigned Op = ReductionDescriptor::getReductionBinOp(RK); + unsigned Op = RecurrenceDescriptor::getRecurrenceBinOp(RK); setDebugLocFromInst(Builder, ReducedPartRdx); for (unsigned part = 1; part < UF; ++part) { if (Op != Instruction::ICmp && Op != Instruction::FCmp) @@ -3194,7 +3194,7 @@ void InnerLoopVectorizer::vectorizeLoop() { Builder.CreateBinOp((Instruction::BinaryOps)Op, RdxParts[part], ReducedPartRdx, "bin.rdx")); else - ReducedPartRdx = ReductionDescriptor::createMinMaxOp( + ReducedPartRdx = RecurrenceDescriptor::createMinMaxOp( Builder, MinMaxKind, ReducedPartRdx, RdxParts[part]); } @@ -3226,8 +3226,8 @@ void InnerLoopVectorizer::vectorizeLoop() { TmpVec = addFastMathFlag(Builder.CreateBinOp( (Instruction::BinaryOps)Op, TmpVec, Shuf, "bin.rdx")); else - TmpVec = ReductionDescriptor::createMinMaxOp(Builder, MinMaxKind, - TmpVec, Shuf); + TmpVec = RecurrenceDescriptor::createMinMaxOp(Builder, MinMaxKind, + TmpVec, Shuf); } // The result is in the first element of the vector. @@ -4040,8 +4040,8 @@ bool LoopVectorizationLegality::canVectorizeInstrs() { continue; } - if (ReductionDescriptor::isReductionPHI(Phi, TheLoop, - Reductions[Phi])) { + if (RecurrenceDescriptor::isReductionPHI(Phi, TheLoop, + Reductions[Phi])) { AllowedExit.insert(Reductions[Phi].getLoopExitInstr()); continue; } diff --git a/lib/Transforms/Vectorize/SLPVectorizer.cpp b/lib/Transforms/Vectorize/SLPVectorizer.cpp index a3a45c8..370e295 100644 --- a/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -315,12 +315,12 @@ static bool InTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst, } /// \returns the AA location that is being access by the instruction. -static AliasAnalysis::Location getLocation(Instruction *I, AliasAnalysis *AA) { +static MemoryLocation getLocation(Instruction *I, AliasAnalysis *AA) { if (StoreInst *SI = dyn_cast<StoreInst>(I)) return MemoryLocation::get(SI); if (LoadInst *LI = dyn_cast<LoadInst>(I)) return MemoryLocation::get(LI); - return AliasAnalysis::Location(); + return MemoryLocation(); } /// \returns True if the instruction is not a volatile or atomic load/store. @@ -515,7 +515,7 @@ private: /// /// \p Loc1 is the location of \p Inst1. It is passed explicitly because it /// is invariant in the calling loop. - bool isAliased(const AliasAnalysis::Location &Loc1, Instruction *Inst1, + bool isAliased(const MemoryLocation &Loc1, Instruction *Inst1, Instruction *Inst2) { // First check if the result is already in the cache. @@ -524,7 +524,7 @@ private: if (result.hasValue()) { return result.getValue(); } - AliasAnalysis::Location Loc2 = getLocation(Inst2, AA); + MemoryLocation Loc2 = getLocation(Inst2, AA); bool aliased = true; if (Loc1.Ptr && Loc2.Ptr && isSimple(Inst1) && isSimple(Inst2)) { // Do the alias check. @@ -1637,8 +1637,10 @@ bool BoUpSLP::isFullyVectorizableTinyTree() { if (VectorizableTree.size() != 2) return false; - // Handle splat stores. - if (!VectorizableTree[0].NeedToGather && isSplat(VectorizableTree[1].Scalars)) + // Handle splat and all-constants stores. + if (!VectorizableTree[0].NeedToGather && + (allConstant(VectorizableTree[1].Scalars) || + isSplat(VectorizableTree[1].Scalars))) return true; // Gathering cost would be too much for tiny trees. @@ -2903,7 +2905,7 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD, ScheduleData *DepDest = BundleMember->NextLoadStore; if (DepDest) { Instruction *SrcInst = BundleMember->Inst; - AliasAnalysis::Location SrcLoc = getLocation(SrcInst, SLP->AA); + MemoryLocation SrcLoc = getLocation(SrcInst, SLP->AA); bool SrcMayWrite = BundleMember->Inst->mayWriteToMemory(); unsigned numAliased = 0; unsigned DistToSrc = 1; |