//===- 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
// convertable, 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/StatisticReporter.h"
#include <algorithm>
#include <iostream>
using std::cerr;
static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
ValueTypeCache &ConvertedTypes);
static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
ValueMapCache &VMC);
// AllIndicesZero - Return true if all of the indices of the specified memory
// access instruction are zero, indicating an effectively nil offset to the
// pointer value.
//
static bool AllIndicesZero(const MemAccessInst *MAI) {
for (User::const_op_iterator S = MAI->idx_begin(), E = MAI->idx_end();
S != E; ++S)
if (!isa<Constant>(S->get()) || !cast<Constant>(S->get())->isNullValue())
return false;
return true;
}
// 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 MallocConvertableToType(MallocInst *MI, const Type *Ty,
ValueTypeCache &CTMap) {
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...
analysis::ExprType Expr = analysis::ClassifyExpression(MI->getArraySize());
// Get information about the base datatype being allocated, before & after
int ReqTypeSize = TD.getTypeSize(Ty);
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...
int OffsetVal = Expr.Offset ? getConstantValue