diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/AliasAnalysis.cpp | 11 | ||||
-rw-r--r-- | lib/Analysis/Analysis.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 23 | ||||
-rw-r--r-- | lib/Analysis/DbgInfoPrinter.cpp | 59 | ||||
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 164 | ||||
-rw-r--r-- | lib/Analysis/IVUsers.cpp | 5 | ||||
-rw-r--r-- | lib/Analysis/InlineCost.cpp | 40 | ||||
-rw-r--r-- | lib/Analysis/LoopInfo.cpp | 5 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 22 | ||||
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 28 |
10 files changed, 142 insertions, 223 deletions
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index dee9b53..371dcaf 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -116,13 +116,16 @@ AliasAnalysis::getModRefBehavior(Function *F, return DoesNotAccessMemory; if (F->onlyReadsMemory()) return OnlyReadsMemory; - if (unsigned id = F->getIntrinsicID()) { + if (unsigned id = F->getIntrinsicID()) + return getModRefBehavior(id); + } + return UnknownModRefBehavior; +} + +AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(unsigned iid) { #define GET_INTRINSIC_MODREF_BEHAVIOR #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_MODREF_BEHAVIOR - } - } - return UnknownModRefBehavior; } AliasAnalysis::ModRefResult diff --git a/lib/Analysis/Analysis.cpp b/lib/Analysis/Analysis.cpp index f8cb323..398dec7 100644 --- a/lib/Analysis/Analysis.cpp +++ b/lib/Analysis/Analysis.cpp @@ -13,11 +13,11 @@ using namespace llvm; -int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action, - char **OutMessages) { +LLVMBool LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action, + char **OutMessages) { std::string Messages; - int Result = verifyModule(*unwrap(M), + LLVMBool Result = verifyModule(*unwrap(M), static_cast<VerifierFailureAction>(Action), OutMessages? &Messages : 0); @@ -27,7 +27,7 @@ int LLVMVerifyModule(LLVMModuleRef M, LLVMVerifierFailureAction Action, return Result; } -int LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) { +LLVMBool LLVMVerifyFunction(LLVMValueRef Fn, LLVMVerifierFailureAction Action) { return verifyFunction(*unwrap<Function>(Fn), static_cast<VerifierFailureAction>(Action)); } diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index eaf90d0..4ae8859 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -398,8 +398,8 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C, BytesLoaded, TD)) return 0; - APInt ResultVal(IntType->getBitWidth(), 0); - for (unsigned i = 0; i != BytesLoaded; ++i) { + APInt ResultVal = APInt(IntType->getBitWidth(), RawBytes[BytesLoaded-1]); + for (unsigned i = 1; i != BytesLoaded; ++i) { ResultVal <<= 8; ResultVal |= APInt(IntType->getBitWidth(), RawBytes[BytesLoaded-1-i]); } @@ -718,14 +718,13 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, switch (Opcode) { default: return 0; + case Instruction::ICmp: + case Instruction::FCmp: assert(0 && "Invalid for compares"); case Instruction::Call: if (Function *F = dyn_cast<Function>(Ops[0])) if (canConstantFoldCallTo(F)) return ConstantFoldCall(F, Ops+1, NumOps-1); return 0; - case Instruction::ICmp: - case Instruction::FCmp: - llvm_unreachable("This function is invalid for compares: no predicate specified"); case Instruction::PtrToInt: // If the input is a inttoptr, eliminate the pair. This requires knowing // the width of a pointer, so it can't be done in ConstantExpr::getCast. @@ -877,6 +876,20 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, CE1->getOperand(0), TD); } } + + // icmp eq (or x, y), 0 -> (icmp eq x, 0) & (icmp eq y, 0) + // icmp ne (or x, y), 0 -> (icmp ne x, 0) | (icmp ne y, 0) + if ((Predicate == ICmpInst::ICMP_EQ || Predicate == ICmpInst::ICMP_NE) && + CE0->getOpcode() == Instruction::Or && Ops1->isNullValue()) { + Constant *LHS = + ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(0), Ops1,TD); + Constant *RHS = + ConstantFoldCompareInstOperands(Predicate, CE0->getOperand(1), Ops1,TD); + unsigned OpC = + Predicate == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or; + Constant *Ops[] = { LHS, RHS }; + return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, 2, TD); + } } return ConstantExpr::getCompare(Predicate, Ops0, Ops1); diff --git a/lib/Analysis/DbgInfoPrinter.cpp b/lib/Analysis/DbgInfoPrinter.cpp index 7d72b38..3532b05 100644 --- a/lib/Analysis/DbgInfoPrinter.cpp +++ b/lib/Analysis/DbgInfoPrinter.cpp @@ -37,8 +37,6 @@ PrintDirectory("print-fullpath", namespace { class PrintDbgInfo : public FunctionPass { raw_ostream &Out; - void printStopPoint(const DbgStopPointInst *DSI); - void printFuncStart(const DbgFuncStartInst *FS); void printVariableDeclaration(const Value *V); public: static char ID; // Pass identification @@ -74,27 +72,6 @@ void PrintDbgInfo::printVariableDeclaration(const Value *V) { Out << File << ":" << LineNo << "\n"; } -void PrintDbgInfo::printStopPoint(const DbgStopPointInst *DSI) { - if (PrintDirectory) - if (MDString *Str = dyn_cast<MDString>(DSI->getDirectory())) - Out << Str->getString() << '/'; - - if (MDString *Str = dyn_cast<MDString>(DSI->getFileName())) - Out << Str->getString(); - Out << ':' << DSI->getLine(); - - if (unsigned Col = DSI->getColumn()) - Out << ':' << Col; -} - -void PrintDbgInfo::printFuncStart(const DbgFuncStartInst *FS) { - DISubprogram Subprogram(FS->getSubprogram()); - Out << "; fully qualified function name: " << Subprogram.getDisplayName() - << " return type: " << Subprogram.getReturnTypeName() - << " at line " << Subprogram.getLineNumber() - << "\n\n"; -} - bool PrintDbgInfo::runOnFunction(Function &F) { if (F.isDeclaration()) return false; @@ -108,57 +85,21 @@ bool PrintDbgInfo::runOnFunction(Function &F) { // Skip dead blocks. continue; - const DbgStopPointInst *DSI = findBBStopPoint(BB); Out << BB->getName(); Out << ":"; - if (DSI) { - Out << "; ("; - printStopPoint(DSI); - Out << ")"; - } - Out << "\n"; - // A dbgstoppoint's information is valid until we encounter a new one. - const DbgStopPointInst *LastDSP = DSI; - bool Printed = DSI != 0; for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; ++i) { - if (isa<DbgInfoIntrinsic>(i)) { - if ((DSI = dyn_cast<DbgStopPointInst>(i))) { - if (DSI->getContext() == LastDSP->getContext() && - DSI->getLineValue() == LastDSP->getLineValue() && - DSI->getColumnValue() == LastDSP->getColumnValue()) - // Don't print same location twice. - continue; - - LastDSP = cast<DbgStopPointInst>(i); - - // Don't print consecutive stoppoints, use a flag to know which one we - // printed. - Printed = false; - } else if (const DbgFuncStartInst *FS = dyn_cast<DbgFuncStartInst>(i)) { - printFuncStart(FS); - } - } else { - if (!Printed && LastDSP) { - Out << "; "; - printStopPoint(LastDSP); - Out << "\n"; - Printed = true; - } - Out << *i << '\n'; printVariableDeclaration(i); if (const User *U = dyn_cast<User>(i)) { for(unsigned i=0;i<U->getNumOperands();i++) printVariableDeclaration(U->getOperand(i)); } - } } } - return false; } diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index de2d839..59ba807 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -599,9 +599,7 @@ void DIVariable::dump() const { //===----------------------------------------------------------------------===// DIFactory::DIFactory(Module &m) - : M(m), VMContext(M.getContext()), DeclareFn(0) { - EmptyStructPtr = PointerType::getUnqual(StructType::get(VMContext)); -} + : M(m), VMContext(M.getContext()), DeclareFn(0) {} Constant *DIFactory::GetTagConstant(unsigned TAG) { assert((TAG & LLVMDebugVersionMask) == 0 && @@ -1033,58 +1031,52 @@ DILocation DIFactory::CreateLocation(unsigned LineNo, unsigned ColumnNo, /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D, - Instruction *InsertBefore) { - // Cast the storage to a {}* for the call to llvm.dbg.declare. - Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertBefore); - + Instruction *InsertBefore) { if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = { Storage, D.getNode() }; + Value *Elts[] = { Storage }; + Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() }; return CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore); } /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D, - BasicBlock *InsertAtEnd) { - // Cast the storage to a {}* for the call to llvm.dbg.declare. - Storage = new BitCastInst(Storage, EmptyStructPtr, "", InsertAtEnd); - + BasicBlock *InsertAtEnd) { if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = { Storage, D.getNode() }; + Value *Elts[] = { Storage }; + Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() }; return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); } /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. -Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset, +Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset, DIVariable D, Instruction *InsertBefore) { assert(V && "no value passed to dbg.value"); - assert(Offset->getType() == Type::getInt64Ty(V->getContext()) && - "offset must be i64"); if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); Value *Elts[] = { V }; - Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset, + Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), + ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), D.getNode() }; return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore); } /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. -Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, Value *Offset, +Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset, DIVariable D, BasicBlock *InsertAtEnd) { assert(V && "no value passed to dbg.value"); - assert(Offset->getType() == Type::getInt64Ty(V->getContext()) && - "offset must be i64"); if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); Value *Elts[] = { V }; - Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), Offset, + Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), + ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), D.getNode() }; return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd); } @@ -1242,52 +1234,6 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) { return true; } -/// findStopPoint - Find the stoppoint coressponding to this instruction, that -/// is the stoppoint that dominates this instruction. -const DbgStopPointInst *llvm::findStopPoint(const Instruction *Inst) { - if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(Inst)) - return DSI; - - const BasicBlock *BB = Inst->getParent(); - BasicBlock::const_iterator I = Inst, B; - while (BB) { - B = BB->begin(); - - // A BB consisting only of a terminator can't have a stoppoint. - while (I != B) { - --I; - if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I)) - return DSI; - } - - // This BB didn't have a stoppoint: if there is only one predecessor, look - // for a stoppoint there. We could use getIDom(), but that would require - // dominator info. - BB = I->getParent()->getUniquePredecessor(); - if (BB) - I = BB->getTerminator(); - } - - return 0; -} - -/// findBBStopPoint - Find the stoppoint corresponding to first real -/// (non-debug intrinsic) instruction in this Basic Block, and return the -/// stoppoint for it. -const DbgStopPointInst *llvm::findBBStopPoint(const BasicBlock *BB) { - for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (const DbgStopPointInst *DSI = dyn_cast<DbgStopPointInst>(I)) - return DSI; - - // Fallback to looking for stoppoint of unique predecessor. Useful if this - // BB contains no stoppoints, but unique predecessor does. - BB = BB->getUniquePredecessor(); - if (BB) - return findStopPoint(BB->getTerminator()); - - return 0; -} - Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) { const Module *M = V->getParent(); NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"); @@ -1306,25 +1252,24 @@ Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) { /// Finds the llvm.dbg.declare intrinsic corresponding to this value if any. /// It looks through pointer casts too. -const DbgDeclareInst *llvm::findDbgDeclare(const Value *V, bool stripCasts) { - if (stripCasts) { - V = V->stripPointerCasts(); - - // Look for the bitcast. - for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); - I != E; ++I) - if (isa<BitCastInst>(I)) { - const DbgDeclareInst *DDI = findDbgDeclare(*I, false); - if (DDI) return DDI; - } +const DbgDeclareInst *llvm::findDbgDeclare(const Value *V) { + V = V->stripPointerCasts(); + + if (!isa<Instruction>(V) && !isa<Argument>(V)) return 0; - } - - // Find llvm.dbg.declare among uses of the instruction. - for (Value::use_const_iterator I = V->use_begin(), E =V->use_end(); - I != E; ++I) - if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) - return DDI; + + const Function *F = NULL; + if (const Instruction *I = dyn_cast<Instruction>(V)) + F = I->getParent()->getParent(); + else if (const Argument *A = dyn_cast<Argument>(V)) + F = A->getParent(); + + for (Function::const_iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) + for (BasicBlock::const_iterator BI = (*FI).begin(), BE = (*FI).end(); + BI != BE; ++BI) + if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) + if (DDI->getAddress() == V) + return DDI; return 0; } @@ -1372,29 +1317,6 @@ bool llvm::getLocationInfo(const Value *V, std::string &DisplayName, } /// ExtractDebugLocation - Extract debug location information -/// from llvm.dbg.stoppoint intrinsic. -DebugLoc llvm::ExtractDebugLocation(DbgStopPointInst &SPI, - DebugLocTracker &DebugLocInfo) { - DebugLoc DL; - Value *Context = SPI.getContext(); - - // If this location is already tracked then use it. - DebugLocTuple Tuple(cast<MDNode>(Context), NULL, SPI.getLine(), - SPI.getColumn()); - DenseMap<DebugLocTuple, unsigned>::iterator II - = DebugLocInfo.DebugIdMap.find(Tuple); - if (II != DebugLocInfo.DebugIdMap.end()) - return DebugLoc::get(II->second); - - // Add a new location entry. - unsigned Id = DebugLocInfo.DebugLocations.size(); - DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = Id; - - return DebugLoc::get(Id); -} - -/// ExtractDebugLocation - Extract debug location information /// from DILocation. DebugLoc llvm::ExtractDebugLocation(DILocation &Loc, DebugLocTracker &DebugLocInfo) { @@ -1419,32 +1341,6 @@ DebugLoc llvm::ExtractDebugLocation(DILocation &Loc, return DebugLoc::get(Id); } -/// ExtractDebugLocation - Extract debug location information -/// from llvm.dbg.func_start intrinsic. -DebugLoc llvm::ExtractDebugLocation(DbgFuncStartInst &FSI, - DebugLocTracker &DebugLocInfo) { - DebugLoc DL; - Value *SP = FSI.getSubprogram(); - - DISubprogram Subprogram(cast<MDNode>(SP)); - unsigned Line = Subprogram.getLineNumber(); - DICompileUnit CU(Subprogram.getCompileUnit()); - - // If this location is already tracked then use it. - DebugLocTuple Tuple(CU.getNode(), NULL, Line, /* Column */ 0); - DenseMap<DebugLocTuple, unsigned>::iterator II - = DebugLocInfo.DebugIdMap.find(Tuple); - if (II != DebugLocInfo.DebugIdMap.end()) - return DebugLoc::get(II->second); - - // Add a new location entry. - unsigned Id = DebugLocInfo.DebugLocations.size(); - DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = Id; - - return DebugLoc::get(Id); -} - /// getDISubprogram - Find subprogram that is enclosing this scope. DISubprogram llvm::getDISubprogram(MDNode *Scope) { DIDescriptor D(Scope); diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp index df9e31c..26c0c9e 100644 --- a/lib/Analysis/IVUsers.cpp +++ b/lib/Analysis/IVUsers.cpp @@ -128,8 +128,9 @@ static bool getSCEVStartAndStride(const SCEV *&SH, Loop *L, Loop *UseLoop, if (!AddRecStride->properlyDominates(Header, DT)) return false; - DEBUG(dbgs() << "[" << L->getHeader()->getName() - << "] Variable stride: " << *AddRec << "\n"); + DEBUG(dbgs() << "["; + WriteAsOperand(dbgs(), L->getHeader(), /*PrintType=*/false); + dbgs() << "] Variable stride: " << *AddRec << "\n"); } Stride = AddRecStride; diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp index bd9377b..651c918 100644 --- a/lib/Analysis/InlineCost.cpp +++ b/lib/Analysis/InlineCost.cpp @@ -102,6 +102,37 @@ unsigned InlineCostAnalyzer::FunctionInfo:: return Reduction; } +// callIsSmall - If a call is likely to lower to a single target instruction, or +// is otherwise deemed small return true. +// TODO: Perhaps calls like memcpy, strcpy, etc? +static bool callIsSmall(const Function *F) { + if (!F) return false; + + if (F->hasLocalLinkage()) return false; + + if (!F->hasName()) return false; + + StringRef Name = F->getName(); + + // These will all likely lower to a single selection DAG node. + if (Name == "copysign" || Name == "copysignf" || + Name == "fabs" || Name == "fabsf" || Name == "fabsl" || + Name == "sin" || Name == "sinf" || Name == "sinl" || + Name == "cos" || Name == "cosf" || Name == "cosl" || + Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl" ) + return true; + + // These are all likely to be optimized into something smaller. + if (Name == "pow" || Name == "powf" || Name == "powl" || + Name == "exp2" || Name == "exp2l" || Name == "exp2f" || + Name == "floor" || Name == "floorf" || Name == "ceil" || + Name == "round" || Name == "ffs" || Name == "ffsl" || + Name == "abs" || Name == "labs" || Name == "llabs") + return true; + + return false; +} + /// analyzeBasicBlock - Fill in the current structure with information gleaned /// from the specified block. void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { @@ -129,7 +160,7 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { // Calls often compile into many machine instructions. Bump up their // cost to reflect this. - if (!isa<IntrinsicInst>(II)) + if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction())) NumInsts += InlineConstants::CallPenalty; } @@ -141,11 +172,16 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { if (isa<ExtractElementInst>(II) || isa<VectorType>(II->getType())) ++NumVectorInsts; - // Noop casts, including ptr <-> int, don't count. if (const CastInst *CI = dyn_cast<CastInst>(II)) { + // Noop casts, including ptr <-> int, don't count. if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) || isa<PtrToIntInst>(CI)) continue; + // Result of a cmp instruction is often extended (to be used by other + // cmp instructions, logical or return instructions). These are usually + // nop on most sane targets. + if (isa<CmpInst>(CI->getOperand(0))) + continue; } else if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(II)){ // If a GEP has all constant indices, it will probably be folded with // a load/store. diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 5d31c11..453af5a 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -21,6 +21,7 @@ #include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SmallPtrSet.h" #include <algorithm> @@ -385,6 +386,10 @@ BasicBlock *Loop::getUniqueExitBlock() const { return 0; } +void Loop::dump() const { + print(dbgs()); +} + //===----------------------------------------------------------------------===// // LoopInfo implementation // diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 17dc686..4d85ce4 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -316,7 +316,9 @@ void SCEVAddRecExpr::print(raw_ostream &OS) const { OS << "{" << *Operands[0]; for (unsigned i = 1, e = Operands.size(); i != e; ++i) OS << ",+," << *Operands[i]; - OS << "}<" << L->getHeader()->getName() + ">"; + OS << "}<"; + WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false); + OS << ">"; } void SCEVFieldOffsetExpr::print(raw_ostream &OS) const { @@ -5193,7 +5195,9 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE, for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I) PrintLoopInfo(OS, SE, *I); - OS << "Loop " << L->getHeader()->getName() << ": "; + OS << "Loop "; + WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false); + OS << ": "; SmallVector<BasicBlock *, 8> ExitBlocks; L->getExitBlocks(ExitBlocks); @@ -5206,8 +5210,10 @@ static void PrintLoopInfo(raw_ostream &OS, ScalarEvolution *SE, OS << "Unpredictable backedge-taken count. "; } - OS << "\n"; - OS << "Loop " << L->getHeader()->getName() << ": "; + OS << "\n" + "Loop "; + WriteAsOperand(OS, L->getHeader(), /*PrintType=*/false); + OS << ": "; if (!isa<SCEVCouldNotCompute>(SE->getMaxBackedgeTakenCount(L))) { OS << "max backedge-taken count is " << *SE->getMaxBackedgeTakenCount(L); @@ -5227,7 +5233,9 @@ void ScalarEvolution::print(raw_ostream &OS, const Module *) const { // const isn't dangerous. ScalarEvolution &SE = *const_cast<ScalarEvolution *>(this); - OS << "Classifying expressions for: " << F->getName() << "\n"; + OS << "Classifying expressions for: "; + WriteAsOperand(OS, F, /*PrintType=*/false); + OS << "\n"; for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) if (isSCEVable(I->getType())) { OS << *I << '\n'; @@ -5256,7 +5264,9 @@ void ScalarEvolution::print(raw_ostream &OS, const Module *) const { OS << "\n"; } - OS << "Determining loop execution counts for: " << F->getName() << "\n"; + OS << "Determining loop execution counts for: "; + WriteAsOperand(OS, F, /*PrintType=*/false); + OS << "\n"; for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) PrintLoopInfo(OS, &SE, *I); } diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index acd3119..91e5bc3 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -726,8 +726,7 @@ unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD, Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1); if (Tmp2 == 1) return 1; - return std::min(Tmp, Tmp2)-1; - break; + return std::min(Tmp, Tmp2)-1; case Instruction::Sub: Tmp2 = ComputeNumSignBits(U->getOperand(1), TD, Depth+1); @@ -757,8 +756,24 @@ unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD, // is, at worst, one more bit than the inputs. Tmp = ComputeNumSignBits(U->getOperand(0), TD, Depth+1); if (Tmp == 1) return 1; // Early out. - return std::min(Tmp, Tmp2)-1; - break; + return std::min(Tmp, Tmp2)-1; + + case Instruction::PHI: { + PHINode *PN = cast<PHINode>(U); + // Don't analyze large in-degree PHIs. + if (PN->getNumIncomingValues() > 4) break; + + // Take the minimum of all incoming values. This can't infinitely loop + // because of our depth threshold. + Tmp = ComputeNumSignBits(PN->getIncomingValue(0), TD, Depth+1); + for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) { + if (Tmp == 1) return Tmp; + Tmp = std::min(Tmp, + ComputeNumSignBits(PN->getIncomingValue(1), TD, Depth+1)); + } + return Tmp; + } + case Instruction::Trunc: // FIXME: it's tricky to do anything useful for this, but it is an important // case for targets like X86. @@ -1348,7 +1363,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset, // Make sure the index-ee is a pointer to array of i8. const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType()); const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType()); - if (AT == 0 || AT->getElementType() != Type::getInt8Ty(V->getContext())) + if (AT == 0 || !AT->getElementType()->isInteger(8)) return false; // Check to make sure that the first operand of the GEP is an integer and @@ -1387,8 +1402,7 @@ bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset, // Must be a Constant Array ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit); - if (Array == 0 || - Array->getType()->getElementType() != Type::getInt8Ty(V->getContext())) + if (Array == 0 || !Array->getType()->getElementType()->isInteger(8)) return false; // Get the number of elements in the array |