summaryrefslogtreecommitdiff
path: root/lib/Transforms/TransformInternals.h
blob: 51e32c81e67b9dbdbad86360bfffee1d346092e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===-- 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.
//
//===----------------------------------------------------------------------===//

#ifndef TRANSFORM_INTERNALS_H
#define TRANSFORM_INTERNALS_H

#include "llvm/BasicBlock.h"
#include "llvm/Target/TargetData.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include <map>
#include <set>

namespace llvm {

static inline int64_t getConstantValue(const ConstantInt *CPI) {
  return (int64_t)cast<ConstantInt>(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.
//
static inline const CompositeType *getPointedToComposite(const Type *Ty) {
  const PointerType *PT = dyn_cast<PointerType>(Ty);
  return PT ? dyn_cast<CompositeType>(PT->getElementType()) : 0;
}


//===----------------------------------------------------------------------===//
//  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 {
  Use Op;
  ValueMapCache &Cache;
public:
  ValueHandle(ValueMapCache &VMC, Value *V);
  ValueHandle(const ValueHandle &);
  ~ValueHandle();

  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<Instruction>(V) && classof(cast<Instruction>(V));
  }
};


// ------------- Expression Conversion ---------------------

typedef std::map<const Value*, const Type*> ValueTypeCache;

class ValueMapCache {
public:
  // Operands mapped - Contains an entry if the first value (the user) has had
  // the second value (the operand) mapped already.
  //
  std::set<const User*> OperandsMapped;

  // Expression Map - Contains an entry from the old value to the new value of
  // an expression that has been converted over.
  //
  std::map<const Value *, Value *> ExprMap;
  typedef std::map<const Value *, Value *> 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<ValueHandle> NewCasts;
};


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<Value*> &Offsets,
                                const TargetData &TD, bool StopEarly = true);

} // End llvm namespace

#endif