1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

ConvertibleToGEP always returns 0, remove some old crufty code which

is actually dead because of this!

llvm-svn: 22515
This commit is contained in:
Chris Lattner 2005-07-26 16:38:28 +00:00
parent dd4417e8f9
commit 1b22c180d7
4 changed files with 0 additions and 369 deletions

View File

@ -252,32 +252,6 @@ bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty,
if (ElTy) break; // Found a number of zeros we can strip off!
// Otherwise, we can convert a GEP from one form to the other iff the
// current gep is of the form 'getelementptr sbyte*, long N
// and we could convert this to an appropriate GEP for the new type.
//
if (GEP->getNumOperands() == 2 &&
GEP->getType() == PointerType::get(Type::SByteTy)) {
// Do not Check to see if our incoming pointer can be converted
// to be a ptr to an array of the right type... because in more cases than
// not, it is simply not analyzable because of pointer/array
// discrepancies. To fix this, we will insert a cast before the GEP.
//
// Check to see if 'N' is an expression that can be converted to
// the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(PTy, I->getOperand(1), Indices, TD);
if (ElTy == PVTy) {
if (!ExpressionConvertibleToType(I->getOperand(0),
PointerType::get(ElTy), CTMap, TD))
return false; // Can't continue, ExConToTy might have polluted set!
break;
}
}
// Otherwise, it could be that we have something like this:
// getelementptr [[sbyte] *] * %reg115, long %reg138 ; [sbyte]**
// and want to convert it into something like this:
@ -459,32 +433,6 @@ Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty,
}
}
if (Res == 0 && GEP->getNumOperands() == 2 &&
GEP->getType() == PointerType::get(Type::SByteTy)) {
// Otherwise, we can convert a GEP from one form to the other iff the
// current gep is of the form 'getelementptr sbyte*, unsigned N
// and we could convert this to an appropriate GEP for the new type.
//
const PointerType *NewSrcTy = PointerType::get(PVTy);
BasicBlock::iterator It = I;
// Check to see if 'N' is an expression that can be converted to
// the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(NewSrcTy, I->getOperand(1),
Indices, TD, &It);
if (ElTy) {
assert(ElTy == PVTy && "Internal error, setup wrong!");
Res = new GetElementPtrInst(Constant::getNullValue(NewSrcTy),
Indices, Name);
VMC.ExprMap[I] = Res;
Res->setOperand(0, ConvertExpressionToType(I->getOperand(0),
NewSrcTy, VMC, TD));
}
}
// Otherwise, it could be that we have something like this:
// getelementptr [[sbyte] *] * %reg115, uint %reg138 ; [sbyte]**
// and want to convert it into something like this:
@ -637,23 +585,6 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
return true;
case Instruction::Add:
if (isa<PointerType>(Ty)) {
Value *IndexVal = I->getOperand(V == I->getOperand(0) ? 1 : 0);
std::vector<Value*> Indices;
if (const Type *ETy = ConvertibleToGEP(Ty, IndexVal, Indices, TD)) {
const Type *RetTy = PointerType::get(ETy);
// Only successful if we can convert this type to the required type
if (ValueConvertibleToType(I, RetTy, CTMap, TD)) {
CTMap[I] = RetTy;
return true;
}
// We have to return failure here because ValueConvertibleToType could
// have polluted our map
return false;
}
}
// FALLTHROUGH
case Instruction::Sub: {
if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false;
@ -780,47 +711,6 @@ static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
return false;
}
case Instruction::GetElementPtr:
if (V != I->getOperand(0) || !isa<PointerType>(Ty)) return false;
// If we have a two operand form of getelementptr, this is really little
// more than a simple addition. As with addition, check to see if the
// getelementptr instruction can be changed to index into the new type.
//
if (I->getNumOperands() == 2) {
const Type *OldElTy = cast<PointerType>(I->getType())->getElementType();
uint64_t DataSize = TD.getTypeSize(OldElTy);
Value *Index = I->getOperand(1);
Instruction *TempScale = 0;
// If the old data element is not unit sized, we have to create a scale
// instruction so that ConvertibleToGEP will know the REAL amount we are
// indexing by. Note that this is never inserted into the instruction
// stream, so we have to delete it when we're done.
//
if (DataSize != 1) {
Value *CST;
if (Index->getType()->isSigned())
CST = ConstantSInt::get(Index->getType(), DataSize);
else
CST = ConstantUInt::get(Index->getType(), DataSize);
TempScale = BinaryOperator::create(Instruction::Mul, Index, CST);
Index = TempScale;
}
// Check to see if the second argument is an expression that can
// be converted to the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(Ty, Index, Indices, TD);
delete TempScale; // Free our temporary multiply if we made it
if (ElTy == 0) return false; // Cannot make conversion...
return ValueConvertibleToType(I, PointerType::get(ElTy), CTMap, TD);
}
return false;
case Instruction::PHI: {
PHINode *PN = cast<PHINode>(I);
// Be conservative if we find a giant PHI node.
@ -964,23 +854,6 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
break;
case Instruction::Add:
if (isa<PointerType>(NewTy)) {
Value *IndexVal = I->getOperand(OldVal == I->getOperand(0) ? 1 : 0);
std::vector<Value*> Indices;
BasicBlock::iterator It = I;
if (const Type *ETy = ConvertibleToGEP(NewTy, IndexVal, Indices, TD,&It)){
// If successful, convert the add to a GEP
//const Type *RetTy = PointerType::get(ETy);
// First operand is actually the given pointer...
Res = new GetElementPtrInst(NewVal, Indices, Name);
assert(cast<PointerType>(Res->getType())->getElementType() == ETy &&
"ConvertibleToGEP broken!");
break;
}
}
// FALLTHROUGH
case Instruction::Sub:
case Instruction::SetEQ:
case Instruction::SetNE: {
@ -1102,64 +975,6 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
break;
}
case Instruction::GetElementPtr: {
// Convert a one index getelementptr into just about anything that is
// desired.
//
BasicBlock::iterator It = I;
const Type *OldElTy = cast<PointerType>(I->getType())->getElementType();
uint64_t DataSize = TD.getTypeSize(OldElTy);
Value *Index = I->getOperand(1);
if (DataSize != 1) {
// Insert a multiply of the old element type is not a unit size...
Value *CST;
if (Index->getType()->isSigned())
CST = ConstantSInt::get(Index->getType(), DataSize);
else
CST = ConstantUInt::get(Index->getType(), DataSize);
Index = BinaryOperator::create(Instruction::Mul, Index, CST, "scale", It);
}
// Perform the conversion now...
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(NewVal->getType(),Index,Indices,TD,&It);
assert(ElTy != 0 && "GEP Conversion Failure!");
Res = new GetElementPtrInst(NewVal, Indices, Name);
assert(Res->getType() == PointerType::get(ElTy) &&
"ConvertibleToGet failed!");
}
#if 0
if (I->getType() == PointerType::get(Type::SByteTy)) {
// Convert a getelementptr sbyte * %reg111, uint 16 freely back to
// anything that is a pointer type...
//
BasicBlock::iterator It = I;
// Check to see if the second argument is an expression that can
// be converted to the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
const Type *ElTy = ConvertibleToGEP(NewVal->getType(), I->getOperand(1),
Indices, TD, &It);
assert(ElTy != 0 && "GEP Conversion Failure!");
Res = new GetElementPtrInst(NewVal, Indices, Name);
} else {
// Convert a getelementptr ulong * %reg123, uint %N
// to getelementptr long * %reg123, uint %N
// ... where the type must simply stay the same size...
//
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
std::vector<Value*> Indices(GEP->idx_begin(), GEP->idx_end());
Res = new GetElementPtrInst(NewVal, Indices, Name);
}
#endif
break;
case Instruction::PHI: {
PHINode *OldPN = cast<PHINode>(I);
PHINode *NewPN = new PHINode(NewTy, Name);

View File

@ -96,143 +96,6 @@ static inline bool isReinterpretingCast(const CastInst *CI) {
return!CI->getOperand(0)->getType()->isLosslesslyConvertibleTo(CI->getType());
}
// Peephole optimize the following instructions:
// %t1 = cast ? to x *
// %t2 = add x * %SP, %t1 ;; Constant must be 2nd operand
//
// Into: %t3 = getelementptr {<...>} * %SP, <element indices>
// %t2 = cast <eltype> * %t3 to {<...>}*
//
static bool HandleCastToPointer(BasicBlock::iterator BI,
const PointerType *DestPTy,
const TargetData &TD) {
CastInst &CI = cast<CastInst>(*BI);
if (CI.use_empty()) return false;
// Scan all of the uses, looking for any uses that are not add or sub
// instructions. If we have non-adds, do not make this transformation.
//
bool HasSubUse = false; // Keep track of any subtracts...
for (Value::use_iterator I = CI.use_begin(), E = CI.use_end();
I != E; ++I)
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*I)) {
if ((BO->getOpcode() != Instruction::Add &&
BO->getOpcode() != Instruction::Sub) ||
// Avoid add sbyte* %X, %X cases...
BO->getOperand(0) == BO->getOperand(1))
return false;
else
HasSubUse |= BO->getOpcode() == Instruction::Sub;
} else {
return false;
}
std::vector<Value*> Indices;
Value *Src = CI.getOperand(0);
const Type *Result = ConvertibleToGEP(DestPTy, Src, Indices, TD, &BI);
if (Result == 0) return false; // Not convertible...
// Cannot handle subtracts if there is more than one index required...
if (HasSubUse && Indices.size() != 1) return false;
PRINT_PEEPHOLE2("cast-add-to-gep:in", *Src, CI);
// If we have a getelementptr capability... transform all of the
// add instruction uses into getelementptr's.
while (!CI.use_empty()) {
BinaryOperator *I = cast<BinaryOperator>(*CI.use_begin());
assert((I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Sub) &&
"Use is not a valid add instruction!");
// Get the value added to the cast result pointer...
Value *OtherPtr = I->getOperand((I->getOperand(0) == &CI) ? 1 : 0);
Instruction *GEP = new GetElementPtrInst(OtherPtr, Indices, I->getName());
PRINT_PEEPHOLE1("cast-add-to-gep:i", *I);
// If the instruction is actually a subtract, we are guaranteed to only have
// one index (from code above), so we just need to negate the pointer index
// long value.
if (I->getOpcode() == Instruction::Sub) {
Instruction *Neg = BinaryOperator::createNeg(GEP->getOperand(1),
GEP->getOperand(1)->getName()+".neg", I);
GEP->setOperand(1, Neg);
}
if (GEP->getType() == I->getType()) {
// Replace the old add instruction with the shiny new GEP inst
ReplaceInstWithInst(I, GEP);
} else {
// If the type produced by the gep instruction differs from the original
// add instruction type, insert a cast now.
//
// Insert the GEP instruction before the old add instruction...
I->getParent()->getInstList().insert(I, GEP);
PRINT_PEEPHOLE1("cast-add-to-gep:o", *GEP);
GEP = new CastInst(GEP, I->getType());
// Replace the old add instruction with the shiny new GEP inst
ReplaceInstWithInst(I, GEP);
}
PRINT_PEEPHOLE1("cast-add-to-gep:o", *GEP);
}
return true;
}
// Peephole optimize the following instructions:
// %t1 = cast ulong <const int> to {<...>} *
// %t2 = add {<...>} * %SP, %t1 ;; Constant must be 2nd operand
//
// or
// %t1 = cast {<...>}* %SP to int*
// %t5 = cast ulong <const int> to int*
// %t2 = add int* %t1, %t5 ;; int is same size as field
//
// Into: %t3 = getelementptr {<...>} * %SP, <element indices>
// %t2 = cast <eltype> * %t3 to {<...>}*
//
static bool PeepholeOptimizeAddCast(BasicBlock *BB, BasicBlock::iterator &BI,
Value *AddOp1, CastInst *AddOp2,
const TargetData &TD) {
const CompositeType *CompTy;
Value *OffsetVal = AddOp2->getOperand(0);
Value *SrcPtr = 0; // Of type pointer to struct...
if ((CompTy = getPointedToComposite(AddOp1->getType()))) {
SrcPtr = AddOp1; // Handle the first case...
} else if (CastInst *AddOp1c = dyn_cast<CastInst>(AddOp1)) {
SrcPtr = AddOp1c->getOperand(0); // Handle the second case...
CompTy = getPointedToComposite(SrcPtr->getType());
}
// Only proceed if we have detected all of our conditions successfully...
if (!CompTy || !SrcPtr || !OffsetVal->getType()->isInteger())
return false;
std::vector<Value*> Indices;
if (!ConvertibleToGEP(SrcPtr->getType(), OffsetVal, Indices, TD, &BI))
return false; // Not convertible... perhaps next time
if (getPointedToComposite(AddOp1->getType())) { // case 1
PRINT_PEEPHOLE2("add-to-gep1:in", *AddOp2, *BI);
} else {
PRINT_PEEPHOLE3("add-to-gep2:in", *AddOp1, *AddOp2, *BI);
}
GetElementPtrInst *GEP = new GetElementPtrInst(SrcPtr, Indices,
AddOp2->getName(), BI);
Instruction *NCI = new CastInst(GEP, AddOp1->getType());
ReplaceInstWithInst(BB->getInstList(), BI, NCI);
PRINT_PEEPHOLE2("add-to-gep:out", *GEP, *NCI);
return true;
}
bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
Instruction *I = BI;
const TargetData &TD = getAnalysis<TargetData>();
@ -321,18 +184,6 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
}
}
// Otherwise find out it this cast is a cast to a pointer type, which is
// then added to some other pointer, then loaded or stored through. If
// so, convert the add into a getelementptr instruction...
//
if (const PointerType *DestPTy = dyn_cast<PointerType>(DestTy)) {
if (HandleCastToPointer(BI, DestPTy, TD)) {
BI = BB->begin(); // Rescan basic block. BI might be invalidated.
++NumGEPInstFormed;
return true;
}
}
// Check to see if we are casting from a structure pointer to a pointer to
// the first element of the structure... to avoid munching other peepholes,
// we only let this happen if there are no add uses of the cast.
@ -494,14 +345,6 @@ bool RPR::PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) {
return true;
}
} else if (I->getOpcode() == Instruction::Add &&
isa<CastInst>(I->getOperand(1))) {
if (PeepholeOptimizeAddCast(BB, BI, I->getOperand(0),
cast<CastInst>(I->getOperand(1)), TD)) {
++NumGEPInstFormed;
return true;
}
} else if (CallInst *CI = dyn_cast<CallInst>(I)) {
// If we have a call with all varargs arguments, convert the call to use the
// actual argument types present...

View File

@ -90,16 +90,3 @@ const Type *llvm::getStructOffsetType(const Type *Ty, unsigned &Offset,
Offset = unsigned(ThisOffset + SubOffs);
return LeafTy;
}
// ConvertibleToGEP - This function returns true if the specified value V is
// a valid index into a pointer of type Ty. If it is valid, Idx is filled in
// with the values that would be appropriate to make this a getelementptr
// instruction. The type returned is the root type that the GEP would point to
//
const Type *llvm::ConvertibleToGEP(const Type *Ty, Value *OffsetVal,
std::vector<Value*> &Indices,
const TargetData &TD,
BasicBlock::iterator *BI) {
return 0;
}

View File

@ -37,20 +37,6 @@ static inline const CompositeType *getPointedToComposite(const Type *Ty) {
return PT ? dyn_cast<CompositeType>(PT->getElementType()) : 0;
}
// ConvertibleToGEP - This function returns true if the specified value V is
// a valid index into a pointer of type Ty. If it is valid, Idx is filled in
// with the values that would be appropriate to make this a getelementptr
// instruction. The type returned is the root type that the GEP would point
// to if it were synthesized with this operands.
//
// If BI is nonnull, cast instructions are inserted as appropriate for the
// arguments of the getelementptr.
//
const Type *ConvertibleToGEP(const Type *Ty, Value *V,
std::vector<Value*> &Indices,
const TargetData &TD,
BasicBlock::iterator *BI = 0);
//===----------------------------------------------------------------------===//
// ValueHandle Class - Smart pointer that occupies a slot on the users USE list