//===- ExprTypeConvert.cpp - Code to change an LLVM Expr Type -------------===//
//
// This file implements the part of level raising that checks to see if it is
// possible to coerce an entire expression tree into a different type. If
// convertible, other routines from this file will do the conversion.
//
//===----------------------------------------------------------------------===//
#include "TransformInternals.h"
#include "llvm/iOther.h"
#include "llvm/iPHINode.h"
#include "llvm/iMemory.h"
#include "llvm/ConstantHandling.h"
#include "llvm/Analysis/Expressions.h"
#include "Support/STLExtras.h"
#include "Support/Debug.h"
#include <algorithm>
using std::cerr;
static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
ValueTypeCache &ConvertedTypes,
const TargetData &TD);
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 = ClassifyExpression(MI->getArraySize());
// Get information about the base datatype being allocated, before & after
int ReqTypeSize = TD.getTypeSize(Ty);
if (ReqTypeSize == 0) return false;
unsigned 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...
int64_t Offset = OffsetVal * OldTypeSize;
int64_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.
<