From 9a8641201b2db8427be2a6531c043f384562c081 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 7 Dec 2009 18:36:53 +0000 Subject: [PATCH] checkpoint of the new PHITransAddr code, still not done and not used by anything. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90779 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/PHITransAddr.h | 58 +++--- lib/Analysis/PHITransAddr.cpp | 286 ++++++++++++++++++++++++--- 2 files changed, 292 insertions(+), 52 deletions(-) diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h index e19fb1c13f6..ed5ddcae280 100644 --- a/include/llvm/Analysis/PHITransAddr.h +++ b/include/llvm/Analysis/PHITransAddr.h @@ -35,10 +35,13 @@ class PHITransAddr { /// Addr - The actual address we're analyzing. Value *Addr; + /// TD - The target data we are playing with if known, otherwise null. + const TargetData *TD; + /// InstInputs - The inputs for our symbolic address. SmallVector InstInputs; public: - PHITransAddr(Value *addr) : Addr(addr) { + PHITransAddr(Value *addr, const TargetData *td) : Addr(addr), TD(td) { // If the address is an instruction, the whole thing is considered an input. if (Instruction *I = dyn_cast(Addr)) InstInputs.push_back(I); @@ -55,35 +58,44 @@ public: return false; } - /// IsPHITranslatable - If this needs PHI translation, return true if we have - /// some hope of doing it. This should be used as a filter to avoid calling - /// GetPHITranslatedValue in hopeless situations. - bool IsPHITranslatable() const; + /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true + /// if we have some hope of doing it. This should be used as a filter to + /// avoid calling PHITranslateValue in hopeless situations. + bool IsPotentiallyPHITranslatable() const; - /// GetPHITranslatedValue - Given a computation that satisfied the - /// isPHITranslatable predicate, see if we can translate the computation into - /// the specified predecessor block. If so, return that value, otherwise - /// return null. - Value *GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, - BasicBlock *Pred, const TargetData *TD) const; + /// PHITranslateValue - PHI translate the current address up the CFG from + /// CurBB to Pred, updating our state the reflect any needed changes. This + /// returns true on failure. + bool PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB); - /// GetAvailablePHITranslatePointer - Return the value computed by - /// PHITranslatePointer if it dominates PredBB, otherwise return null. - Value *GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const; + /// PHITranslateWithInsertion - PHI translate this value into the specified + /// predecessor block, inserting a computation of the value if it is + /// unavailable. + /// + /// All newly created instructions are added to the NewInsts list. This + /// returns null on failure. + /// + Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT, + SmallVectorImpl &NewInsts); +private: + Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); - /// InsertPHITranslatedPointer - Insert a computation of the PHI translated + + /// GetAvailablePHITranslatedSubExpr - Return the value computed by + /// PHITranslateSubExpr if it dominates PredBB, otherwise return null. + Value *GetAvailablePHITranslatedSubExpr(Value *V, + BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT); + + /// InsertPHITranslatedSubExpr - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// - Value *InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB, - BasicBlock *PredBB, const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl &NewInsts) const; - + Value *InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, + BasicBlock *PredBB, const DominatorTree &DT, + SmallVectorImpl &NewInsts); }; } // end namespace llvm diff --git a/lib/Analysis/PHITransAddr.cpp b/lib/Analysis/PHITransAddr.cpp index ce7eca5d27c..bdaaac1eaa1 100644 --- a/lib/Analysis/PHITransAddr.cpp +++ b/lib/Analysis/PHITransAddr.cpp @@ -13,36 +13,178 @@ #include "llvm/Analysis/PHITransAddr.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/InstructionSimplify.h" using namespace llvm; -/// IsPHITranslatable - If this needs PHI translation, return true if we have -/// some hope of doing it. This should be used as a filter to avoid calling -/// GetPHITranslatedValue in hopeless situations. -bool PHITransAddr::IsPHITranslatable() const { - return true; // not a good filter. +/// IsPotentiallyPHITranslatable - If this needs PHI translation, return true +/// if we have some hope of doing it. This should be used as a filter to +/// avoid calling PHITranslateValue in hopeless situations. +bool PHITransAddr::IsPotentiallyPHITranslatable() const { + // If the input value is not an instruction, or if it is not defined in CurBB, + // then we don't need to phi translate it. + Instruction *Inst = dyn_cast(Addr); + if (isa(Inst) || + isa(Inst) || + isa(Inst) || + (Inst->getOpcode() == Instruction::And && + isa(Inst->getOperand(1)))) + return true; + + // cerr << "MEMDEP: Could not PHI translate: " << *Pointer; + // if (isa(PtrInst) || isa(PtrInst)) + // cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0); + + return false; } -/// GetPHITranslatedValue - Given a computation that satisfied the -/// isPHITranslatable predicate, see if we can translate the computation into -/// the specified predecessor block. If so, return that value, otherwise -/// return null. -Value *PHITransAddr::GetPHITranslatedValue(Value *InVal, BasicBlock *CurBB, - BasicBlock *Pred, - const TargetData *TD) const { - // Not a great implementation. - return 0; + +Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, + BasicBlock *PredBB) { + // If this is a non-instruction value, it can't require PHI translation. + Instruction *Inst = dyn_cast(V); + if (Inst == 0) return V; + + // Determine whether 'Inst' is an input to our PHI translatable expression. + bool isInput = std::count(InstInputs.begin(), InstInputs.end(), Inst); + + // If 'Inst' is not defined in this block, it is either an input, or an + // intermediate result. + if (Inst->getParent() != CurBB) { + // If it is an input, then it remains an input. + if (isInput) + return Inst; + + // Otherwise, it must be an intermediate result. See if its operands need + // to be phi translated, and if so, reconstruct it. + + if (BitCastInst *BC = dyn_cast(Inst)) { + Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB); + if (PHIIn == 0) return 0; + if (PHIIn == BC->getOperand(0)) + return BC; + + // Find an available version of this cast. + + // Constants are trivial to find. + if (Constant *C = dyn_cast(PHIIn)) + return ConstantExpr::getBitCast(C, BC->getType()); + + // Otherwise we have to see if a bitcasted version of the incoming pointer + // is available. If so, we can use it, otherwise we have to fail. + for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end(); + UI != E; ++UI) { + if (BitCastInst *BCI = dyn_cast(*UI)) + if (BCI->getType() == BC->getType()) + return BCI; + } + return 0; + } + + // Handle getelementptr with at least one PHI translatable operand. + if (GetElementPtrInst *GEP = dyn_cast(Inst)) { + SmallVector GEPOps; + BasicBlock *CurBB = GEP->getParent(); + bool AnyChanged = false; + for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { + Value *GEPOp = PHITranslateSubExpr(GEP->getOperand(i), CurBB, PredBB); + if (GEPOp == 0) return 0; + + AnyChanged = GEPOp != GEP->getOperand(i); + GEPOps.push_back(GEPOp); + } + + if (!AnyChanged) + return GEP; + + // Simplify the GEP to handle 'gep x, 0' -> x etc. + if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD)) + return V; + + // Scan to see if we have this GEP available. + Value *APHIOp = GEPOps[0]; + for (Value::use_iterator UI = APHIOp->use_begin(), E = APHIOp->use_end(); + UI != E; ++UI) { + if (GetElementPtrInst *GEPI = dyn_cast(*UI)) + if (GEPI->getType() == GEP->getType() && + GEPI->getNumOperands() == GEPOps.size() && + GEPI->getParent()->getParent() == CurBB->getParent()) { + bool Mismatch = false; + for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) + if (GEPI->getOperand(i) != GEPOps[i]) { + Mismatch = true; + break; + } + if (!Mismatch) + return GEPI; + } + } + return 0; + } + + // Handle add with a constant RHS. + if (Inst->getOpcode() == Instruction::Add && + isa(Inst->getOperand(1))) { + // PHI translate the LHS. + Constant *RHS = cast(Inst->getOperand(1)); + bool isNSW = cast(Inst)->hasNoSignedWrap(); + bool isNUW = cast(Inst)->hasNoUnsignedWrap(); + + Value *LHS = PHITranslateSubExpr(Inst->getOperand(0), CurBB, PredBB); + if (LHS == 0) return 0; + + // If the PHI translated LHS is an add of a constant, fold the immediates. + if (BinaryOperator *BOp = dyn_cast(LHS)) + if (BOp->getOpcode() == Instruction::Add) + if (ConstantInt *CI = dyn_cast(BOp->getOperand(1))) { + LHS = BOp->getOperand(0); + RHS = ConstantExpr::getAdd(RHS, CI); + isNSW = isNUW = false; + } + + // See if the add simplifies away. + if (Value *Res = SimplifyAddInst(LHS, RHS, isNSW, isNUW, TD)) + return Res; + + // Otherwise, see if we have this add available somewhere. + for (Value::use_iterator UI = LHS->use_begin(), E = LHS->use_end(); + UI != E; ++UI) { + if (BinaryOperator *BO = dyn_cast(*UI)) + if (BO->getOperand(0) == LHS && BO->getOperand(1) == RHS && + BO->getParent()->getParent() == CurBB->getParent()) + return BO; + } + + return 0; + } + + // Otherwise, we failed. + return 0; + } + + // Otherwise, it is defined in this block. It must be an input and must be + // phi translated. + assert(isInput && "Instruction defined in block must be an input"); + + + abort(); // unimplemented so far. } -/// GetAvailablePHITranslatePointer - Return the value computed by -/// PHITranslatePointer if it dominates PredBB, otherwise return null. + +/// PHITranslateValue - PHI translate the current address up the CFG from +/// CurBB to Pred, updating our state the reflect any needed changes. This +/// returns true on failure. +bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) { + Addr = PHITranslateSubExpr(Addr, CurBB, PredBB); + return Addr == 0; +} + +/// GetAvailablePHITranslatedSubExpr - Return the value computed by +/// PHITranslateSubExpr if it dominates PredBB, otherwise return null. Value *PHITransAddr:: -GetAvailablePHITranslatedValue(Value *V, - BasicBlock *CurBB, BasicBlock *PredBB, - const TargetData *TD, - const DominatorTree &DT) const { +GetAvailablePHITranslatedSubExpr(Value *V, BasicBlock *CurBB,BasicBlock *PredBB, + const DominatorTree &DT) { // See if PHI translation succeeds. - V = GetPHITranslatedValue(V, CurBB, PredBB, TD); - if (V == 0) return 0; + V = PHITranslateSubExpr(V, CurBB, PredBB); // Make sure the value is live in the predecessor. if (Instruction *Inst = dyn_cast_or_null(V)) @@ -51,21 +193,107 @@ GetAvailablePHITranslatedValue(Value *V, return V; } + +/// PHITranslateWithInsertion - PHI translate this value into the specified +/// predecessor block, inserting a computation of the value if it is +/// unavailable. +/// +/// All newly created instructions are added to the NewInsts list. This +/// returns null on failure. +/// +Value *PHITransAddr:: +PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB, + const DominatorTree &DT, + SmallVectorImpl &NewInsts) { + unsigned NISize = NewInsts.size(); + + // Attempt to PHI translate with insertion. + Addr = InsertPHITranslatedSubExpr(Addr, CurBB, PredBB, DT, NewInsts); + + // If successful, return the new value. + if (Addr) return Addr; + + // If not, destroy any intermediate instructions inserted. + while (NewInsts.size() != NISize) + NewInsts.pop_back_val()->eraseFromParent(); + return 0; +} + + /// InsertPHITranslatedPointer - Insert a computation of the PHI translated /// version of 'V' for the edge PredBB->CurBB into the end of the PredBB /// block. All newly created instructions are added to the NewInsts list. /// This returns null on failure. /// Value *PHITransAddr:: -InsertPHITranslatedPointer(Value *InVal, BasicBlock *CurBB, - BasicBlock *PredBB, const TargetData *TD, - const DominatorTree &DT, - SmallVectorImpl &NewInsts) const { +InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, + BasicBlock *PredBB, const DominatorTree &DT, + SmallVectorImpl &NewInsts) { // See if we have a version of this value already available and dominating - // PredBB. If so, there is no need to insert a new copy. - if (Value *Res = GetAvailablePHITranslatedValue(InVal, CurBB, PredBB, TD, DT)) + // PredBB. If so, there is no need to insert a new instance of it. + if (Value *Res = GetAvailablePHITranslatedSubExpr(InVal, CurBB, PredBB, DT)) return Res; - // Not a great implementation. + // If we don't have an available version of this value, it must be an + // instruction. + Instruction *Inst = cast(InVal); + + // Handle bitcast of PHI translatable value. + if (BitCastInst *BC = dyn_cast(Inst)) { + Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0), + CurBB, PredBB, DT, NewInsts); + if (OpVal == 0) return 0; + + // Otherwise insert a bitcast at the end of PredBB. + BitCastInst *New = new BitCastInst(OpVal, InVal->getType(), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); + NewInsts.push_back(New); + return New; + } + + // Handle getelementptr with at least one PHI operand. + if (GetElementPtrInst *GEP = dyn_cast(Inst)) { + SmallVector GEPOps; + BasicBlock *CurBB = GEP->getParent(); + for (unsigned i = 0, e = GEP->getNumOperands(); i != e; ++i) { + Value *OpVal = InsertPHITranslatedSubExpr(GEP->getOperand(i), + CurBB, PredBB, DT, NewInsts); + if (OpVal == 0) return 0; + GEPOps.push_back(OpVal); + } + + GetElementPtrInst *Result = + GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); + Result->setIsInBounds(GEP->isInBounds()); + NewInsts.push_back(Result); + return Result; + } + +#if 0 + // FIXME: This code works, but it is unclear that we actually want to insert + // a big chain of computation in order to make a value available in a block. + // This needs to be evaluated carefully to consider its cost trade offs. + + // Handle add with a constant RHS. + if (Inst->getOpcode() == Instruction::Add && + isa(Inst->getOperand(1))) { + // PHI translate the LHS. + Value *OpVal = InsertPHITranslatedSubExpr(Inst->getOperand(0), + CurBB, PredBB, DT, NewInsts); + if (OpVal == 0) return 0; + + BinaryOperator *Res = BinaryOperator::CreateAdd(OpVal, Inst->getOperand(1), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); + Res->setHasNoSignedWrap(cast(Inst)->hasNoSignedWrap()); + Res->setHasNoUnsignedWrap(cast(Inst)->hasNoUnsignedWrap()); + NewInsts.push_back(Res); + return Res; + } +#endif + return 0; }