diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ConstantFolding.cpp | 73 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/Evaluator.cpp | 34 |
2 files changed, 61 insertions, 46 deletions
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index ace7131e7d5..c778438aec2 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -320,6 +320,41 @@ bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, return true; } +Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy, + const DataLayout &DL) { + do { + Type *SrcTy = C->getType(); + + // If the type sizes are the same and a cast is legal, just directly + // cast the constant. + if (DL.getTypeSizeInBits(DestTy) == DL.getTypeSizeInBits(SrcTy)) { + Instruction::CastOps Cast = Instruction::BitCast; + // If we are going from a pointer to int or vice versa, we spell the cast + // differently. + if (SrcTy->isIntegerTy() && DestTy->isPointerTy()) + Cast = Instruction::IntToPtr; + else if (SrcTy->isPointerTy() && DestTy->isIntegerTy()) + Cast = Instruction::PtrToInt; + + if (CastInst::castIsValid(Cast, C, DestTy)) + return ConstantExpr::getCast(Cast, C, DestTy); + } + + // If this isn't an aggregate type, there is nothing we can do to drill down + // and find a bitcastable constant. + if (!SrcTy->isAggregateType()) + return nullptr; + + // We're simulating a load through a pointer that was bitcast to point to + // a different type, so we can try to walk down through the initial + // elements of an aggregate to see if some part of th e aggregate is + // castable to implement the "load" semantic model. + C = C->getAggregateElement(0u); + } while (C); + + return nullptr; +} + namespace { /// Recursive helper to read bits out of global. C is the constant being copied @@ -537,8 +572,8 @@ Constant *FoldReinterpretLoadFromConstPtr(Constant *C, Type *LoadTy, return ConstantInt::get(IntType->getContext(), ResultVal); } -Constant *ConstantFoldLoadThroughBitcast(ConstantExpr *CE, Type *DestTy, - const DataLayout &DL) { +Constant *ConstantFoldLoadThroughBitcastExpr(ConstantExpr *CE, Type *DestTy, + const DataLayout &DL) { auto *SrcPtr = CE->getOperand(0); auto *SrcPtrTy = dyn_cast<PointerType>(SrcPtr->getType()); if (!SrcPtrTy) @@ -549,37 +584,7 @@ Constant *ConstantFoldLoadThroughBitcast(ConstantExpr *CE, Type *DestTy, if (!C) return nullptr; - do { - Type *SrcTy = C->getType(); - - // If the type sizes are the same and a cast is legal, just directly - // cast the constant. - if (DL.getTypeSizeInBits(DestTy) == DL.getTypeSizeInBits(SrcTy)) { - Instruction::CastOps Cast = Instruction::BitCast; - // If we are going from a pointer to int or vice versa, we spell the cast - // differently. - if (SrcTy->isIntegerTy() && DestTy->isPointerTy()) - Cast = Instruction::IntToPtr; - else if (SrcTy->isPointerTy() && DestTy->isIntegerTy()) - Cast = Instruction::PtrToInt; - - if (CastInst::castIsValid(Cast, C, DestTy)) - return ConstantExpr::getCast(Cast, C, DestTy); - } - - // If this isn't an aggregate type, there is nothing we can do to drill down - // and find a bitcastable constant. - if (!SrcTy->isAggregateType()) - return nullptr; - - // We're simulating a load through a pointer that was bitcast to point to - // a different type, so we can try to walk down through the initial - // elements of an aggregate to see if some part of th e aggregate is - // castable to implement the "load" semantic model. - C = C->getAggregateElement(0u); - } while (C); - - return nullptr; + return llvm::ConstantFoldLoadThroughBitcast(C, DestTy, DL); } } // end anonymous namespace @@ -611,7 +616,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, } if (CE->getOpcode() == Instruction::BitCast) - if (Constant *LoadedC = ConstantFoldLoadThroughBitcast(CE, Ty, DL)) + if (Constant *LoadedC = ConstantFoldLoadThroughBitcastExpr(CE, Ty, DL)) return LoadedC; // Instead of loading constant c string, use corresponding integer value diff --git a/llvm/lib/Transforms/Utils/Evaluator.cpp b/llvm/lib/Transforms/Utils/Evaluator.cpp index 3c5e299fae9..51fc423546d 100644 --- a/llvm/lib/Transforms/Utils/Evaluator.cpp +++ b/llvm/lib/Transforms/Utils/Evaluator.cpp @@ -174,6 +174,11 @@ static bool isSimpleEnoughPointerToCommit(Constant *C) { return false; } +static Constant *getInitializer(Constant *C) { + auto *GV = dyn_cast<GlobalVariable>(C); + return GV && GV->hasDefinitiveInitializer() ? GV->getInitializer() : nullptr; +} + /// Return the value that would be computed by a load from P after the stores /// reflected by 'memory' have been performed. If we can't decide, return null. Constant *Evaluator::ComputeLoadResult(Constant *P) { @@ -189,14 +194,21 @@ Constant *Evaluator::ComputeLoadResult(Constant *P) { return nullptr; } - // Handle a constantexpr getelementptr. - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(P)) - if (CE->getOpcode() == Instruction::GetElementPtr && - isa<GlobalVariable>(CE->getOperand(0))) { - GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0)); - if (GV->hasDefinitiveInitializer()) - return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE); + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(P)) { + switch (CE->getOpcode()) { + // Handle a constantexpr getelementptr. + case Instruction::GetElementPtr: + if (auto *I = getInitializer(CE->getOperand(0))) + return ConstantFoldLoadThroughGEPConstantExpr(I, CE); + break; + // Handle a constantexpr bitcast. + case Instruction::BitCast: + if (auto *I = getInitializer(CE->getOperand(0))) + return ConstantFoldLoadThroughBitcast( + I, P->getType()->getPointerElementType(), DL); + break; } + } return nullptr; // don't know how to evaluate. } @@ -252,7 +264,8 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, // In order to push the bitcast onto the stored value, a bitcast // from NewTy to Val's type must be legal. If it's not, we can try // introspecting NewTy to find a legal conversion. - while (!Val->getType()->canLosslesslyBitCastTo(NewTy)) { + Constant *NewVal; + while (!(NewVal = ConstantFoldLoadThroughBitcast(Val, NewTy, DL))) { // If NewTy is a struct, we can convert the pointer to the struct // into a pointer to its first member. // FIXME: This could be extended to support arrays as well. @@ -276,10 +289,7 @@ bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, } } - // If we found compatible types, go ahead and push the bitcast - // onto the stored value. - Val = ConstantExpr::getBitCast(Val, NewTy); - + Val = NewVal; DEBUG(dbgs() << "Evaluated bitcast: " << *Val << "\n"); } } |