aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/ConstantFolding.cpp40
-rw-r--r--lib/Analysis/DebugInfo.cpp32
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 << "] ";