//===- ExprTypeConvert.cpp - Code to change an LLVM Expr Type -------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the part of level raising that checks to see if it is
#include "TransformInternals.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
-#include "llvm/Analysis/Expressions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
+#include <iostream>
using namespace llvm;
static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
ValueMapCache &VMC, const TargetData &TD);
-// Peephole Malloc instructions: we take a look at the use chain of the
-// malloc instruction, and try to find out if the following conditions hold:
-// 1. The malloc is of the form: 'malloc [sbyte], uint <constant>'
-// 2. The only users of the malloc are cast & add instructions
-// 3. Of the cast instructions, there is only one destination pointer type
-// [RTy] where the size of the pointed to object is equal to the number
-// of bytes allocated.
-//
-// If these conditions hold, we convert the malloc to allocate an [RTy]
-// element. TODO: This comment is out of date WRT arrays
-//
-static bool MallocConvertibleToType(MallocInst *MI, const Type *Ty,
- ValueTypeCache &CTMap,
- const TargetData &TD) {
- if (!isa<PointerType>(Ty)) return false; // Malloc always returns pointers
-
- // Deal with the type to allocate, not the pointer type...
- Ty = cast<PointerType>(Ty)->getElementType();
- if (!Ty->isSized()) return false; // Can only alloc something with a size
-
- // Analyze the number of bytes allocated...
- ExprType Expr = ClassifyExpr(MI->getArraySize());
-
- // Get information about the base datatype being allocated, before & after
- uint64_t ReqTypeSize = TD.getTypeSize(Ty);
- if (ReqTypeSize == 0) return false;
- uint64_t OldTypeSize = TD.getTypeSize(MI->getType()->getElementType());
-
- // Must have a scale or offset to analyze it...
- if (!Expr.Offset && !Expr.Scale && OldTypeSize == 1) return false;
-
- // Get the offset and scale of the allocation...
- int64_t OffsetVal = Expr.Offset ? getConstantValue(Expr.Offset) : 0;
- int64_t ScaleVal = Expr.Scale ? getConstantValue(Expr.Scale) :(Expr.Var != 0);
-
- // The old type might not be of unit size, take old size into consideration
- // here...
- uint64_t Offset = OffsetVal * OldTypeSize;
- uint64_t Scale = ScaleVal * OldTypeSize;
-
- // In order to be successful, both the scale and the offset must be a multiple
- // of the requested data type's size.
- //
- if (Offset/ReqTypeSize*ReqTypeSize != Offset ||
- Scale/ReqTypeSize*ReqTypeSize != Scale)
- return false; // Nope.
-
- return true;
-}
-
-static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
- const std::string &Name,
- ValueMapCache &VMC,
- const TargetData &TD){
- BasicBlock *BB = MI->getParent();
- BasicBlock::iterator It = BB->end();
-
- // Analyze the number of bytes allocated...
- ExprType Expr = ClassifyExpr(MI->getArraySize());
-
- const PointerType *AllocTy = cast<PointerType>(Ty);
- const Type *ElType = AllocTy->getElementType();
-
- uint64_t DataSize = TD.getTypeSize(ElType);
- uint64_t OldTypeSize = TD.getTypeSize(MI->getType()->getElementType());
-
- // Get the offset and scale coefficients that we are allocating...
- int64_t OffsetVal = (Expr.Offset ? getConstantValue(Expr.Offset) : 0);
- int64_t ScaleVal = Expr.Scale ? getConstantValue(Expr.Scale) : (Expr.Var !=0);
-
- // The old type might not be of unit size, take old size into consideration
- // here...
- unsigned Offset = OffsetVal * OldTypeSize / DataSize;
- unsigned Scale = ScaleVal * OldTypeSize / DataSize;
-
- // Locate the malloc instruction, because we may be inserting instructions
- It = MI;
-
- // If we have a scale, apply it first...
- if (Expr.Var) {
- // Expr.Var is not necessarily unsigned right now, insert a cast now.
- if (Expr.Var->getType() != Type::UIntTy)
- Expr.Var = new CastInst(Expr.Var, Type::UIntTy,
- Expr.Var->getName()+"-uint", It);
-
- if (Scale != 1)
- Expr.Var = BinaryOperator::create(Instruction::Mul, Expr.Var,
- ConstantUInt::get(Type::UIntTy, Scale),
- Expr.Var->getName()+"-scl", It);
-
- } else {
- // If we are not scaling anything, just make the offset be the "var"...
- Expr.Var = ConstantUInt::get(Type::UIntTy, Offset);
- Offset = 0; Scale = 1;
- }
-
- // If we have an offset now, add it in...
- if (Offset != 0) {
- assert(Expr.Var && "Var must be nonnull by now!");
- Expr.Var = BinaryOperator::create(Instruction::Add, Expr.Var,
- ConstantUInt::get(Type::UIntTy, Offset),
- Expr.Var->getName()+"-off", It);
- }
-
- assert(AllocTy == Ty);
- return new MallocInst(AllocTy->getElementType(), Expr.Var, Name);
-}
-
// ExpressionConvertibleToType - Return true if it is possible
bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty,
// Expression type must be holdable in a register.
if (!Ty->isFirstClassType())
return false;
-
+
ValueTypeCache::iterator CTMI = CTMap.find(V);
if (CTMI != CTMap.end()) return CTMI->second == Ty;
//
if (isa<Constant>(V) && !isa<GlobalValue>(V))
return true;
-
+
CTMap[V] = Ty;
if (V->getType() == Ty) return true; // Expression already correct type!
// We also do not allow conversion of a cast that casts from a ptr to array
// of X to a *X. For example: cast [4 x %List *] * %val to %List * *
//
- if (const PointerType *SPT =
+ if (const PointerType *SPT =
dyn_cast<PointerType>(I->getOperand(0)->getType()))
if (const PointerType *DPT = dyn_cast<PointerType>(I->getType()))
if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
if (!ExpressionConvertibleToType(LI->getPointerOperand(),
PointerType::get(Ty), CTMap, TD))
return false;
- break;
+ break;
}
case Instruction::PHI: {
PHINode *PN = cast<PHINode>(I);
break;
}
- case Instruction::Malloc:
- if (!MallocConvertibleToType(cast<MallocInst>(I), Ty, CTMap, TD))
- return false;
- break;
-
case Instruction::GetElementPtr: {
// GetElementPtr's are directly convertible to a pointer type if they have
// a number of zeros at the end. Because removing these values does not
// %t2 = cast %List * * %t1 to %List *
// into
// %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
- //
+ //
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
const PointerType *PTy = dyn_cast<PointerType>(Ty);
if (!PTy) return false; // GEP must always return a pointer...
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:
// getelemenptr [[int] *] * %reg115, long %reg138 ; [int]**
//
- if (GEP->getNumOperands() == 2 &&
+ if (GEP->getNumOperands() == 2 &&
PTy->getElementType()->isSized() &&
- TD.getTypeSize(PTy->getElementType()) ==
+ TD.getTypeSize(PTy->getElementType()) ==
TD.getTypeSize(GEP->getType()->getElementType())) {
const PointerType *NewSrcTy = PointerType::get(PVTy);
if (!ExpressionConvertibleToType(I->getOperand(0), NewSrcTy, CTMap, TD))
}
-Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty,
+Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty,
ValueMapCache &VMC, const TargetData &TD) {
if (V->getType() == Ty) return V; // Already where we need to be?
ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(V);
if (VMCI != VMC.ExprMap.end()) {
- const Value *GV = VMCI->second;
- const Type *GTy = VMCI->second->getType();
assert(VMCI->second->getType() == Ty);
if (Instruction *I = dyn_cast<Instruction>(V))
Instruction *Res; // Result of conversion
ValueHandle IHandle(VMC, I); // Prevent I from being removed!
-
+
Constant *Dummy = Constant::getNullValue(Ty);
switch (I->getOpcode()) {
Res = new CastInst(I->getOperand(0), Ty, Name);
VMC.NewCasts.insert(ValueHandle(VMC, Res));
break;
-
+
case Instruction::Add:
case Instruction::Sub:
Res = BinaryOperator::create(cast<BinaryOperator>(I)->getOpcode(),
break;
}
- case Instruction::Malloc: {
- Res = ConvertMallocToType(cast<MallocInst>(I), Ty, Name, VMC, TD);
- break;
- }
-
case Instruction::GetElementPtr: {
// GetElementPtr's are directly convertible to a pointer type if they have
// a number of zeros at the end. Because removing these values does not
// %t2 = cast %List * * %t1 to %List *
// into
// %t2 = getelementptr %Hosp * %hosp, ubyte 4 ; <%List *>
- //
+ //
GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
// Check to see if there are zero elements that we can remove from the
}
}
- 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:
Res = new CallInst(Constant::getNullValue(NewPTy),
std::vector<Value*>(I->op_begin()+1, I->op_end()),
Name);
+ if (cast<CallInst>(I)->isTailCall())
+ cast<CallInst>(Res)->setTailCall();
+ cast<CallInst>(Res)->setCallingConv(cast<CallInst>(I)->getCallingConv());
VMC.ExprMap[I] = Res;
Res->setOperand(0, ConvertExpressionToType(I->getOperand(0),NewPTy,VMC,TD));
break;
VMC.ExprMap[I] = Res;
- unsigned NumUses = I->use_size();
+ //// WTF is this code! FIXME: remove this.
+ unsigned NumUses = I->getNumUses();
for (unsigned It = 0; It < NumUses; ) {
unsigned OldSize = NumUses;
Value::use_iterator UI = I->use_begin();
std::advance(UI, It);
ConvertOperandToType(*UI, I, Res, VMC, TD);
- NumUses = I->use_size();
+ NumUses = I->getNumUses();
if (NumUses == OldSize) ++It;
}
// We also do not allow conversion of a cast that casts from a ptr to array
// of X to a *X. For example: cast [4 x %List *] * %val to %List * *
//
- if (const PointerType *SPT =
+ if (const PointerType *SPT =
dyn_cast<PointerType>(I->getOperand(0)->getType()))
if (const PointerType *DPT = dyn_cast<PointerType>(I->getType()))
if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
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;
if (const PointerType *PT = dyn_cast<PointerType>(Ty)) {
LoadInst *LI = cast<LoadInst>(I);
-
+
const Type *LoadedTy = PT->getElementType();
// They could be loading the first element of a composite type...
return false;
case Instruction::Store: {
- StoreInst *SI = cast<StoreInst>(I);
-
if (V == I->getOperand(0)) {
ValueTypeCache::iterator CTMI = CTMap.find(I->getOperand(1));
if (CTMI != CTMap.end()) { // Operand #1 is in the table already?
assert(Offset == 0 && "Offset changed!");
if (ElTy == 0) // Element at offset zero in struct doesn't exist!
return false; // Can only happen for {}*
-
+
if (ElTy == Ty) // Looks like the 0th element of structure is
return true; // compatible! Accept now!
}
// Must move the same amount of data...
- if (!ElTy->isSized() ||
+ if (!ElTy->isSized() ||
TD.getTypeSize(ElTy) != TD.getTypeSize(I->getOperand(0)->getType()))
return false;
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.
// the call provides...
//
if (NumArgs < FTy->getNumParams()) return false;
-
+
// Unless this is a vararg function type, we cannot provide more arguments
// than are desired...
//
//
return ValueConvertibleToType(I, FTy->getReturnType(), CTMap, TD);
}
-
+
const PointerType *MPtr = cast<PointerType>(I->getOperand(0)->getType());
const FunctionType *FTy = cast<FunctionType>(MPtr->getElementType());
if (!FTy->isVarArg()) return false;
const TargetData &TD) {
ValueHandle VH(VMC, V);
- unsigned NumUses = V->use_size();
+ // FIXME: This is horrible!
+ unsigned NumUses = V->getNumUses();
for (unsigned It = 0; It < NumUses; ) {
unsigned OldSize = NumUses;
Value::use_iterator UI = V->use_begin();
std::advance(UI, It);
ConvertOperandToType(*UI, V, NewVal, VMC, TD);
- NumUses = V->use_size();
+ NumUses = V->getNumUses();
if (NumUses == OldSize) ++It;
}
}
ValueHandle IHandle(VMC, I);
const Type *NewTy = NewVal->getType();
- Constant *Dummy = (NewTy != Type::VoidTy) ?
+ Constant *Dummy = (NewTy != Type::VoidTy) ?
Constant::getNullValue(NewTy) : 0;
switch (I->getOpcode()) {
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: {
Src = new GetElementPtrInst(Src, Indices, Name+".idx", I);
}
}
-
+
Res = new LoadInst(Src, Name);
assert(Res->getType()->isFirstClassType() && "Load of structure or array!");
break;
//
const Type *ElTy =
cast<PointerType>(VMCI->second->getType())->getElementType();
-
+
Value *SrcPtr = VMCI->second;
if (ElTy != NewTy) {
// We check that this is a struct in the initial scan...
const StructType *SElTy = cast<StructType>(ElTy);
-
+
std::vector<Value*> Indices;
Indices.push_back(Constant::getNullValue(Type::UIntTy));
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);
}
Res = new CallInst(Meth, Params, Name);
+ if (cast<CallInst>(I)->isTailCall())
+ cast<CallInst>(Res)->setTailCall();
+ cast<CallInst>(Res)->setCallingConv(cast<CallInst>(I)->getCallingConv());
break;
}
default:
if (I->getType() != Res->getType())
ConvertValueToNewType(I, Res, VMC, TD);
else {
- bool FromStart = true;
- Value::use_iterator UI;
- while (1) {
- if (FromStart) UI = I->use_begin();
- if (UI == I->use_end()) break;
-
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; )
if (isa<ValueHandle>(*UI)) {
++UI;
- FromStart = false;
} else {
- User *U = *UI;
- if (!FromStart) --UI;
- U->replaceUsesOfWith(I, Res);
- if (!FromStart) ++UI;
+ Use &U = UI.getUse();
+ ++UI; // Do not invalidate UI.
+ U.set(Res);
}
- }
}
}
//DEBUG(std::cerr << "VH DELETING: " << (void*)I << " " << I);
- for (User::op_iterator OI = I->op_begin(), OE = I->op_end();
+ for (User::op_iterator OI = I->op_begin(), OE = I->op_end();
OI != OE; ++OI)
if (Instruction *U = dyn_cast<Instruction>(OI)) {
*OI = 0;
RecursiveDelete(Cache, dyn_cast<Instruction>(V));
} else {
//DEBUG(std::cerr << "VH RELEASING: " << (void*)Operands[0].get() << " "
- // << Operands[0]->use_size() << " " << Operands[0]);
+ // << Operands[0]->getNumUses() << " " << Operands[0]);
}
}