move another load optimization from instcombine -> libanalysis.
llvm-svn: 84841
This commit is contained in:
parent
51d2f70e32
commit
cf7e8947e9
|
@ -103,42 +103,56 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,
|
||||||
if (GV->isConstant() && GV->hasDefinitiveInitializer())
|
if (GV->isConstant() && GV->hasDefinitiveInitializer())
|
||||||
return GV->getInitializer();
|
return GV->getInitializer();
|
||||||
|
|
||||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
|
// If the loaded value isn't a constant expr, we can't handle it.
|
||||||
if (CE->getOpcode() == Instruction::GetElementPtr) {
|
ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
|
||||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
|
if (!CE) return 0;
|
||||||
if (GV->isConstant() && GV->hasDefinitiveInitializer())
|
|
||||||
if (Constant *V =
|
|
||||||
ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE))
|
|
||||||
return V;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instead of loading constant c string, use corresponding integer value
|
if (CE->getOpcode() == Instruction::GetElementPtr) {
|
||||||
// directly if string length is small enough.
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
|
||||||
std::string Str;
|
if (GV->isConstant() && GV->hasDefinitiveInitializer())
|
||||||
if (TD && GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) {
|
if (Constant *V =
|
||||||
unsigned len = Str.length();
|
ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE))
|
||||||
const Type *Ty = cast<PointerType>(CE->getType())->getElementType();
|
return V;
|
||||||
unsigned numBits = Ty->getPrimitiveSizeInBits();
|
}
|
||||||
// Replace LI with immediate integer store.
|
|
||||||
if ((numBits >> 3) == len + 1) {
|
// Instead of loading constant c string, use corresponding integer value
|
||||||
APInt StrVal(numBits, 0);
|
// directly if string length is small enough.
|
||||||
APInt SingleChar(numBits, 0);
|
std::string Str;
|
||||||
if (TD->isLittleEndian()) {
|
if (TD && GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) {
|
||||||
for (signed i = len-1; i >= 0; i--) {
|
unsigned len = Str.length();
|
||||||
SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
|
const Type *Ty = cast<PointerType>(CE->getType())->getElementType();
|
||||||
StrVal = (StrVal << 8) | SingleChar;
|
unsigned numBits = Ty->getPrimitiveSizeInBits();
|
||||||
}
|
// Replace LI with immediate integer store.
|
||||||
} else {
|
if ((numBits >> 3) == len + 1) {
|
||||||
for (unsigned i = 0; i < len; i++) {
|
APInt StrVal(numBits, 0);
|
||||||
SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
|
APInt SingleChar(numBits, 0);
|
||||||
StrVal = (StrVal << 8) | SingleChar;
|
if (TD->isLittleEndian()) {
|
||||||
}
|
for (signed i = len-1; i >= 0; i--) {
|
||||||
// Append NULL at the end.
|
SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
|
||||||
SingleChar = 0;
|
|
||||||
StrVal = (StrVal << 8) | SingleChar;
|
StrVal = (StrVal << 8) | SingleChar;
|
||||||
}
|
}
|
||||||
return ConstantInt::get(CE->getContext(), StrVal);
|
} else {
|
||||||
|
for (unsigned i = 0; i < len; i++) {
|
||||||
|
SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
|
||||||
|
StrVal = (StrVal << 8) | SingleChar;
|
||||||
|
}
|
||||||
|
// Append NULL at the end.
|
||||||
|
SingleChar = 0;
|
||||||
|
StrVal = (StrVal << 8) | SingleChar;
|
||||||
}
|
}
|
||||||
|
return ConstantInt::get(CE->getContext(), StrVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this load comes from anywhere in a constant global, and if the global
|
||||||
|
// is all undef or zero, we know what it loads.
|
||||||
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getUnderlyingObject())){
|
||||||
|
if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
|
||||||
|
const Type *ResTy = cast<PointerType>(C->getType())->getElementType();
|
||||||
|
if (GV->getInitializer()->isNullValue())
|
||||||
|
return Constant::getNullValue(ResTy);
|
||||||
|
if (isa<UndefValue>(GV->getInitializer()))
|
||||||
|
return UndefValue::get(ResTy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11364,7 +11364,8 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
|
||||||
if (Constant *CSrc = dyn_cast<Constant>(CastOp))
|
if (Constant *CSrc = dyn_cast<Constant>(CastOp))
|
||||||
if (ASrcTy->getNumElements() != 0) {
|
if (ASrcTy->getNumElements() != 0) {
|
||||||
Value *Idxs[2];
|
Value *Idxs[2];
|
||||||
Idxs[0] = Idxs[1] = Constant::getNullValue(Type::getInt32Ty(*Context));
|
Idxs[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
|
||||||
|
Idxs[1] = Idxs[0];
|
||||||
CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs, 2);
|
CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs, 2);
|
||||||
SrcTy = cast<PointerType>(CastOp->getType());
|
SrcTy = cast<PointerType>(CastOp->getType());
|
||||||
SrcPTy = SrcTy->getElementType();
|
SrcPTy = SrcTy->getElementType();
|
||||||
|
@ -11453,17 +11454,6 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
||||||
if (Instruction *Res = InstCombineLoadCast(*this, LI, TD))
|
if (Instruction *Res = InstCombineLoadCast(*this, LI, TD))
|
||||||
return Res;
|
return Res;
|
||||||
|
|
||||||
// If this load comes from anywhere in a constant global, and if the global
|
|
||||||
// is all undef or zero, we know what it loads.
|
|
||||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op->getUnderlyingObject())){
|
|
||||||
if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
|
|
||||||
if (GV->getInitializer()->isNullValue())
|
|
||||||
return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType()));
|
|
||||||
else if (isa<UndefValue>(GV->getInitializer()))
|
|
||||||
return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Op->hasOneUse()) {
|
if (Op->hasOneUse()) {
|
||||||
// Change select and PHI nodes to select values instead of addresses: this
|
// Change select and PHI nodes to select values instead of addresses: this
|
||||||
// helps alias analysis out a lot, allows many others simplifications, and
|
// helps alias analysis out a lot, allows many others simplifications, and
|
||||||
|
|
Loading…
Reference in New Issue