mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-23 12:08:25 +00:00
move another load optimization from instcombine -> libanalysis.
llvm-svn: 84841
This commit is contained in:
parent
3fb4c19b7d
commit
cd80b1711b
@ -103,45 +103,59 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,
|
||||
if (GV->isConstant() && GV->hasDefinitiveInitializer())
|
||||
return GV->getInitializer();
|
||||
|
||||
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
|
||||
if (CE->getOpcode() == Instruction::GetElementPtr) {
|
||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(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
|
||||
// directly if string length is small enough.
|
||||
std::string Str;
|
||||
if (TD && GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) {
|
||||
unsigned len = Str.length();
|
||||
const Type *Ty = cast<PointerType>(CE->getType())->getElementType();
|
||||
unsigned numBits = Ty->getPrimitiveSizeInBits();
|
||||
// Replace LI with immediate integer store.
|
||||
if ((numBits >> 3) == len + 1) {
|
||||
APInt StrVal(numBits, 0);
|
||||
APInt SingleChar(numBits, 0);
|
||||
if (TD->isLittleEndian()) {
|
||||
for (signed i = len-1; i >= 0; i--) {
|
||||
SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
|
||||
StrVal = (StrVal << 8) | SingleChar;
|
||||
}
|
||||
} 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;
|
||||
// If the loaded value isn't a constant expr, we can't handle it.
|
||||
ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
|
||||
if (!CE) return 0;
|
||||
|
||||
if (CE->getOpcode() == Instruction::GetElementPtr) {
|
||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(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
|
||||
// directly if string length is small enough.
|
||||
std::string Str;
|
||||
if (TD && GetConstantStringInfo(CE->getOperand(0), Str) && !Str.empty()) {
|
||||
unsigned len = Str.length();
|
||||
const Type *Ty = cast<PointerType>(CE->getType())->getElementType();
|
||||
unsigned numBits = Ty->getPrimitiveSizeInBits();
|
||||
// Replace LI with immediate integer store.
|
||||
if ((numBits >> 3) == len + 1) {
|
||||
APInt StrVal(numBits, 0);
|
||||
APInt SingleChar(numBits, 0);
|
||||
if (TD->isLittleEndian()) {
|
||||
for (signed i = len-1; i >= 0; i--) {
|
||||
SingleChar = (uint64_t) Str[i] & UCHAR_MAX;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -11364,7 +11364,8 @@ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI,
|
||||
if (Constant *CSrc = dyn_cast<Constant>(CastOp))
|
||||
if (ASrcTy->getNumElements() != 0) {
|
||||
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);
|
||||
SrcTy = cast<PointerType>(CastOp->getType());
|
||||
SrcPTy = SrcTy->getElementType();
|
||||
@ -11453,17 +11454,6 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
|
||||
if (Instruction *Res = InstCombineLoadCast(*this, LI, TD))
|
||||
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()) {
|
||||
// Change select and PHI nodes to select values instead of addresses: this
|
||||
// helps alias analysis out a lot, allows many others simplifications, and
|
||||
|
Loading…
Reference in New Issue
Block a user