From ee8b951e73a9580ada11725ccd2e4f49e758b34f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 29 Oct 2009 01:21:20 +0000 Subject: [PATCH] teach various passes about blockaddress. We no longer crash on any clang tests. llvm-svn: 85465 --- llvm/lib/Transforms/IPO/GlobalDCE.cpp | 14 ++--- llvm/lib/Transforms/Scalar/SCCP.cpp | 74 +++++++++++++++-------- llvm/lib/Transforms/Utils/ValueMapper.cpp | 4 +- 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Transforms/IPO/GlobalDCE.cpp b/llvm/lib/Transforms/IPO/GlobalDCE.cpp index af4711e09289..cfab6b27d15b 100644 --- a/llvm/lib/Transforms/IPO/GlobalDCE.cpp +++ b/llvm/lib/Transforms/IPO/GlobalDCE.cpp @@ -191,13 +191,13 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { void GlobalDCE::MarkUsedGlobalsAsNeeded(Constant *C) { if (GlobalValue *GV = dyn_cast(C)) - GlobalIsNeeded(GV); - else { - // Loop over all of the operands of the constant, adding any globals they - // use to the list of needed globals. - for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I) - MarkUsedGlobalsAsNeeded(cast(*I)); - } + return GlobalIsNeeded(GV); + + // Loop over all of the operands of the constant, adding any globals they + // use to the list of needed globals. + for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I) + if (Constant *OpC = dyn_cast(*I)) + MarkUsedGlobalsAsNeeded(OpC); } // RemoveUnusedGlobalValue - Loop over all of the uses of the specified diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index 4701d2f74056..4e5fae8a0414 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -448,10 +448,16 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI, Succs[BCValue.getConstant() == ConstantInt::getFalse(*Context)] = true; } } - } else if (isa(&TI)) { + return; + } + + if (isa(&TI)) { // Invoke instructions successors are always executable. Succs[0] = Succs[1] = true; - } else if (SwitchInst *SI = dyn_cast(&TI)) { + return; + } + + if (SwitchInst *SI = dyn_cast(&TI)) { LatticeVal &SCValue = getValueState(SI->getCondition()); if (SCValue.isOverdefined() || // Overdefined condition? (SCValue.isConstant() && !isa(SCValue.getConstant()))) { @@ -459,9 +465,20 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI, Succs.assign(TI.getNumSuccessors(), true); } else if (SCValue.isConstant()) Succs[SI->findCaseValue(cast(SCValue.getConstant()))] = true; - } else { - llvm_unreachable("SCCP: Don't know how to handle this terminator!"); + return; } + + // TODO: This could be improved if the operand is a [cast of a] BlockAddress. + if (isa(&TI)) { + // Just mark all destinations executable! + Succs.assign(TI.getNumSuccessors(), true); + return; + } + +#ifndef NDEBUG + errs() << "Unknown terminator instruction: " << TI << '\n'; +#endif + llvm_unreachable("SCCP: Don't know how to handle this terminator!"); } @@ -479,25 +496,27 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) { if (BranchInst *BI = dyn_cast(TI)) { if (BI->isUnconditional()) return true; - else { - LatticeVal &BCValue = getValueState(BI->getCondition()); - if (BCValue.isOverdefined()) { - // Overdefined condition variables mean the branch could go either way. - return true; - } else if (BCValue.isConstant()) { - // Not branching on an evaluatable constant? - if (!isa(BCValue.getConstant())) return true; + + LatticeVal &BCValue = getValueState(BI->getCondition()); + if (BCValue.isOverdefined()) { + // Overdefined condition variables mean the branch could go either way. + return true; + } else if (BCValue.isConstant()) { + // Not branching on an evaluatable constant? + if (!isa(BCValue.getConstant())) return true; - // Constant condition variables mean the branch can only go a single way - return BI->getSuccessor(BCValue.getConstant() == - ConstantInt::getFalse(*Context)) == To; - } - return false; + // Constant condition variables mean the branch can only go a single way + return BI->getSuccessor(BCValue.getConstant() == + ConstantInt::getFalse(*Context)) == To; } - } else if (isa(TI)) { - // Invoke instructions successors are always executable. + return false; + } + + // Invoke instructions successors are always executable. + if (isa(TI)) return true; - } else if (SwitchInst *SI = dyn_cast(TI)) { + + if (SwitchInst *SI = dyn_cast(TI)) { LatticeVal &SCValue = getValueState(SI->getCondition()); if (SCValue.isOverdefined()) { // Overdefined condition? // All destinations are executable! @@ -517,12 +536,17 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) { return SI->getDefaultDest() == To; } return false; - } else { -#ifndef NDEBUG - errs() << "Unknown terminator instruction: " << *TI << '\n'; -#endif - llvm_unreachable(0); } + + // Just mark all destinations executable! + // TODO: This could be improved if the operand is a [cast of a] BlockAddress. + if (isa(&TI)) + return true; + +#ifndef NDEBUG + errs() << "Unknown terminator instruction: " << *TI << '\n'; +#endif + llvm_unreachable(0); } // visit Implementations - Something changed in this instruction... Either an diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 21126c94aef9..39331d78169a 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -113,8 +113,8 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM) { if (BlockAddress *BA = dyn_cast(C)) { Function *F = cast(MapValue(BA->getFunction(), VM)); - BasicBlock *BB = cast(MapValue(BA->getBasicBlock(), VM)); - return VM[V] = BlockAddress::get(F, BB); + BasicBlock *BB = cast_or_null(MapValue(BA->getBasicBlock(),VM)); + return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock()); } llvm_unreachable("Unknown type of constant!");