diff options
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/CodeGenPrepare.cpp | 48 | ||||
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 8 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopUnrollPass.cpp | 1 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopUnswitch.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/Scalar.cpp | 11 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyCFGPass.cpp | 15 |
6 files changed, 76 insertions, 9 deletions
diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index 7ceda1fa1f2c2..50c96304db095 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -28,6 +28,7 @@ #include "llvm/Transforms/Utils/AddrModeMatcher.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Utils/BuildLibCalls.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/Assembly/Writer.h" @@ -36,6 +37,7 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/PatternMatch.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/IRBuilder.h" using namespace llvm; using namespace llvm::PatternMatch; @@ -72,6 +74,7 @@ namespace { DenseMap<Value*,Value*> &SunkAddrs); bool OptimizeInlineAsmInst(Instruction *I, CallSite CS, DenseMap<Value*,Value*> &SunkAddrs); + bool OptimizeCallInst(CallInst *CI); bool MoveExtToFormExtLoad(Instruction *I); bool OptimizeExtUses(Instruction *I); void findLoopBackEdges(const Function &F); @@ -537,6 +540,47 @@ static bool OptimizeCmpExpression(CmpInst *CI) { return MadeChange; } +namespace { +class CodeGenPrepareFortifiedLibCalls : public SimplifyFortifiedLibCalls { +protected: + void replaceCall(Value *With) { + CI->replaceAllUsesWith(With); + CI->eraseFromParent(); + } + bool isFoldable(unsigned SizeCIOp, unsigned, bool) const { + if (ConstantInt *SizeCI = dyn_cast<ConstantInt>(CI->getOperand(SizeCIOp))) + return SizeCI->isAllOnesValue(); + return false; + } +}; +} // end anonymous namespace + +bool CodeGenPrepare::OptimizeCallInst(CallInst *CI) { + // Lower all uses of llvm.objectsize.* + IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI); + if (II && II->getIntrinsicID() == Intrinsic::objectsize) { + bool Min = (cast<ConstantInt>(II->getOperand(2))->getZExtValue() == 1); + const Type *ReturnTy = CI->getType(); + Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); + CI->replaceAllUsesWith(RetVal); + CI->eraseFromParent(); + return true; + } + + // From here on out we're working with named functions. + if (CI->getCalledFunction() == 0) return false; + + // We'll need TargetData from here on out. + const TargetData *TD = TLI ? TLI->getTargetData() : 0; + if (!TD) return false; + + // Lower all default uses of _chk calls. This is very similar + // to what InstCombineCalls does, but here we are only lowering calls + // that have the default "don't know" as the objectsize. Anything else + // should be left alone. + CodeGenPrepareFortifiedLibCalls Simplifier; + return Simplifier.fold(CI, TD); +} //===----------------------------------------------------------------------===// // Memory Optimization //===----------------------------------------------------------------------===// @@ -913,6 +957,10 @@ bool CodeGenPrepare::OptimizeBlock(BasicBlock &BB) { } else // Sink address computing for memory operands into the block. MadeChange |= OptimizeInlineAsmInst(I, &(*CI), SunkAddrs); + } else { + // Other CallInst optimizations that don't need to muck with the + // enclosing iterator here. + MadeChange |= OptimizeCallInst(CI); } } } diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index cb563c3a7d035..de93e9f621fe3 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -43,6 +43,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" #include "llvm/Type.h" #include "llvm/Analysis/Dominators.h" @@ -215,7 +216,7 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L, void IndVarSimplify::RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) { // Verify the input to the pass in already in LCSSA form. - assert(L->isLCSSAForm()); + assert(L->isLCSSAForm(*DT)); SmallVector<BasicBlock*, 8> ExitBlocks; L->getUniqueExitBlocks(ExitBlocks); @@ -445,7 +446,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { // Clean up dead instructions. Changed |= DeleteDeadPHIs(L->getHeader()); // Check a post-condition. - assert(L->isLCSSAForm() && "Indvars did not leave the loop in lcssa form!"); + assert(L->isLCSSAForm(*DT) && "Indvars did not leave the loop in lcssa form!"); return Changed; } @@ -556,6 +557,9 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) { // dominates the exit block. if (I->mayHaveSideEffects() || I->mayReadFromMemory()) continue; + // Skip debug info intrinsics. + if (isa<DbgInfoIntrinsic>(I)) + continue; // Don't sink static AllocaInsts out of the entry block, which would // turn them into dynamic allocas! if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) diff --git a/lib/Transforms/Scalar/LoopUnrollPass.cpp b/lib/Transforms/Scalar/LoopUnrollPass.cpp index a355ec3a7e68f..4ad41ae4b59f7 100644 --- a/lib/Transforms/Scalar/LoopUnrollPass.cpp +++ b/lib/Transforms/Scalar/LoopUnrollPass.cpp @@ -86,7 +86,6 @@ static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls) { } bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) { - assert(L->isLCSSAForm()); LoopInfo *LI = &getAnalysis<LoopInfo>(); BasicBlock *Header = L->getHeader(); diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 071e9b7c9e97a..e3b809e35d4cc 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -206,7 +206,7 @@ bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) { Function *F = currentLoop->getHeader()->getParent(); bool Changed = false; do { - assert(currentLoop->isLCSSAForm()); + assert(currentLoop->isLCSSAForm(*DT)); redoLoop = false; Changed |= processCurrentLoop(); } while(redoLoop); diff --git a/lib/Transforms/Scalar/Scalar.cpp b/lib/Transforms/Scalar/Scalar.cpp index b54565cb80ecd..cb034232df534 100644 --- a/lib/Transforms/Scalar/Scalar.cpp +++ b/lib/Transforms/Scalar/Scalar.cpp @@ -14,6 +14,8 @@ #include "llvm-c/Transforms/Scalar.h" #include "llvm/PassManager.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Target/TargetData.h" #include "llvm/Transforms/Scalar.h" using namespace llvm; @@ -90,6 +92,11 @@ void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createScalarReplAggregatesPass()); } +void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef PM, + int Threshold) { + unwrap(PM)->add(createScalarReplAggregatesPass(Threshold)); +} + void LLVMAddSimplifyLibCallsPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createSimplifyLibCallsPass()); } @@ -105,3 +112,7 @@ void LLVMAddConstantPropagationPass(LLVMPassManagerRef PM) { void LLVMAddDemoteMemoryToRegisterPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createDemoteRegisterToMemoryPass()); } + +void LLVMAddVerifierPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createVerifierPass()); +} diff --git a/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/lib/Transforms/Scalar/SimplifyCFGPass.cpp index 62f34a2ee0680..738c5e8d13d1d 100644 --- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -26,6 +26,7 @@ #include "llvm/Transforms/Utils/Local.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/Attributes.h" #include "llvm/Support/CFG.h" @@ -210,12 +211,16 @@ static bool MergeEmptyReturnBlocks(Function &F) { // Check for something else in the block. BasicBlock::iterator I = Ret; --I; - if (!isa<PHINode>(I) || I != BB.begin() || - Ret->getNumOperands() == 0 || - Ret->getOperand(0) != I) + // Skip over debug info. + while (isa<DbgInfoIntrinsic>(I) && I != BB.begin()) + --I; + if (!isa<DbgInfoIntrinsic>(I) && + (!isa<PHINode>(I) || I != BB.begin() || + Ret->getNumOperands() == 0 || + Ret->getOperand(0) != I)) continue; } - + // If this is the first returning block, remember it and keep going. if (RetBlock == 0) { RetBlock = &BB; @@ -239,7 +244,7 @@ static bool MergeEmptyReturnBlocks(Function &F) { // If the canonical return block has no PHI node, create one now. PHINode *RetBlockPHI = dyn_cast<PHINode>(RetBlock->begin()); if (RetBlockPHI == 0) { - Value *InVal = cast<ReturnInst>(RetBlock->begin())->getOperand(0); + Value *InVal = cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0); RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(), "merge", &RetBlock->front()); |