diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 40 | ||||
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 32 |
2 files changed, 37 insertions, 35 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index ac2670a163..7c99325b2d 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -16,6 +16,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" #include "llvm/ADT/SmallVector.h" @@ -383,12 +384,43 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, // the int size is >= the ptr size. This requires knowing the width of a // pointer, so it can't be done in ConstantExpr::getCast. if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ops[0])) { - if (TD && CE->getOpcode() == Instruction::PtrToInt && + if (TD && TD->getPointerSizeInBits() <= CE->getType()->getPrimitiveSizeInBits()) { - Constant *Input = CE->getOperand(0); - Constant *C = FoldBitCast(Input, DestTy, *TD); - return C ? C : ConstantExpr::getBitCast(Input, DestTy); + if (CE->getOpcode() == Instruction::PtrToInt) { + Constant *Input = CE->getOperand(0); + Constant *C = FoldBitCast(Input, DestTy, *TD); + return C ? C : ConstantExpr::getBitCast(Input, DestTy); + } + // If there's a constant offset added to the integer value before + // it is casted back to a pointer, see if the expression can be + // converted into a GEP. + if (CE->getOpcode() == Instruction::Add) + if (ConstantInt *L = dyn_cast<ConstantInt>(CE->getOperand(0))) + if (ConstantExpr *R = dyn_cast<ConstantExpr>(CE->getOperand(1))) + if (R->getOpcode() == Instruction::PtrToInt) + if (GlobalVariable *GV = + dyn_cast<GlobalVariable>(R->getOperand(0))) { + const PointerType *GVTy = cast<PointerType>(GV->getType()); + if (const ArrayType *AT = + dyn_cast<ArrayType>(GVTy->getElementType())) { + const Type *ElTy = AT->getElementType(); + uint64_t PaddedSize = TD->getTypePaddedSize(ElTy); + APInt PSA(L->getValue().getBitWidth(), PaddedSize); + if (ElTy == cast<PointerType>(DestTy)->getElementType() && + L->getValue().urem(PSA) == 0) { + APInt ElemIdx = L->getValue().udiv(PSA); + if (ElemIdx.ult(APInt(ElemIdx.getBitWidth(), + AT->getNumElements()))) { + Constant *Index[] = { + Constant::getNullValue(CE->getType()), + ConstantInt::get(ElemIdx) + }; + return ConstantExpr::getGetElementPtr(GV, &Index[0], 2); + } + } + } + } } } return ConstantExpr::getCast(Opcode, Ops[0], DestTy); diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 4e398f27c1..181f3e9eff 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -59,9 +59,6 @@ bool DIDescriptor::ValidDebugInfo(Value *V, CodeGenOpt::Level OptLevel) { case DW_TAG_subprogram: assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value"); break; - case DW_TAG_inlined_subroutine: - assert(DIInlinedSubprogram(GV).Verify() && "Invalid DebugInfo value"); - break; case DW_TAG_lexical_block: /// FIXME. This interfers with the quality of generated code when /// during optimization. @@ -149,8 +146,6 @@ DIBasicType::DIBasicType(GlobalVariable *GV) : DIType(GV, dwarf::DW_TAG_base_type) {} DISubprogram::DISubprogram(GlobalVariable *GV) : DIGlobal(GV, dwarf::DW_TAG_subprogram) {} -DIInlinedSubprogram::DIInlinedSubprogram(GlobalVariable *GV) - : DIGlobal(GV, dwarf::DW_TAG_inlined_subroutine) {} DIGlobalVariable::DIGlobalVariable(GlobalVariable *GV) : DIGlobal(GV, dwarf::DW_TAG_variable) {} DIBlock::DIBlock(GlobalVariable *GV) @@ -291,25 +286,6 @@ bool DISubprogram::Verify() const { return true; } -/// Verify - Verify that an inlined subprogram descriptor is well formed. -bool DIInlinedSubprogram::Verify() const { - if (isNull()) - return false; - - if (getContext().isNull()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) - return false; - - DICompositeType Ty = getType(); - if (!Ty.isNull() && !Ty.Verify()) - return false; - - return true; -} - /// Verify - Verify that a global variable descriptor is well formed. bool DIGlobalVariable::Verify() const { if (isNull()) @@ -1007,8 +983,7 @@ namespace llvm { /// dump - print descriptor. void DIDescriptor::dump() const { - cerr << "[" << dwarf::TagString(getTag()) << "] "; - cerr << std::hex << "[GV:" << GV << "]" << std::dec; + cerr << " [" << dwarf::TagString(getTag()) << "]\n"; } /// dump - print compile unit. @@ -1110,11 +1085,6 @@ void DISubprogram::dump() const { DIGlobal::dump(); } -/// dump - print subprogram. -void DIInlinedSubprogram::dump() const { - DIGlobal::dump(); -} - /// dump - print global variable. void DIGlobalVariable::dump() const { cerr << " ["; getGlobal()->dump(); cerr << "] "; |