//===- 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
// 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/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Analysis/Expressions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
using namespace llvm;
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() || !MI->getType()->getElementType()->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;