X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FTransformInternals.h;h=4f92dc4eda8db3a7c6e1bdb3d80fbaf237a810f5;hb=ff5bf9c62bb1d604ea9ad95f0687ac1592fa774a;hp=e6e65efd03d2a1f3418ee576f2217bd405520779;hpb=59cd9f1e9fcad6b40fc522010512f60ec10151d0;p=oota-llvm.git diff --git a/lib/Transforms/TransformInternals.h b/lib/Transforms/TransformInternals.h index e6e65efd03d..4f92dc4eda8 100644 --- a/lib/Transforms/TransformInternals.h +++ b/lib/Transforms/TransformInternals.h @@ -1,4 +1,11 @@ -//===-- TransformInternals.h - Shared functions for Transforms ---*- C++ -*--=// +//===-- TransformInternals.h - Shared functions for Transforms --*- C++ -*-===// +// +// 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 header file declares shared functions used by the different components // of the Transforms library. @@ -10,47 +17,126 @@ #include "llvm/BasicBlock.h" #include "llvm/Target/TargetData.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Constants.h" #include +#include -// TargetData Hack: Eventually we will have annotations given to us by the -// backend so that we know stuff about type size and alignments. For now -// though, just use this, because it happens to match the model that GCC uses. -// -// FIXME: This should use annotations +static inline int64_t getConstantValue(const ConstantInt *CPI) { + return (int64_t)cast(CPI)->getRawValue(); +} + + +// getPointedToComposite - If the argument is a pointer type, and the pointed to +// value is a composite type, return the composite type, else return null. // -extern const TargetData TD; +static inline const CompositeType *getPointedToComposite(const Type *Ty) { + const PointerType *PT = dyn_cast(Ty); + return PT ? dyn_cast(PT->getElementType()) : 0; +} -// losslessCastableTypes - Return true if the types are bitwise equivalent. -// This predicate returns true if it is possible to cast from one type to -// another without gaining or losing precision, or altering the bits in any way. +// 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. // -bool losslessCastableTypes(const Type *T1, const Type *T2); +// 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 &Indices, + const TargetData &TD, + BasicBlock::iterator *BI = 0); -// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI) -// with a value, then remove and delete the original instruction. -// -void ReplaceInstWithValue(BasicBlock::InstListType &BIL, - BasicBlock::iterator &BI, Value *V); +//===----------------------------------------------------------------------===// +// ValueHandle Class - Smart pointer that occupies a slot on the users USE list +// that prevents it from being destroyed. This "looks" like an Instruction +// with Opcode UserOp1. +// +class ValueMapCache; +class ValueHandle : public Instruction { + ValueMapCache &Cache; +public: + ValueHandle(ValueMapCache &VMC, Value *V); + ValueHandle(const ValueHandle &); + ~ValueHandle(); -// ReplaceInstWithInst - Replace the instruction specified by BI with the -// instruction specified by I. The original instruction is deleted and BI is -// updated to point to the new instruction. -// -void ReplaceInstWithInst(BasicBlock::InstListType &BIL, - BasicBlock::iterator &BI, Instruction *I); + virtual Instruction *clone() const { abort(); return 0; } + + virtual const char *getOpcodeName() const { + return "ValueHandle"; + } + + inline bool operator<(const ValueHandle &VH) const { + return getOperand(0) < VH.getOperand(0); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ValueHandle *) { return true; } + static inline bool classof(const Instruction *I) { + return (I->getOpcode() == Instruction::UserOp1); + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; // ------------- Expression Conversion --------------------- -typedef map ValueTypeCache; -typedef map ValueMapCache; +typedef std::map ValueTypeCache; + +struct ValueMapCache { + // Operands mapped - Contains an entry if the first value (the user) has had + // the second value (the operand) mapped already. + // + std::set OperandsMapped; + + // Expression Map - Contains an entry from the old value to the new value of + // an expression that has been converted over. + // + std::map ExprMap; + typedef std::map ExprMapTy; + + // Cast Map - Cast instructions can have their source and destination values + // changed independently for each part. Because of this, our old naive + // implementation would create a TWO new cast instructions, which would cause + // all kinds of problems. Here we keep track of the newly allocated casts, so + // that we only create one for a particular instruction. + // + std::set NewCasts; +}; -// RetValConvertableToType - Return true if it is possible -bool RetValConvertableToType(Value *V, const Type *Ty, - ValueTypeCache &ConvertedTypes); -void ConvertUsersType(Value *V, Value *NewVal, ValueMapCache &VMC); +bool ExpressionConvertibleToType(Value *V, const Type *Ty, ValueTypeCache &Map, + const TargetData &TD); +Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC, + const TargetData &TD); +// ValueConvertibleToType - Return true if it is possible +bool ValueConvertibleToType(Value *V, const Type *Ty, + ValueTypeCache &ConvertedTypes, + const TargetData &TD); + +void ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC, + const TargetData &TD); + + +// getStructOffsetType - Return a vector of offsets that are to be used to index +// into the specified struct type to get as close as possible to index as we +// can. Note that it is possible that we cannot get exactly to Offset, in which +// case we update offset to be the offset we actually obtained. The resultant +// leaf type is returned. +// +// If StopEarly is set to true (the default), the first object with the +// specified type is returned, even if it is a struct type itself. In this +// case, this routine will not drill down to the leaf type. Set StopEarly to +// false if you want a leaf +// +const Type *getStructOffsetType(const Type *Ty, unsigned &Offset, + std::vector &Offsets, + const TargetData &TD, bool StopEarly = true); #endif