move another load optimization from instcombine -> libanalysis.

llvm-svn: 84841
This commit is contained in:
Chris Lattner 2009-10-22 06:44:07 +00:00
parent 51d2f70e32
commit cf7e8947e9
2 changed files with 50 additions and 46 deletions

View File

@ -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);
} }
} }

View File

@ -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